diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index b99bfda1a51fe..e05566dc2c745 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -291,11 +291,11 @@ where // FIXME(lqd): Unify and de-duplicate the following with the actual // `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the // `ObligationCause`. The normalization results are currently different between - // `AtExt::normalize` used in the query and `normalize` called below: the former fails - // to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. Check - // after #85499 lands to see if its fixes have erased this difference. + // `QueryNormalizeExt::query_normalize` used in the query and `normalize` called below: + // the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. + // Check after #85499 lands to see if its fixes have erased this difference. let (param_env, value) = key.into_parts(); - let _ = ocx.normalize(cause, param_env, value.value); + let _ = ocx.normalize(&cause, param_env, value.value); try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index d4cee305387dc..54213d55a2da7 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -761,8 +761,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { hir_id, ObligationCauseCode::ItemObligation(callee), ); - let normalized_predicates = - ocx.normalize(cause.clone(), param_env, predicates); + let normalized_predicates = ocx.normalize(&cause, param_env, predicates); ocx.register_obligations(traits::predicates_for_generics( |_, _| cause.clone(), self.param_env, diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index a9cb191cc593f..be786569cde3f 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -46,8 +46,8 @@ pub fn is_subtype<'tcx>( let infcx = builder.build(); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); - let src = ocx.normalize(cause.clone(), param_env, src); - let dest = ocx.normalize(cause.clone(), param_env, dest); + let src = ocx.normalize(&cause, param_env, src); + let dest = ocx.normalize(&cause, param_env, dest); match ocx.sub(&cause, param_env, src, dest) { Ok(()) => {} Err(_) => return false, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 5f06db4038ff7..8215031063827 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -109,6 +109,9 @@ pub trait AstConv<'tcx> { ) -> Ty<'tcx>; /// Normalize an associated type coming from the user. + /// + /// This should only be used by astconv. Use `FnCtxt::normalize` + /// or `ObligationCtxt::normalize` in downstream crates. fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; /// Invoked when we encounter an error from some prior pass diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index de386e2d13556..ba58672e7595a 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -221,7 +221,7 @@ fn compare_predicate_entailment<'tcx>( let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs); for (predicate, span) in iter::zip(impl_m_own_bounds.predicates, impl_m_own_bounds.spans) { let normalize_cause = traits::ObligationCause::misc(span, impl_m_hir_id); - let predicate = ocx.normalize(normalize_cause, param_env, predicate); + let predicate = ocx.normalize(&normalize_cause, param_env, predicate); let cause = ObligationCause::new( span, @@ -260,7 +260,7 @@ fn compare_predicate_entailment<'tcx>( ); let norm_cause = ObligationCause::misc(impl_m_span, impl_m_hir_id); - let impl_sig = ocx.normalize(norm_cause.clone(), param_env, impl_sig); + let impl_sig = ocx.normalize(&norm_cause, param_env, impl_sig); let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig)); debug!("compare_impl_method: impl_fty={:?}", impl_fty); @@ -271,7 +271,7 @@ fn compare_predicate_entailment<'tcx>( // we have to do this before normalization, since the normalized ty may // not contain the input parameters. See issue #87748. wf_tys.extend(trait_sig.inputs_and_output.iter()); - let trait_sig = ocx.normalize(norm_cause, param_env, trait_sig); + let trait_sig = ocx.normalize(&norm_cause, param_env, trait_sig); // We also have to add the normalized trait signature // as we don't normalize during implied bounds computation. wf_tys.extend(trait_sig.inputs_and_output.iter()); @@ -366,7 +366,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>( // Normalize the impl signature with fresh variables for lifetime inference. let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id); let impl_sig = ocx.normalize( - norm_cause.clone(), + &norm_cause, param_env, infcx.replace_bound_vars_with_fresh_vars( return_span, @@ -387,7 +387,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>( tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs), ) .fold_with(&mut collector); - let trait_sig = ocx.normalize(norm_cause.clone(), param_env, unnormalized_trait_sig); + let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig); let trait_return_ty = trait_sig.output(); let wf_tys = FxIndexSet::from_iter( @@ -592,7 +592,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> { for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.item_def_id).subst_iter_copied(self.tcx(), proj.substs) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( - ObligationCause::misc(self.span, self.body_id), + &ObligationCause::misc(self.span, self.body_id), self.param_env, pred, ); @@ -1403,11 +1403,11 @@ pub(crate) fn raw_compare_const_impl<'tcx>( ); // There is no "body" here, so just pass dummy id. - let impl_ty = ocx.normalize(cause.clone(), param_env, impl_ty); + let impl_ty = ocx.normalize(&cause, param_env, impl_ty); debug!("compare_const_impl: impl_ty={:?}", impl_ty); - let trait_ty = ocx.normalize(cause.clone(), param_env, trait_ty); + let trait_ty = ocx.normalize(&cause, param_env, trait_ty); debug!("compare_const_impl: trait_ty={:?}", trait_ty); @@ -1556,7 +1556,7 @@ fn compare_type_predicate_entailment<'tcx>( for (span, predicate) in std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates) { let cause = ObligationCause::misc(span, impl_ty_hir_id); - let predicate = ocx.normalize(cause, param_env, predicate); + let predicate = ocx.normalize(&cause, param_env, predicate); let cause = ObligationCause::new( span, @@ -1778,7 +1778,7 @@ pub fn check_type_bounds<'tcx>( for mut obligation in util::elaborate_obligations(tcx, obligations) { let normalized_predicate = - ocx.normalize(normalize_cause.clone(), normalize_param_env, obligation.predicate); + ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate); debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate); obligation.predicate = normalized_predicate; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 8171a2ab270cd..7daed74e9de83 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -53,12 +53,14 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { self.ocx.infcx.tcx } + // Convenience function to normalize during wfcheck. This performs + // `ObligationCtxt::normalize`, but provides a nice `ObligationCauseCode`. fn normalize(&self, span: Span, loc: Option, value: T) -> T where T: TypeFoldable<'tcx>, { self.ocx.normalize( - ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(loc)), + &ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(loc)), self.param_env, value, ) diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 664d3a3a1db84..2058832d5fdc1 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -332,7 +332,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { ObligationCauseCode::MainFunctionType, ); let ocx = traits::ObligationCtxt::new(&infcx); - let norm_return_ty = ocx.normalize(cause.clone(), param_env, return_ty); + let norm_return_ty = ocx.normalize(&cause, param_env, return_ty); ocx.register_bound(cause, param_env, norm_return_ty, term_did); let errors = ocx.select_all_or_error(); if !errors.is_empty() { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index e50d249849fa8..b09ddf80e2a52 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -448,7 +448,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // previously appeared within a `Binder<>` and hence would not // have been normalized before. let fn_sig = self.replace_bound_vars_with_fresh_vars(call_expr.span, infer::FnCall, fn_sig); - let fn_sig = self.normalize_associated_types_in(call_expr.span, fn_sig); + let fn_sig = self.normalize(call_expr.span, fn_sig); // Call the generic checker. let expected_arg_tys = self.expected_inputs_for_expected_output( diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 732b4bec58ed5..890a068a7befc 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -752,10 +752,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { match *self.expr_ty.kind() { ty::FnDef(..) => { // Attempt a coercion to a fn pointer type. - let f = fcx.normalize_associated_types_in( - self.expr_span, - self.expr_ty.fn_sig(fcx.tcx), - ); + let f = fcx.normalize(self.expr_span, self.expr_ty.fn_sig(fcx.tcx)); let res = fcx.try_coerce( self.expr, self.expr_ty, diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 1ceb07def72e7..0c9a350c295f4 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -1,6 +1,6 @@ use crate::coercion::CoerceMany; use crate::gather_locals::GatherLocalsVisitor; -use crate::{FnCtxt, Inherited}; +use crate::FnCtxt; use crate::{GeneratorTypes, UnsafetyState}; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -20,21 +20,16 @@ use std::cell::RefCell; /// /// * ... /// * inherited: other fields inherited from the enclosing fn (if any) -#[instrument(skip(inherited, body), level = "debug")] +#[instrument(skip(fcx, body), level = "debug")] pub(super) fn check_fn<'a, 'tcx>( - inherited: &'a Inherited<'tcx>, - param_env: ty::ParamEnv<'tcx>, + fcx: &mut FnCtxt<'a, 'tcx>, fn_sig: ty::FnSig<'tcx>, decl: &'tcx hir::FnDecl<'tcx>, fn_def_id: LocalDefId, body: &'tcx hir::Body<'tcx>, can_be_generator: Option, -) -> (FnCtxt<'a, 'tcx>, Option>) { - let fn_id = inherited.tcx.hir().local_def_id_to_hir_id(fn_def_id); - - // Create the function context. This is either derived from scratch or, - // in the case of closures, based on the outer context. - let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id); +) -> Option> { + let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id); fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id)); let tcx = fcx.tcx; @@ -47,7 +42,7 @@ pub(super) fn check_fn<'a, 'tcx>( declared_ret_ty, body.value.hir_id, decl.output.span(), - param_env, + fcx.param_env, )); fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty))); @@ -105,7 +100,7 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.write_ty(param.hir_id, param_ty); } - inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig); + fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig); if let ty::Dynamic(_, _, ty::Dyn) = declared_ret_ty.kind() { // FIXME: We need to verify that the return type is `Sized` after the return expression has @@ -174,7 +169,7 @@ pub(super) fn check_fn<'a, 'tcx>( check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig, decl, declared_ret_ty); } - (fcx, gen_ty) + gen_ty } fn check_panic_info_fn( diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index e584d413c4190..5d3419b3b6e66 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -79,16 +79,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?bound_sig, ?liberated_sig); + let mut fcx = FnCtxt::new(self, self.param_env.without_const(), body.value.hir_id); let generator_types = check_fn( - self, - self.param_env.without_const(), + &mut fcx, liberated_sig, closure.fn_decl, expr_def_id, body, closure.movability, - ) - .1; + ); let parent_substs = InternalSubsts::identity_for_item( self.tcx, @@ -214,7 +213,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if expected_sig.is_none() && let ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) = bound_predicate.skip_binder() { - expected_sig = self.normalize_associated_types_in( + expected_sig = self.normalize( obligation.cause.span, self.deduce_sig_from_projection( Some(obligation.cause.span), @@ -623,7 +622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); // Astconv can't normalize inputs or outputs with escaping bound vars, // so normalize them here, after we've wrapped them in a binder. - let result = self.normalize_associated_types_in(self.tcx.hir().span(hir_id), result); + let result = self.normalize(self.tcx.hir().span(hir_id), result); let c_result = self.inh.infcx.canonicalize_response(result); self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result); @@ -797,12 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> ClosureSignatures<'tcx> { let liberated_sig = self.tcx().liberate_late_bound_regions(expr_def_id.to_def_id(), bound_sig); - let liberated_sig = self.inh.normalize_associated_types_in( - body.value.span, - self.tcx.hir().local_def_id_to_hir_id(expr_def_id), - self.param_env, - liberated_sig, - ); + let liberated_sig = self.normalize(body.value.span, liberated_sig); ClosureSignatures { bound_sig, liberated_sig } } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index b2d9d70fbd2ac..f0b349f0c98dd 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -62,7 +62,9 @@ use rustc_span::{self, BytePos, DesugaringKind, Span}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt}; +use rustc_trait_selection::traits::{ + self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt, +}; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; @@ -832,7 +834,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let b = self.shallow_resolve(b); let InferOk { value: b, mut obligations } = - self.normalize_associated_types_in_as_infer_ok(self.cause.span, b); + self.at(&self.cause, self.param_env).normalize(b); debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b); match b.kind() { @@ -854,7 +856,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } let InferOk { value: a_sig, obligations: o1 } = - self.normalize_associated_types_in_as_infer_ok(self.cause.span, a_sig); + self.at(&self.cause, self.param_env).normalize(a_sig); obligations.extend(o1); let a_fn_pointer = self.tcx.mk_fn_ptr(a_sig); @@ -1141,8 +1143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Err(TypeError::IntrinsicCast); } // The signature must match. - let a_sig = self.normalize_associated_types_in(new.span, a_sig); - let b_sig = self.normalize_associated_types_in(new.span, b_sig); + let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig)); let sig = self .at(cause, self.param_env) .trace(prev_ty, new_ty) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 5166f1fd1c743..0c5bbb3e20be3 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1664,7 +1664,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .fields .iter() .map(|f| { - let fru_ty = self.normalize_associated_types_in( + let fru_ty = self.normalize( expr_span, self.field_ty(base_expr.span, f, fresh_substs), ); @@ -1748,9 +1748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Adt(adt, substs) if adt.is_struct() => variant .fields .iter() - .map(|f| { - self.normalize_associated_types_in(expr_span, f.ty(self.tcx, substs)) - }) + .map(|f| self.normalize(expr_span, f.ty(self.tcx, substs))) .collect(), _ => { self.tcx diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 994fe48c9fee0..952d272625918 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -16,7 +16,7 @@ use rustc_hir_analysis::astconv::{ }; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; -use rustc_infer::infer::{InferOk, InferResult}; +use rustc_infer::infer::InferResult; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; @@ -30,9 +30,8 @@ use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{Span, DUMMY_SP}; -use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt}; +use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCauseCode, ObligationCtxt}; use std::collections::hash_map::Entry; use std::slice; @@ -343,7 +342,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { debug!("instantiate_type_scheme(value={:?}, substs={:?})", value, substs); let value = EarlyBinder(value).subst(self.tcx, substs); - let result = self.normalize_associated_types_in(span, value); + let result = self.normalize(span, value); debug!("instantiate_type_scheme = {:?}", result); result } @@ -359,7 +358,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let bounds = self.tcx.predicates_of(def_id); let spans: Vec = bounds.predicates.iter().map(|(_, span)| *span).collect(); let result = bounds.instantiate(self.tcx, substs); - let result = self.normalize_associated_types_in(span, result); + let result = self.normalize(span, result); debug!( "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}", bounds, substs, result, spans, @@ -367,50 +366,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (result, spans) } - pub(in super::super) fn normalize_associated_types_in(&self, span: Span, value: T) -> T + pub(in super::super) fn normalize(&self, span: Span, value: T) -> T where T: TypeFoldable<'tcx>, { - self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value) - } - - pub(in super::super) fn normalize_associated_types_in_as_infer_ok( - &self, - span: Span, - value: T, - ) -> InferOk<'tcx, T> - where - T: TypeFoldable<'tcx>, - { - self.inh.partially_normalize_associated_types_in( - ObligationCause::misc(span, self.body_id), - self.param_env, - value, - ) - } - - pub(in super::super) fn normalize_op_associated_types_in_as_infer_ok( - &self, - span: Span, - value: T, - opt_input_expr: Option<&hir::Expr<'_>>, - ) -> InferOk<'tcx, T> - where - T: TypeFoldable<'tcx>, - { - self.inh.partially_normalize_associated_types_in( - ObligationCause::new( - span, - self.body_id, - traits::BinOp { - rhs_span: opt_input_expr.map(|expr| expr.span), - is_lit: opt_input_expr - .map_or(false, |expr| matches!(expr.kind, ExprKind::Lit(_))), - output_ty: None, - }, - ), - self.param_env, - value, + self.register_infer_ok_obligations( + self.at(&self.misc(span), self.param_env).normalize(value), ) } @@ -490,7 +451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let span = self.tcx.def_span(anon_const.def_id); let c = ty::Const::from_anon_const(self.tcx, anon_const.def_id); self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None)); - self.normalize_associated_types_in(span, c) + self.normalize(span, c) } } } @@ -583,7 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: &'tcx ty::FieldDef, substs: SubstsRef<'tcx>, ) -> Ty<'tcx> { - self.normalize_associated_types_in(span, field.ty(self.tcx, substs)) + self.normalize(span, field.ty(self.tcx, substs)) } pub(in super::super) fn resolve_rvalue_scopes(&self, def_id: DefId) { @@ -1110,7 +1071,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Res::Local(hid) = res { let ty = self.local_ty(span, hid).decl_ty; - let ty = self.normalize_associated_types_in(span, ty); + let ty = self.normalize(span, ty); self.write_ty(hir_id, ty); return (ty, res); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index ed5f7f31764fd..ea141e815bf4a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -288,7 +288,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { if ty.has_escaping_bound_vars() { ty // FIXME: normalization and escaping regions } else { - self.normalize_associated_types_in(span, ty) + self.normalize(span, ty) } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 6c3526a71a328..b9a8d16311c93 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -20,6 +20,7 @@ use rustc_span::Span; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::DefIdOrName; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; +use rustc_trait_selection::traits::NormalizeExt; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn body_fn_sig(&self) -> Option> { @@ -245,7 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // implied by wf, but also because that would possibly result in // erroneous errors later on. let infer::InferOk { value: output, obligations: _ } = - self.normalize_associated_types_in_as_infer_ok(expr.span, output); + self.at(&self.misc(expr.span), self.param_env).normalize(output); if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) } } @@ -759,7 +760,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("suggest_missing_return_type: expected type {:?}", ty); let bound_vars = self.tcx.late_bound_vars(fn_id); let ty = Binder::bind_with_vars(ty, bound_vars); - let ty = self.normalize_associated_types_in(span, ty); + let ty = self.normalize(span, ty); let ty = self.tcx.erase_late_bound_regions(ty); if self.can_coerce(expected, ty) { err.subdiagnostic(ExpectedReturnTypeLabel::Other { span, expected }); @@ -920,7 +921,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = >::ast_ty_to_ty(self, ty); let bound_vars = self.tcx.late_bound_vars(fn_id); let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars)); - let ty = self.normalize_associated_types_in(expr.span, ty); + let ty = self.normalize(expr.span, ty); let ty = match self.tcx.asyncness(fn_id.owner) { hir::IsAsync::Async => { let infcx = self.tcx.infer_ctxt().build(); diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 4e044d39d50a1..3b1518ff79b4e 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -235,7 +235,7 @@ pub fn resolve_interior<'a, 'tcx>( counter += 1; ty::BoundRegion { var, kind } }; - let ty = fcx.normalize_associated_types_in(cause.span, cause.ty); + let ty = fcx.normalize(cause.span, cause.ty); let ty = fcx.tcx.fold_regions(ty, |region, current_depth| { let br = match region.kind() { ty::ReVar(vid) => { diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs index e5c9f439af3e0..869ad07c00d61 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/inherited.rs @@ -7,12 +7,10 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::HirIdMap; use rustc_infer::infer; use rustc_infer::infer::{DefiningAnchor, InferCtxt, InferOk, TyCtxtInferExt}; -use rustc_middle::ty::fold::TypeFoldable; 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::infer::InferCtxtExt as _; use rustc_trait_selection::traits::{ self, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _, }; @@ -102,7 +100,7 @@ impl<'tcx> Inherited<'tcx> { infcx.probe(|_| { let ocx = ObligationCtxt::new_in_snapshot(infcx); let normalized_fn_sig = ocx.normalize( - ObligationCause::dummy(), + &ObligationCause::dummy(), // FIXME(compiler-errors): This is probably not the right param-env... infcx.tcx.param_env(def_id), fn_sig, @@ -179,35 +177,4 @@ impl<'tcx> Inherited<'tcx> { self.register_predicates(infer_ok.obligations); infer_ok.value } - - pub(super) fn normalize_associated_types_in( - &self, - span: Span, - body_id: hir::HirId, - param_env: ty::ParamEnv<'tcx>, - value: T, - ) -> T - where - T: TypeFoldable<'tcx>, - { - self.normalize_associated_types_in_with_cause( - ObligationCause::misc(span, body_id), - param_env, - value, - ) - } - - pub(super) fn normalize_associated_types_in_with_cause( - &self, - cause: ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - value: T, - ) -> T - where - T: TypeFoldable<'tcx>, - { - let ok = self.partially_normalize_associated_types_in(cause, param_env, value); - debug!(?ok); - self.register_infer_ok_obligations(ok) - } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 5104b44802323..09bd123350dfd 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -233,9 +233,10 @@ fn typeck_with_fallback<'tcx>( let typeck_results = Inherited::build(tcx, def_id).enter(|inh| { let param_env = tcx.param_env(def_id); - let mut fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig { + let mut fcx = FnCtxt::new(&inh, param_env, body.value.hir_id); + + if let Some(hir::FnSig { header, decl, .. }) = fn_sig { let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() { - let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id); >::ty_of_fn(&fcx, id, header.unsafety, header.abi, decl, None, None) } else { tcx.fn_sig(def_id) @@ -245,15 +246,10 @@ fn typeck_with_fallback<'tcx>( // Compute the function signature from point of view of inside the fn. let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig); - let fn_sig = inh.normalize_associated_types_in( - body.value.span, - body_id.hir_id, - param_env, - fn_sig, - ); - check_fn(&inh, param_env, fn_sig, decl, def_id, body, None).0 + let fn_sig = fcx.normalize(body.value.span, fn_sig); + + check_fn(&mut fcx, fn_sig, decl, def_id, body, None); } else { - let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id); let expected_type = body_ty .and_then(|ty| match ty.kind { hir::TyKind::Infer => Some(>::ast_ty_to_ty(&fcx, ty)), @@ -304,7 +300,7 @@ fn typeck_with_fallback<'tcx>( _ => fallback(), }); - let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type); + let expected_type = fcx.normalize(body.value.span, expected_type); fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized); // Gather locals in statics (because of block expressions). @@ -313,8 +309,6 @@ fn typeck_with_fallback<'tcx>( fcx.check_expr_coercable_to_type(&body.value, expected_type, None); fcx.write_ty(id, expected_type); - - fcx }; fcx.type_inference_fallback(); diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index f50a16dcb236d..03d0e7926de11 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -106,7 +106,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // traits, no trait system method can be called before this point because they // could alter our Self-type, except for normalizing the receiver from the // signature (which is also done during probing). - let method_sig_rcvr = self.normalize_associated_types_in(self.span, method_sig.inputs()[0]); + let method_sig_rcvr = self.normalize(self.span, method_sig.inputs()[0]); debug!( "confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}", self_ty, method_sig_rcvr, method_sig, method_predicates @@ -114,7 +114,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.unify_receivers(self_ty, method_sig_rcvr, &pick, all_substs); let (method_sig, method_predicates) = - self.normalize_associated_types_in(self.span, (method_sig, method_predicates)); + self.normalize(self.span, (method_sig, method_predicates)); let method_sig = ty::Binder::dummy(method_sig); // Make sure nobody calls `drop()` explicitly. diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 9c2de1763b080..ebbd5eb1e6478 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -23,8 +23,8 @@ use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, Ty, TypeVisitable}; use rustc_span::symbol::Ident; use rustc_span::Span; -use rustc_trait_selection::traits; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; +use rustc_trait_selection::traits::{self, NormalizeExt}; use self::probe::{IsSuggestion, ProbeScope}; @@ -465,11 +465,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let fn_sig = fn_sig.subst(self.tcx, substs); let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig); - let InferOk { value, obligations: o } = if is_op { - self.normalize_op_associated_types_in_as_infer_ok(span, fn_sig, opt_input_expr) + let cause = if is_op { + ObligationCause::new( + span, + self.body_id, + traits::BinOp { + rhs_span: opt_input_expr.map(|expr| expr.span), + is_lit: opt_input_expr + .map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))), + output_ty: None, + }, + ) } else { - self.normalize_associated_types_in_as_infer_ok(span, fn_sig) + traits::ObligationCause::misc(span, self.body_id) }; + + let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(fn_sig); let fn_sig = { obligations.extend(o); value @@ -485,11 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // any late-bound regions appearing in its bounds. let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs); - let InferOk { value, obligations: o } = if is_op { - self.normalize_op_associated_types_in_as_infer_ok(span, bounds, opt_input_expr) - } else { - self.normalize_associated_types_in_as_infer_ok(span, bounds) - }; + let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(bounds); let bounds = { obligations.extend(o); value @@ -497,20 +504,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { assert!(!bounds.has_escaping_bound_vars()); - let cause = if is_op { - ObligationCause::new( - span, - self.body_id, - traits::BinOp { - rhs_span: opt_input_expr.map(|expr| expr.span), - is_lit: opt_input_expr - .map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))), - output_ty: None, - }, - ) - } else { - traits::ObligationCause::misc(span, self.body_id) - }; let predicates_cause = cause.clone(); obligations.extend(traits::predicates_for_generics( move |_, _| predicates_cause.clone(), diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 4380e66a0d248..c78a32c29dcda 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -31,13 +31,13 @@ use rustc_span::lev_distance::{ use rustc_span::symbol::sym; use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP}; use rustc_trait_selection::autoderef::{self, Autoderef}; -use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy; use rustc_trait_selection::traits::query::method_autoderef::{ CandidateStep, MethodAutoderefStepsResult, }; use rustc_trait_selection::traits::query::CanonicalTyGoal; +use rustc_trait_selection::traits::NormalizeExt; use rustc_trait_selection::traits::{self, ObligationCause}; use std::cmp::max; use std::iter; @@ -716,9 +716,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized, // see issue #89650 let cause = traits::ObligationCause::misc(self.span, self.body_id); - let InferOk { value: xform_self_ty, obligations } = self - .fcx - .partially_normalize_associated_types_in(cause, self.param_env, xform_self_ty); + let InferOk { value: xform_self_ty, obligations } = + self.fcx.at(&cause, self.param_env).normalize(xform_self_ty); debug!( "assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}", @@ -1507,11 +1506,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let InferOk { value: normalized_xform_ret_ty, obligations: normalization_obligations, - } = self.fcx.partially_normalize_associated_types_in( - cause.clone(), - self.param_env, - probe.xform_ret_ty, - ); + } = self.fcx.at(&cause, self.param_env).normalize(probe.xform_ret_ty); xform_ret_ty = normalized_xform_ret_ty; debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty); @@ -1521,11 +1516,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let impl_bounds = impl_bounds.instantiate(self.tcx, substs); let InferOk { value: impl_bounds, obligations: norm_obligations } = - self.fcx.partially_normalize_associated_types_in( - cause.clone(), - self.param_env, - impl_bounds, - ); + self.fcx.at(&cause, self.param_env).normalize(impl_bounds); // Convert the bounds into obligations. let impl_obligations = traits::predicates_for_generics( diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index af3a7ae248665..e988c77a064f6 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -1,6 +1,6 @@ use crate::errors::AutoDerefReachedRecursionLimit; -use crate::infer::InferCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt; +use crate::traits::NormalizeExt; use crate::traits::{self, TraitEngine, TraitEngineExt}; use rustc_hir as hir; use rustc_infer::infer::InferCtxt; @@ -138,11 +138,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { return None; } - let normalized_ty = self.infcx.partially_normalize_associated_types_in( - cause, - self.param_env, - tcx.mk_projection(tcx.lang_items().deref_target()?, trait_ref.substs), - ); + let normalized_ty = self + .infcx + .at(&cause, self.param_env) + .normalize(tcx.mk_projection(tcx.lang_items().deref_target()?, trait_ref.substs)); let mut fulfillcx = >::new_in_snapshot(tcx); let normalized_ty = normalized_ty.into_value_registering_obligations(self.infcx, &mut *fulfillcx); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 25a9c29caa7ab..6c70bbf75163a 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -3,7 +3,6 @@ use crate::traits::{self, ObligationCtxt}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_infer::traits::ObligationCause; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse}; use rustc_middle::traits::query::Fallible; @@ -30,15 +29,6 @@ pub trait InferCtxtExt<'tcx> { span: Span, ) -> bool; - fn partially_normalize_associated_types_in( - &self, - cause: ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - value: T, - ) -> InferOk<'tcx, T> - where - T: TypeFoldable<'tcx>; - /// Check whether a `ty` implements given trait(trait_def_id). /// The inputs are: /// @@ -88,24 +78,6 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item, span) } - /// Normalizes associated types in `value`, potentially returning - /// new obligations that must further be processed. - #[instrument(level = "debug", skip(self, cause, param_env), ret)] - fn partially_normalize_associated_types_in( - &self, - cause: ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - value: T, - ) -> InferOk<'tcx, T> - where - T: TypeFoldable<'tcx>, - { - let mut selcx = traits::SelectionContext::new(self); - let traits::Normalized { value, obligations } = - traits::normalize(&mut selcx, param_env, cause, value); - InferOk { value, obligations } - } - #[instrument(level = "debug", skip(self, params), ret)] fn type_implements_trait( &self, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 3a05708aebc6c..64d01ddb09a49 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use super::TraitEngine; use super::{ChalkFulfillmentContext, FulfillmentContext}; -use crate::infer::InferCtxtExt; +use crate::traits::NormalizeExt; use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::at::ToTrace; @@ -104,11 +104,11 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { pub fn normalize>( &self, - cause: ObligationCause<'tcx>, + cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, value: T, ) -> T { - let infer_ok = self.infcx.partially_normalize_associated_types_in(cause, param_env, value); + let infer_ok = self.infcx.at(&cause, param_env).normalize(value); self.register_infer_ok_obligations(infer_ok) } @@ -185,7 +185,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { // sound and then uncomment this line again. // implied_bounds.insert(ty); - let normalized = self.normalize(cause.clone(), param_env, ty); + let normalized = self.normalize(&cause, param_env, ty); implied_bounds.insert(normalized); } implied_bounds diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs index 6a5744f5f762b..752b53fbc3f9a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs @@ -17,11 +17,11 @@ pub fn recompute_applicable_impls<'tcx>( let placeholder_obligation = infcx.replace_bound_vars_with_placeholders(obligation.predicate); let obligation_trait_ref = - ocx.normalize(dummy_cause.clone(), param_env, placeholder_obligation.trait_ref); + ocx.normalize(&dummy_cause, param_env, placeholder_obligation.trait_ref); let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); let impl_trait_ref = tcx.bound_impl_trait_ref(impl_def_id).unwrap().subst(tcx, impl_substs); - let impl_trait_ref = ocx.normalize(ObligationCause::dummy(), param_env, impl_trait_ref); + let impl_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, impl_trait_ref); if let Err(_) = ocx.eq(&dummy_cause, param_env, obligation_trait_ref, impl_trait_ref) { return false; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index b364609d986ed..049b24b39975d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -9,11 +9,11 @@ use super::{ }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use crate::infer::InferCtxtExt as _; use crate::infer::{self, InferCtxt, TyCtxtInferExt}; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::query::normalize::AtExt as _; +use crate::traits::query::normalize::QueryNormalizeExt as _; use crate::traits::specialize::to_pretty_impl_header; +use crate::traits::NormalizeExt; use on_unimplemented::OnUnimplementedNote; use on_unimplemented::TypeErrCtxtExt as _; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; @@ -1595,6 +1595,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { bound_predicate.rebind(data), ); let mut obligations = vec![]; + // FIXME(normalization): Change this to use `At::normalize` let normalized_ty = super::normalize_projection_type( &mut selcx, obligation.param_env, @@ -1933,7 +1934,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let infcx = self.tcx.infer_ctxt().build(); infcx .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) - .normalize(candidate) + .query_normalize(candidate) .map_or(candidate, |normalized| normalized.value) }; @@ -2535,11 +2536,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); let InferOk { value: cleaned_pred, .. } = - self.infcx.partially_normalize_associated_types_in( - ObligationCause::dummy(), - param_env, - cleaned_pred, - ); + self.infcx.at(&ObligationCause::dummy(), param_env).normalize(cleaned_pred); let obligation = Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 09f30f976de91..1740128727a5a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2,6 +2,7 @@ use super::{DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, Predi use crate::autoderef::Autoderef; use crate::infer::InferCtxt; +use crate::traits::NormalizeExt; use hir::def::CtorOf; use hir::HirId; @@ -2966,12 +2967,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.tcx.mk_substs_trait(trait_pred.self_ty(), []), ) }); - let InferOk { value: projection_ty, .. } = self - .partially_normalize_associated_types_in( - obligation.cause.clone(), - obligation.param_env, - projection_ty, - ); + let InferOk { value: projection_ty, .. } = + self.at(&obligation.cause, obligation.param_env).normalize(projection_ty); debug!( normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 5285cfa674669..371367f0deb3e 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -56,7 +56,8 @@ pub use self::object_safety::astconv_object_safety_violations; pub use self::object_safety::is_vtable_safe_method; pub use self::object_safety::MethodViolationCode; pub use self::object_safety::ObjectSafetyViolation; -pub use self::project::{normalize, normalize_projection_type, normalize_to}; +pub(crate) use self::project::{normalize, normalize_to}; +pub use self::project::{normalize_projection_type, NormalizeExt}; pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; pub use self::specialize::specialization_graph::FutureCompatOverlapError; @@ -386,7 +387,7 @@ where { let ocx = ObligationCtxt::new(infcx); debug!(?value); - let normalized_value = ocx.normalize(cause, param_env, value); + let normalized_value = ocx.normalize(&cause, param_env, value); debug!(?normalized_value); debug!("select_all_or_error start"); let errors = ocx.select_all_or_error(); @@ -453,7 +454,7 @@ pub fn impossible_predicates<'tcx>( let infcx = tcx.infer_ctxt().build(); let param_env = ty::ParamEnv::reveal_all(); let ocx = ObligationCtxt::new(&infcx); - let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates); + let predicates = ocx.normalize(&ObligationCause::dummy(), param_env, predicates); for predicate in predicates { let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate); ocx.register_obligation(obligation); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e33e89e9c5c3e..113803cd1790a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -27,6 +27,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; +use rustc_infer::infer::at::At; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::ImplSourceBuiltinData; use rustc_middle::traits::select::OverflowError; @@ -48,6 +49,19 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>> pub(super) struct InProgress; +pub trait NormalizeExt<'tcx> { + fn normalize>(&self, t: T) -> InferOk<'tcx, T>; +} + +impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> { + fn normalize>(&self, value: T) -> InferOk<'tcx, T> { + let mut selcx = SelectionContext::new(self.infcx); + let Normalized { value, obligations } = + normalize(&mut selcx, self.param_env, self.cause.clone(), value); + InferOk { value, obligations } + } +} + /// When attempting to resolve `::Name` ... #[derive(Debug)] pub enum ProjectionError<'tcx> { @@ -293,7 +307,7 @@ fn project_and_unify_type<'cx, 'tcx>( /// them with a fully resolved type where possible. The return value /// combines the normalized result and any additional obligations that /// were incurred as result. -pub fn normalize<'a, 'b, 'tcx, T>( +pub(crate) fn normalize<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, @@ -307,7 +321,7 @@ where Normalized { value, obligations } } -pub fn normalize_to<'a, 'b, 'tcx, T>( +pub(crate) fn normalize_to<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, @@ -321,7 +335,7 @@ where } /// As `normalize`, but with a custom depth. -pub fn normalize_with_depth<'a, 'b, 'tcx, T>( +pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, @@ -337,7 +351,7 @@ where } #[instrument(level = "info", skip(selcx, param_env, cause, obligations))] -pub fn normalize_with_depth_to<'a, 'b, 'tcx, T>( +pub(crate) fn normalize_with_depth_to<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, @@ -357,7 +371,7 @@ where } #[instrument(level = "info", skip(selcx, param_env, cause, obligations))] -pub fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>( +pub(crate) fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index a875ea1578dcb..1aed66308709e 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -22,13 +22,13 @@ use super::NoSolution; pub use rustc_middle::traits::query::NormalizationResult; -pub trait AtExt<'tcx> { - fn normalize(&self, value: T) -> Result, NoSolution> +pub trait QueryNormalizeExt<'tcx> { + fn query_normalize(&self, value: T) -> Result, NoSolution> where T: TypeFoldable<'tcx>; } -impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> { +impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> { /// Normalize `value` in the context of the inference context, /// yielding a resulting type, or an error if `value` cannot be /// normalized. If you don't care about regions, you should prefer @@ -42,7 +42,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> { /// normalizing, but for now should be used only when we actually /// know that normalization will succeed, since error reporting /// and other details are still "under development". - fn normalize(&self, value: T) -> Result, NoSolution> + fn query_normalize(&self, value: T) -> Result, NoSolution> where T: TypeFoldable<'tcx>, { diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index a06db4c274831..51968c2d7a191 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -8,8 +8,8 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable}; use rustc_middle::ty::{GenericArg, SubstsRef}; +use super::NormalizeExt; use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext}; -use crate::infer::InferCtxtExt; use rustc_infer::infer::InferOk; pub use rustc_infer::traits::{self, util::*}; @@ -202,15 +202,13 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( ) -> (ImplSubject<'tcx>, impl Iterator>) { let subject = selcx.tcx().bound_impl_subject(impl_def_id); let subject = subject.subst(selcx.tcx(), impl_substs); - let InferOk { value: subject, obligations: normalization_obligations1 } = selcx - .infcx - .partially_normalize_associated_types_in(ObligationCause::dummy(), param_env, subject); + let InferOk { value: subject, obligations: normalization_obligations1 } = + selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(subject); let predicates = selcx.tcx().predicates_of(impl_def_id); let predicates = predicates.instantiate(selcx.tcx(), impl_substs); - let InferOk { value: predicates, obligations: normalization_obligations2 } = selcx - .infcx - .partially_normalize_associated_types_in(ObligationCause::dummy(), param_env, predicates); + let InferOk { value: predicates, obligations: normalization_obligations2 } = + selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates); let impl_obligations = super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates); diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 7b4ad9fea137a..66ab742f15782 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -11,7 +11,7 @@ use rustc_trait_selection::traits::query::dropck_outlives::trivial_dropck_outliv use rustc_trait_selection::traits::query::dropck_outlives::{ DropckConstraint, DropckOutlivesResult, }; -use rustc_trait_selection::traits::query::normalize::AtExt; +use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution}; use rustc_trait_selection::traits::{Normalized, ObligationCause}; @@ -100,7 +100,7 @@ fn dropck_outlives<'tcx>( // to push them onto the stack to be expanded. for ty in constraints.dtorck_types.drain(..) { let Normalized { value: ty, obligations } = - ocx.infcx.at(&cause, param_env).normalize(ty)?; + ocx.infcx.at(&cause, param_env).query_normalize(ty)?; ocx.register_obligations(obligations); debug!("dropck_outlives: ty from dtorck_types = {:?}", ty); diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index bd22d113b4092..44fd8bfb31f23 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -2,7 +2,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable}; -use rustc_trait_selection::traits::query::normalize::AtExt; +use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Normalized, ObligationCause}; use std::sync::atomic::Ordering; @@ -29,7 +29,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + let ParamEnvAnd { param_env, value } = goal; let infcx = tcx.infer_ctxt().build(); let cause = ObligationCause::dummy(); - match infcx.at(&cause, param_env).normalize(value) { + match infcx.at(&cause, param_env).query_normalize(value) { Ok(Normalized { value: normalized_value, obligations: normalized_obligations }) => { // We don't care about the `obligations`; they are // always only region relations, and we are about to diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index c6c072ea3d2bd..7f964afde80fd 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::{ParamEnvAnd, Predicate, ToPredicate}; use rustc_middle::ty::{UserSelfTy, UserSubsts}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtBuilderExt; -use rustc_trait_selection::traits::query::normalize::AtExt; +use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::query::type_op::ascribe_user_type::AscribeUserType; use rustc_trait_selection::traits::query::type_op::eq::Eq; use rustc_trait_selection::traits::query::type_op::normalize::Normalize; @@ -62,7 +62,7 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>( let cause = ObligationCause::dummy_with_span(span); let ty = tcx.bound_type_of(def_id).subst(tcx, substs); - let ty = ocx.normalize(cause.clone(), param_env, ty); + let ty = ocx.normalize(&cause, param_env, ty); debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); ocx.eq(&cause, param_env, mir_ty, ty)?; @@ -85,14 +85,14 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>( ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span), ); let instantiated_predicate = - ocx.normalize(cause.clone(), param_env, instantiated_predicate); + ocx.normalize(&cause.clone(), param_env, instantiated_predicate); ocx.register_obligation(Obligation::new(tcx, cause, param_env, instantiated_predicate)); } if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs); - let impl_self_ty = ocx.normalize(cause.clone(), param_env, impl_self_ty); + let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty); ocx.eq(&cause, param_env, self_ty, impl_self_ty)?; @@ -137,7 +137,7 @@ where { let (param_env, Normalize { value }) = key.into_parts(); let Normalized { value, obligations } = - ocx.infcx.at(&ObligationCause::dummy(), param_env).normalize(value)?; + ocx.infcx.at(&ObligationCause::dummy(), param_env).query_normalize(value)?; ocx.register_obligations(obligations); Ok(value) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 42328222fd382..b18788a033fb6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1581,14 +1581,14 @@ fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'tcx>) -> Option> } use crate::rustc_trait_selection::infer::TyCtxtInferExt; - use crate::rustc_trait_selection::traits::query::normalize::AtExt; + use crate::rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_middle::traits::ObligationCause; // Try to normalize `::T` to a type let infcx = cx.tcx.infer_ctxt().build(); let normalized = infcx .at(&ObligationCause::dummy(), cx.param_env) - .normalize(ty) + .query_normalize(ty) .map(|resolved| infcx.resolve_vars_if_possible(resolved.value)); match normalized { Ok(normalized_value) => { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index f4459e3e6633a..2ceda3511fe44 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -22,7 +22,7 @@ use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::{Size, VariantIdx}; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::query::normalize::AtExt; +use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use std::iter; use crate::{match_def_path, path_res, paths}; @@ -283,7 +283,7 @@ fn is_normalizable_helper<'tcx>( cache.insert(ty, false); let infcx = cx.tcx.infer_ctxt().build(); let cause = rustc_middle::traits::ObligationCause::dummy(); - let result = if infcx.at(&cause, param_env).normalize(ty).is_ok() { + let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() { match ty.kind() { ty::Adt(def, substs) => def.variants().iter().all(|variant| { variant