From 4e8199b572f2035b7749cba276ece3a26630d23e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:21 +0200 Subject: Adding upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- .../src/traits/specialize/mod.rs | 137 +++++++++++---------- 1 file changed, 71 insertions(+), 66 deletions(-) (limited to 'compiler/rustc_trait_selection/src/traits/specialize/mod.rs') diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index c89165858..a251a508b 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -15,11 +15,13 @@ use specialization_graph::GraphExt; use crate::errors::NegativePositiveConflict; use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; -use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause}; -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee}; +use crate::traits::{ + self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, +}; +use rustc_data_structures::fx::FxIndexSet; +use rustc_errors::{error_code, DelayDm, Diagnostic}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::ty::{self, ImplSubject, TyCtxt}; +use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; @@ -30,10 +32,10 @@ use super::SelectionContext; /// Information pertinent to an overlapping impl error. #[derive(Debug)] -pub struct OverlapError { +pub struct OverlapError<'tcx> { pub with_impl: DefId, - pub trait_desc: String, - pub self_desc: Option, + pub trait_ref: ty::TraitRef<'tcx>, + pub self_ty: Option>, pub intercrate_ambiguity_causes: FxIndexSet, pub involves_placeholder: bool, } @@ -200,39 +202,35 @@ fn fulfill_implication<'tcx>( return Err(()); }; + // Needs to be `in_snapshot` because this function is used to rebase + // substitutions, which may happen inside of a select within a probe. + let ocx = ObligationCtxt::new_in_snapshot(infcx); // attempt to prove all of the predicates for impl2 given those for impl1 // (which are packed up in penv) + ocx.register_obligations(obligations.chain(more_obligations)); - infcx.save_and_restore_in_snapshot_flag(|infcx| { - let errors = traits::fully_solve_obligations(&infcx, obligations.chain(more_obligations)); - match &errors[..] { - [] => { - debug!( - "fulfill_implication: an impl for {:?} specializes {:?}", - source_trait, target_trait - ); + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + // no dice! + debug!( + "fulfill_implication: for impls on {:?} and {:?}, \ + could not fulfill: {:?} given {:?}", + source_trait, + target_trait, + errors, + param_env.caller_bounds() + ); + return Err(()); + } - // Now resolve the *substitution* we built for the target earlier, replacing - // the inference variables inside with whatever we got from fulfillment. - Ok(infcx.resolve_vars_if_possible(target_substs)) - } - errors => { - // no dice! - debug!( - "fulfill_implication: for impls on {:?} and {:?}, \ - could not fulfill: {:?} given {:?}", - source_trait, - target_trait, - errors, - param_env.caller_bounds() - ); - Err(()) - } - } - }) + debug!("fulfill_implication: an impl for {:?} specializes {:?}", source_trait, target_trait); + + // Now resolve the *substitution* we built for the target earlier, replacing + // the inference variables inside with whatever we got from fulfillment. + Ok(infcx.resolve_vars_if_possible(target_substs)) } -// Query provider for `specialization_graph_of`. +/// Query provider for `specialization_graph_of`. pub(super) fn specialization_graph_provider( tcx: TyCtxt<'_>, trait_id: DefId, @@ -277,9 +275,9 @@ pub(super) fn specialization_graph_provider( // it negatively impacts perf. #[cold] #[inline(never)] -fn report_overlap_conflict( - tcx: TyCtxt<'_>, - overlap: OverlapError, +fn report_overlap_conflict<'tcx>( + tcx: TyCtxt<'tcx>, + overlap: OverlapError<'tcx>, impl_def_id: LocalDefId, used_to_be_allowed: Option, sg: &mut specialization_graph::Graph, @@ -315,9 +313,9 @@ fn report_overlap_conflict( } } -fn report_negative_positive_conflict( - tcx: TyCtxt<'_>, - overlap: &OverlapError, +fn report_negative_positive_conflict<'tcx>( + tcx: TyCtxt<'tcx>, + overlap: &OverlapError<'tcx>, local_impl_def_id: LocalDefId, negative_impl_def_id: DefId, positive_impl_def_id: DefId, @@ -325,17 +323,17 @@ fn report_negative_positive_conflict( ) { let mut err = tcx.sess.create_err(NegativePositiveConflict { impl_span: tcx.def_span(local_impl_def_id), - trait_desc: &overlap.trait_desc, - self_desc: &overlap.self_desc, + trait_desc: overlap.trait_ref, + self_ty: overlap.self_ty, negative_impl_span: tcx.span_of_impl(negative_impl_def_id), positive_impl_span: tcx.span_of_impl(positive_impl_def_id), }); sg.has_errored = Some(err.emit()); } -fn report_conflicting_impls( - tcx: TyCtxt<'_>, - overlap: OverlapError, +fn report_conflicting_impls<'tcx>( + tcx: TyCtxt<'tcx>, + overlap: OverlapError<'tcx>, impl_def_id: LocalDefId, used_to_be_allowed: Option, sg: &mut specialization_graph::Graph, @@ -345,12 +343,12 @@ fn report_conflicting_impls( // Work to be done after we've built the DiagnosticBuilder. We have to define it // now because the struct_lint methods don't return back the DiagnosticBuilder // that's passed in. - fn decorate<'a, 'b, G: EmissionGuarantee>( - tcx: TyCtxt<'_>, - overlap: OverlapError, + fn decorate<'tcx>( + tcx: TyCtxt<'tcx>, + overlap: &OverlapError<'tcx>, impl_span: Span, - err: &'b mut DiagnosticBuilder<'a, G>, - ) -> &'b mut DiagnosticBuilder<'a, G> { + err: &mut Diagnostic, + ) { match tcx.span_of_impl(overlap.with_impl) { Ok(span) => { err.span_label(span, "first implementation here"); @@ -359,7 +357,7 @@ fn report_conflicting_impls( impl_span, format!( "conflicting implementation{}", - overlap.self_desc.map_or_else(String::new, |ty| format!(" for `{}`", ty)) + overlap.self_ty.map_or_else(String::new, |ty| format!(" for `{}`", ty)) ), ); } @@ -381,26 +379,28 @@ fn report_conflicting_impls( if overlap.involves_placeholder { coherence::add_placeholder_note(err); } - err } - let msg = format!( - "conflicting implementations of trait `{}`{}{}", - overlap.trait_desc, - overlap.self_desc.as_deref().map_or_else(String::new, |ty| format!(" for type `{ty}`")), - match used_to_be_allowed { - Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)", - _ => "", - } - ); + let msg = DelayDm(|| { + format!( + "conflicting implementations of trait `{}`{}{}", + overlap.trait_ref.print_only_trait_path(), + overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")), + match used_to_be_allowed { + Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)", + _ => "", + } + ) + }); match used_to_be_allowed { None => { let reported = if overlap.with_impl.is_local() || tcx.orphan_check_impl(impl_def_id).is_ok() { - let mut err = struct_span_err!(tcx.sess, impl_span, E0119, "{msg}",); - decorate(tcx, overlap, impl_span, &mut err); + let mut err = tcx.sess.struct_span_err(impl_span, msg); + err.code(error_code!(E0119)); + decorate(tcx, &overlap, impl_span, &mut err); Some(err.emit()) } else { Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check")) @@ -417,7 +417,10 @@ fn report_conflicting_impls( tcx.hir().local_def_id_to_hir_id(impl_def_id), impl_span, msg, - |err| decorate(tcx, overlap, impl_span, err), + |err| { + decorate(tcx, &overlap, impl_span, err); + err + }, ); } }; @@ -435,7 +438,7 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti // FIXME: Currently only handles ?Sized. // Needs to support ?Move and ?DynSized when they are implemented. - let mut types_without_default_bounds = FxHashSet::default(); + let mut types_without_default_bounds = FxIndexSet::default(); let sized_trait = tcx.lang_items().sized_trait(); if !substs.is_empty() { @@ -473,7 +476,9 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti trait_pred }); - p = tcx.mk_predicate(new_trait_pred.map_bound(ty::PredicateKind::Trait)) + p = tcx.mk_predicate( + new_trait_pred.map_bound(|p| ty::PredicateKind::Clause(ty::Clause::Trait(p))), + ) } } pretty_predicates.push(p.to_string()); -- cgit v1.2.3