diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index ea141e815bf..1e9b5752130 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::{self, Const, Ty, TyCtxt}; use rustc_session::Session; use rustc_span::symbol::Ident; use rustc_span::{self, Span}; -use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode}; +use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt}; use std::cell::{Cell, RefCell}; use std::ops::Deref; @@ -162,6 +162,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { infcx: &self.infcx, typeck_results: Some(self.typeck_results.borrow()), fallback_has_occurred: self.fallback_has_occurred.get(), + normalize_fn_sig: Box::new(|fn_sig| { + if fn_sig.has_escaping_bound_vars() { + return fn_sig; + } + self.probe(|_| { + let ocx = ObligationCtxt::new_in_snapshot(self); + let normalized_fn_sig = + ocx.normalize(&ObligationCause::dummy(), self.param_env, fn_sig); + if ocx.select_all_or_error().is_empty() { + let normalized_fn_sig = self.resolve_vars_if_possible(normalized_fn_sig); + if !normalized_fn_sig.needs_infer() { + return normalized_fn_sig; + } + } + fn_sig + }) + }), } } diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs index 869ad07c00d..b33e7b8d68c 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/inherited.rs @@ -1,7 +1,6 @@ use super::callee::DeferredCallResolution; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::HirIdMap; @@ -11,9 +10,7 @@ use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefIdMap; use rustc_span::{self, Span}; -use rustc_trait_selection::traits::{ - self, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _, -}; +use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _}; use std::cell::RefCell; use std::ops::Deref; @@ -92,29 +89,7 @@ impl<'tcx> Inherited<'tcx> { infcx: tcx .infer_ctxt() .ignoring_regions() - .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)) - .with_normalize_fn_sig_for_diagnostic(Lrc::new(move |infcx, fn_sig| { - if fn_sig.has_escaping_bound_vars() { - return fn_sig; - } - infcx.probe(|_| { - let ocx = ObligationCtxt::new_in_snapshot(infcx); - let normalized_fn_sig = ocx.normalize( - &ObligationCause::dummy(), - // FIXME(compiler-errors): This is probably not the right param-env... - infcx.tcx.param_env(def_id), - fn_sig, - ); - if ocx.select_all_or_error().is_empty() { - let normalized_fn_sig = - infcx.resolve_vars_if_possible(normalized_fn_sig); - if !normalized_fn_sig.needs_infer() { - return normalized_fn_sig; - } - } - fn_sig - }) - })), + .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)), def_id, typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)), } diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 2483ab724a4..4429e4f4362 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -77,10 +77,6 @@ impl<'tcx> InferCtxt<'tcx> { err_count_on_creation: self.err_count_on_creation, in_snapshot: self.in_snapshot.clone(), universe: self.universe.clone(), - normalize_fn_sig_for_diagnostic: self - .normalize_fn_sig_for_diagnostic - .as_ref() - .map(|f| f.clone()), intercrate: self.intercrate, } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index e2be8fb12d0..6bd1df97c16 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -95,6 +95,7 @@ pub mod nice_region_error; pub struct TypeErrCtxt<'a, 'tcx> { pub infcx: &'a InferCtxt<'tcx>, pub typeck_results: Option>>, + pub normalize_fn_sig: Box) -> ty::PolyFnSig<'tcx> + 'a>, pub fallback_has_occurred: bool, } @@ -1007,22 +1008,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - fn normalize_fn_sig_for_diagnostic(&self, sig: ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> { - if let Some(normalize) = &self.normalize_fn_sig_for_diagnostic { - normalize(self, sig) - } else { - sig - } - } - /// Given two `fn` signatures highlight only sub-parts that are different. fn cmp_fn_sig( &self, sig1: &ty::PolyFnSig<'tcx>, sig2: &ty::PolyFnSig<'tcx>, ) -> (DiagnosticStyledString, DiagnosticStyledString) { - let sig1 = &self.normalize_fn_sig_for_diagnostic(*sig1); - let sig2 = &self.normalize_fn_sig_for_diagnostic(*sig2); + let sig1 = &(self.normalize_fn_sig)(*sig1); + let sig2 = &(self.normalize_fn_sig)(*sig2); let get_lifetimes = |sig| { use rustc_hir::def::Namespace; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 5aebccac6a2..2ce7cd8beba 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -333,9 +333,6 @@ pub struct InferCtxt<'tcx> { /// bound. universe: Cell, - normalize_fn_sig_for_diagnostic: - Option, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>, - /// During coherence we have to assume that other crates may add /// additional impls which we currently don't know about. /// @@ -572,8 +569,6 @@ pub struct InferCtxtBuilder<'tcx> { considering_regions: bool, /// Whether we are in coherence mode. intercrate: bool, - normalize_fn_sig_for_diagnostic: - Option, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>, } pub trait TyCtxtInferExt<'tcx> { @@ -586,7 +581,6 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> { tcx: self, defining_use_anchor: DefiningAnchor::Error, considering_regions: true, - normalize_fn_sig_for_diagnostic: None, intercrate: false, } } @@ -614,14 +608,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> { self } - pub fn with_normalize_fn_sig_for_diagnostic( - mut self, - fun: Lrc, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>, - ) -> Self { - self.normalize_fn_sig_for_diagnostic = Some(fun); - self - } - /// Given a canonical value `C` as a starting point, create an /// inference context that contains each of the bound values /// within instantiated as a fresh variable. The `f` closure is @@ -643,13 +629,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } pub fn build(&mut self) -> InferCtxt<'tcx> { - let InferCtxtBuilder { - tcx, - defining_use_anchor, - considering_regions, - ref normalize_fn_sig_for_diagnostic, - intercrate, - } = *self; + let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self; InferCtxt { tcx, defining_use_anchor, @@ -665,9 +645,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> { in_snapshot: Cell::new(false), skip_leak_check: Cell::new(false), universe: Cell::new(ty::UniverseIndex::ROOT), - normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic - .as_ref() - .map(|f| f.clone()), intercrate, } } @@ -708,7 +685,12 @@ impl<'tcx> InferCtxt<'tcx> { /// Creates a `TypeErrCtxt` for emitting various inference errors. /// During typeck, use `FnCtxt::err_ctxt` instead. pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> { - TypeErrCtxt { infcx: self, typeck_results: None, fallback_has_occurred: false } + TypeErrCtxt { + infcx: self, + typeck_results: None, + fallback_has_occurred: false, + normalize_fn_sig: Box::new(|fn_sig| fn_sig), + } } pub fn is_in_snapshot(&self) -> bool {