From cf94bdc0742c13e2a0cac864c478b8626b266e1b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rustc_trait_selection/src/traits/coherence.rs | 102 +++++++++------------ 1 file changed, 45 insertions(+), 57 deletions(-) (limited to 'compiler/rustc_trait_selection/src/traits/coherence.rs') diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 292787d4d..8aab75490 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -22,7 +22,6 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; -use rustc_middle::ty::subst::Subst; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitor}; use rustc_span::symbol::sym; @@ -61,23 +60,17 @@ pub fn add_placeholder_note(err: &mut Diagnostic) { ); } -/// If there are types that satisfy both impls, invokes `on_overlap` +/// If there are types that satisfy both impls, returns `Some` /// with a suitably-freshened `ImplHeader` with those types -/// substituted. Otherwise, invokes `no_overlap`. -#[instrument(skip(tcx, skip_leak_check, on_overlap, no_overlap), level = "debug")] -pub fn overlapping_impls( +/// substituted. Otherwise, returns `None`. +#[instrument(skip(tcx, skip_leak_check), level = "debug")] +pub fn overlapping_impls( tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId, skip_leak_check: SkipLeakCheck, overlap_mode: OverlapMode, - on_overlap: F1, - no_overlap: F2, -) -> R -where - F1: FnOnce(OverlapResult<'_>) -> R, - F2: FnOnce() -> R, -{ +) -> Option> { // Before doing expensive operations like entering an inference context, do // a quick check via fast_reject to tell if the impl headers could possibly // unify. @@ -98,28 +91,24 @@ where if !may_overlap { // Some types involved are definitely different, so the impls couldn't possibly overlap. debug!("overlapping_impls: fast_reject early-exit"); - return no_overlap(); + return None; } - let overlaps = tcx.infer_ctxt().enter(|infcx| { - let selcx = &mut SelectionContext::intercrate(&infcx); - overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some() - }); - + let infcx = tcx.infer_ctxt().build(); + let selcx = &mut SelectionContext::intercrate(&infcx); + let overlaps = + overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some(); if !overlaps { - return no_overlap(); + return None; } // In the case where we detect an error, run the check again, but // this time tracking intercrate ambiguity causes for better // diagnostics. (These take time and can lead to false errors.) - tcx.infer_ctxt().enter(|infcx| { - let selcx = &mut SelectionContext::intercrate(&infcx); - selcx.enable_tracking_intercrate_ambiguity_causes(); - on_overlap( - overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap(), - ) - }) + let infcx = tcx.infer_ctxt().build(); + let selcx = &mut SelectionContext::intercrate(&infcx); + selcx.enable_tracking_intercrate_ambiguity_causes(); + Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap()) } fn with_fresh_ty_vars<'cx, 'tcx>( @@ -168,7 +157,7 @@ fn overlap_within_probe<'cx, 'tcx>( impl1_def_id: DefId, impl2_def_id: DefId, overlap_mode: OverlapMode, - snapshot: &CombinedSnapshot<'_, 'tcx>, + snapshot: &CombinedSnapshot<'tcx>, ) -> Option> { let infcx = selcx.infcx(); @@ -198,7 +187,7 @@ fn overlap_within_probe<'cx, 'tcx>( } } - // We disable the leak when when creating the `snapshot` by using + // We disable the leak when creating the `snapshot` by using // `infcx.probe_maybe_disable_leak_check`. if infcx.leak_check(true, snapshot).is_err() { debug!("overlap: leak check failed"); @@ -299,37 +288,36 @@ fn negative_impl<'cx, 'tcx>( let tcx = selcx.infcx().tcx; // Create an infcx, taking the predicates of impl1 as assumptions: - tcx.infer_ctxt().enter(|infcx| { - // create a parameter environment corresponding to a (placeholder) instantiation of impl1 - let impl_env = tcx.param_env(impl1_def_id); - let subject1 = match traits::fully_normalize( - &infcx, - ObligationCause::dummy(), - impl_env, - tcx.impl_subject(impl1_def_id), - ) { - Ok(s) => s, - Err(err) => { - tcx.sess.delay_span_bug( - tcx.def_span(impl1_def_id), - format!("failed to fully normalize {:?}: {:?}", impl1_def_id, err), - ); - return false; - } - }; + let infcx = tcx.infer_ctxt().build(); + // create a parameter environment corresponding to a (placeholder) instantiation of impl1 + let impl_env = tcx.param_env(impl1_def_id); + let subject1 = match traits::fully_normalize( + &infcx, + ObligationCause::dummy(), + impl_env, + tcx.impl_subject(impl1_def_id), + ) { + Ok(s) => s, + Err(err) => { + tcx.sess.delay_span_bug( + tcx.def_span(impl1_def_id), + format!("failed to fully normalize {:?}: {:?}", impl1_def_id, err), + ); + return false; + } + }; - // Attempt to prove that impl2 applies, given all of the above. - let selcx = &mut SelectionContext::new(&infcx); - let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id); - let (subject2, obligations) = - impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs); + // Attempt to prove that impl2 applies, given all of the above. + let selcx = &mut SelectionContext::new(&infcx); + let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id); + let (subject2, obligations) = + impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs); - !equate(&infcx, impl_env, subject1, subject2, obligations, impl1_def_id) - }) + !equate(&infcx, impl_env, subject1, subject2, obligations, impl1_def_id) } -fn equate<'cx, 'tcx>( - infcx: &InferCtxt<'cx, 'tcx>, +fn equate<'tcx>( + infcx: &InferCtxt<'tcx>, impl_env: ty::ParamEnv<'tcx>, subject1: ImplSubject<'tcx>, subject2: ImplSubject<'tcx>, @@ -380,8 +368,8 @@ fn negative_impl_exists<'cx, 'tcx>( } #[instrument(level = "debug", skip(infcx))] -fn resolve_negative_obligation<'cx, 'tcx>( - infcx: InferCtxt<'cx, 'tcx>, +fn resolve_negative_obligation<'tcx>( + infcx: InferCtxt<'tcx>, o: &PredicateObligation<'tcx>, body_def_id: DefId, ) -> bool { -- cgit v1.2.3