diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 02071ed6b3666..dac6abe37f589 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -5,14 +5,14 @@ use rustc_infer::infer::region_constraints::Constraint; use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _}; -use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt}; +use rustc_infer::traits::ObligationCause; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::RegionVid; use rustc_middle::ty::UniverseIndex; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::query::type_op; -use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _}; +use rustc_trait_selection::traits::ObligationCtxt; use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause}; use std::fmt; @@ -240,9 +240,9 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { ) -> Option> { let (ref infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); - let mut fulfill_cx = >::new(infcx.tcx); - type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause); - try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) + let ocx = ObligationCtxt::new(infcx); + type_op_prove_predicate_with_cause(&ocx, key, cause); + try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) } } @@ -281,9 +281,7 @@ where ) -> Option> { let (ref infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); - let mut fulfill_cx = >::new(infcx.tcx); - - let mut selcx = SelectionContext::new(infcx); + let ocx = ObligationCtxt::new(infcx); // 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 @@ -292,11 +290,9 @@ where // 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 Normalized { value: _, obligations } = - rustc_trait_selection::traits::normalize(&mut selcx, param_env, cause, value.value); - fulfill_cx.register_predicate_obligations(infcx, obligations); + let _ = ocx.normalize(cause, param_env, value.value); - try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) + try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) } } @@ -329,9 +325,9 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { ) -> Option> { let (ref infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); - let mut fulfill_cx = >::new(infcx.tcx); - type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span)).ok()?; - try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) + let ocx = ObligationCtxt::new(infcx); + type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?; + try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) } } @@ -372,25 +368,24 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { } } -#[instrument(skip(fulfill_cx, infcx), level = "debug")] +#[instrument(skip(ocx), level = "debug")] fn try_extract_error_from_fulfill_cx<'tcx>( - mut fulfill_cx: Box + 'tcx>, - infcx: &InferCtxt<'tcx>, + ocx: &ObligationCtxt<'_, 'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, ) -> Option> { // We generally shouldn't have errors here because the query was // already run, but there's no point using `delay_span_bug` // when we're going to emit an error here anyway. - let _errors = fulfill_cx.select_all_or_error(infcx); - let region_constraints = infcx.with_region_constraints(|r| r.clone()); + let _errors = ocx.select_all_or_error(); + let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone()); try_extract_error_from_region_constraints( - infcx, + ocx.infcx, placeholder_region, error_region, ®ion_constraints, - |vid| infcx.region_var_origin(vid), - |vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(vid))), + |vid| ocx.infcx.region_var_origin(vid), + |vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_region(ty::ReVar(vid))), ) } diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 32f66b06f8358..aeaf7a6cfe1f1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -290,10 +290,7 @@ fn compare_predicate_entailment<'tcx>( // type would be more appropriate. In other places we have a `Vec` // corresponding to their `Vec`, but we don't have that here. // Fixing this would improve the output of test `issue-83765.rs`. - let mut result = infcx - .at(&cause, param_env) - .sup(trait_fty, impl_fty) - .map(|infer_ok| ocx.register_infer_ok_obligations(infer_ok)); + let mut result = ocx.sup(&cause, param_env, trait_fty, impl_fty); // HACK(RPITIT): #101614. When we are trying to infer the hidden types for // RPITITs, we need to equate the output tys instead of just subtyping. If @@ -301,12 +298,8 @@ fn compare_predicate_entailment<'tcx>( // us to infer `_#1t = #'_#2r str`, where `'_#2r` is unconstrained, which gets // fixed up to `ReEmpty`, and which is certainly not what we want. if trait_fty.has_infer_types() { - result = result.and_then(|()| { - infcx - .at(&cause, param_env) - .eq(trait_sig.output(), impl_sig.output()) - .map(|infer_ok| ocx.register_infer_ok_obligations(infer_ok)) - }); + result = + result.and_then(|()| ocx.eq(&cause, param_env, trait_sig.output(), impl_sig.output())); } if let Err(terr) = result { @@ -1389,10 +1382,7 @@ pub(crate) fn raw_compare_const_impl<'tcx>( debug!("compare_const_impl: trait_ty={:?}", trait_ty); - let err = infcx - .at(&cause, param_env) - .sup(trait_ty, impl_ty) - .map(|ok| ocx.register_infer_ok_obligations(ok)); + let err = ocx.sup(&cause, param_env, trait_ty, impl_ty); if let Err(terr) = err { debug!( diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 99d0beacfa0a1..0117bdd0ba81c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1674,7 +1674,7 @@ fn receiver_is_valid<'tcx>( // `self: Self` is always valid. if can_eq_self(receiver_ty) { - if let Err(err) = wfcx.equate_types(&cause, wfcx.param_env, self_ty, receiver_ty) { + if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, receiver_ty) { infcx.err_ctxt().report_mismatched_types(&cause, self_ty, receiver_ty, err).emit(); } return true; @@ -1704,9 +1704,7 @@ fn receiver_is_valid<'tcx>( if can_eq_self(potential_self_ty) { wfcx.register_obligations(autoderef.into_obligations()); - if let Err(err) = - wfcx.equate_types(&cause, wfcx.param_env, self_ty, potential_self_ty) - { + if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty) { infcx .err_ctxt() .report_mismatched_types(&cause, self_ty, potential_self_ty, err) diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 06ca2534d5c3f..cbd6481f9cb81 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -43,7 +43,7 @@ impl<'tcx> InferCtxt<'tcx> { /// /// This is only meant to be invoked as part of constructing an /// inference context at the start of a query (see - /// `InferCtxtBuilder::enter_with_canonical`). It basically + /// `InferCtxtBuilder::build_with_canonical`). It basically /// brings the canonical value "into scope" within your new infcx. /// /// At the end of processing, the substitution S (once diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index a335f8e06bc94..96ac4e9c1292a 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,5 +1,5 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::{self, TraitEngine, TraitEngineExt}; +use crate::traits::{self, ObligationCtxt}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; @@ -142,7 +142,7 @@ pub trait InferCtxtBuilderExt<'tcx> { fn enter_canonical_trait_query( &mut self, canonical_key: &Canonical<'tcx, K>, - operation: impl FnOnce(&InferCtxt<'tcx>, &mut dyn TraitEngine<'tcx>, K) -> Fallible, + operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible, ) -> Fallible> where K: TypeFoldable<'tcx>, @@ -170,17 +170,17 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> { fn enter_canonical_trait_query( &mut self, canonical_key: &Canonical<'tcx, K>, - operation: impl FnOnce(&InferCtxt<'tcx>, &mut dyn TraitEngine<'tcx>, K) -> Fallible, + operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible, ) -> Fallible> where K: TypeFoldable<'tcx>, R: Debug + TypeFoldable<'tcx>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>, { - let (ref infcx, key, canonical_inference_vars) = + let (infcx, key, canonical_inference_vars) = self.build_with_canonical(DUMMY_SP, canonical_key); - let mut fulfill_cx = >::new(infcx.tcx); - let value = operation(infcx, &mut *fulfill_cx, key)?; - infcx.make_canonicalized_query_response(canonical_inference_vars, value, &mut *fulfill_cx) + let ocx = ObligationCtxt::new(&infcx); + let value = operation(&ocx, key)?; + ocx.make_canonicalized_query_response(canonical_inference_vars, value) } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index e0c8deec91aff..21516c93efb53 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -1,14 +1,21 @@ use std::cell::RefCell; +use std::fmt::Debug; use super::TraitEngine; use super::{ChalkFulfillmentContext, FulfillmentContext}; use crate::infer::InferCtxtExt; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_infer::infer::at::ToTrace; +use rustc_infer::infer::canonical::{ + Canonical, CanonicalVarValues, CanonicalizedQueryResponse, QueryResponse, +}; use rustc_infer::infer::{InferCtxt, InferOk}; +use rustc_infer::traits::query::Fallible; use rustc_infer::traits::{ FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _, }; +use rustc_middle::arena::ArenaAllocatable; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::ToPredicate; use rustc_middle::ty::TypeFoldable; @@ -105,12 +112,12 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.register_infer_ok_obligations(infer_ok) } - pub fn equate_types( + pub fn eq>( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - expected: Ty<'tcx>, - actual: Ty<'tcx>, + expected: T, + actual: T, ) -> Result<(), TypeError<'tcx>> { match self.infcx.at(cause, param_env).eq(expected, actual) { Ok(InferOk { obligations, value: () }) => { @@ -121,6 +128,22 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { } } + pub fn sup>( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + expected: T, + actual: T, + ) -> Result<(), TypeError<'tcx>> { + match self.infcx.at(cause, param_env).sup(expected, actual) { + Ok(InferOk { obligations, value: () }) => { + self.register_obligations(obligations); + Ok(()) + } + Err(e) => Err(e), + } + } + pub fn select_all_or_error(&self) -> Vec> { self.engine.borrow_mut().select_all_or_error(self.infcx) } @@ -154,4 +177,20 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { } implied_bounds } + + pub fn make_canonicalized_query_response( + &self, + inference_vars: CanonicalVarValues<'tcx>, + answer: T, + ) -> Fallible> + where + T: Debug + TypeFoldable<'tcx>, + Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, + { + self.infcx.make_canonicalized_query_response( + inference_vars, + answer, + &mut **self.engine.borrow_mut(), + ) + } } diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 7d36b9558d50b..82f6111f6f92e 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -28,9 +28,9 @@ fn implied_outlives_bounds<'tcx>( &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { - tcx.infer_ctxt().enter_canonical_trait_query(&goal, |infcx, _fulfill_cx, key| { + tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { let (param_env, ty) = key.into_parts(); - compute_implied_outlives_bounds(&infcx, param_env, ty) + compute_implied_outlives_bounds(&ocx.infcx, param_env, ty) }) } diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 0da28737f69bc..0ffa92f1ad55d 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -3,6 +3,7 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] +#![feature(let_chains)] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 98bb42c9afda1..e805eb4282119 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -1,6 +1,5 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_trait_selection::infer::InferCtxtBuilderExt; @@ -23,8 +22,8 @@ fn normalize_projection_ty<'tcx>( tcx.sess.perf_stats.normalize_projection_ty.fetch_add(1, Ordering::Relaxed); tcx.infer_ctxt().enter_canonical_trait_query( &goal, - |infcx, fulfill_cx, ParamEnvAnd { param_env, value: goal }| { - let selcx = &mut SelectionContext::new(infcx); + |ocx, ParamEnvAnd { param_env, value: goal }| { + let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); let mut obligations = vec![]; let answer = traits::normalize_projection_type( @@ -35,7 +34,7 @@ fn normalize_projection_ty<'tcx>( 0, &mut obligations, ); - fulfill_cx.register_predicate_obligations(infcx, obligations); + ocx.register_obligations(obligations); // FIXME(associated_const_equality): All users of normalize_projection_ty expected // a type, but there is the possibility it could've been a const now. Maybe change // it to a Term later? diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index bca7458ed332b..98cb3f21555ac 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -2,17 +2,14 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; -use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; -use rustc_infer::traits::{ObligationCauseCode, TraitEngineExt as _}; +use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; +use rustc_infer::traits::ObligationCauseCode; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{ - self, EarlyBinder, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable, Variance, -}; -use rustc_middle::ty::{GenericArg, UserSelfTy, UserSubsts}; -use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Predicate, ToPredicate}; +use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable}; +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::infer::InferCtxtExt; use rustc_trait_selection::traits::query::normalize::AtExt; use rustc_trait_selection::traits::query::type_op::ascribe_user_type::AscribeUserType; use rustc_trait_selection::traits::query::type_op::eq::Eq; @@ -20,7 +17,7 @@ use rustc_trait_selection::traits::query::type_op::normalize::Normalize; use rustc_trait_selection::traits::query::type_op::prove_predicate::ProvePredicate; use rustc_trait_selection::traits::query::type_op::subtype::Subtype; use rustc_trait_selection::traits::query::{Fallible, NoSolution}; -use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, TraitEngine}; +use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt}; use std::fmt; use std::iter::zip; @@ -42,17 +39,16 @@ fn type_op_ascribe_user_type<'tcx>( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { - tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { - type_op_ascribe_user_type_with_span(infcx, fulfill_cx, key, None) + tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { + type_op_ascribe_user_type_with_span(ocx, key, None) }) } /// The core of the `type_op_ascribe_user_type` query: for diagnostics purposes in NLL HRTB errors, /// this query can be re-run to better track the span of the obligation cause, and improve the error /// message. Do not call directly unless you're in that very specific context. -pub fn type_op_ascribe_user_type_with_span<'a, 'tcx: 'a>( - infcx: &'a InferCtxt<'tcx>, - fulfill_cx: &'a mut dyn TraitEngine<'tcx>, +pub fn type_op_ascribe_user_type_with_span<'tcx>( + ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>, span: Option, ) -> Result<(), NoSolution> { @@ -61,68 +57,50 @@ pub fn type_op_ascribe_user_type_with_span<'a, 'tcx: 'a>( "type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}", mir_ty, def_id, user_substs ); - - let mut cx = AscribeUserTypeCx { infcx, param_env, span: span.unwrap_or(DUMMY_SP), fulfill_cx }; + let cx = AscribeUserTypeCx { ocx, param_env, span: span.unwrap_or(DUMMY_SP) }; cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs)?; Ok(()) } struct AscribeUserTypeCx<'me, 'tcx> { - infcx: &'me InferCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + ocx: &'me ObligationCtxt<'me, 'tcx>, + param_env: ty::ParamEnv<'tcx>, span: Span, - fulfill_cx: &'me mut dyn TraitEngine<'tcx>, } impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { - fn normalize(&mut self, value: T) -> T + fn normalize(&self, value: T) -> T where T: TypeFoldable<'tcx>, { self.normalize_with_cause(value, ObligationCause::misc(self.span, hir::CRATE_HIR_ID)) } - fn normalize_with_cause(&mut self, value: T, cause: ObligationCause<'tcx>) -> T + fn normalize_with_cause(&self, value: T, cause: ObligationCause<'tcx>) -> T where T: TypeFoldable<'tcx>, { - self.infcx - .partially_normalize_associated_types_in(cause, self.param_env, value) - .into_value_registering_obligations(self.infcx, self.fulfill_cx) + self.ocx.normalize(cause, self.param_env, value) } - fn relate(&mut self, a: T, variance: Variance, b: T) -> Result<(), NoSolution> + fn eq(&self, a: T, b: T) -> Result<(), NoSolution> where T: ToTrace<'tcx>, { - self.infcx - .at(&ObligationCause::dummy_with_span(self.span), self.param_env) - .relate(a, variance, b)? - .into_value_registering_obligations(self.infcx, self.fulfill_cx); - Ok(()) + Ok(self.ocx.eq(&ObligationCause::dummy_with_span(self.span), self.param_env, a, b)?) } - fn prove_predicate(&mut self, predicate: Predicate<'tcx>, cause: ObligationCause<'tcx>) { - self.fulfill_cx.register_predicate_obligation( - self.infcx, - Obligation::new(cause, self.param_env, predicate), - ); + fn prove_predicate(&self, predicate: Predicate<'tcx>, cause: ObligationCause<'tcx>) { + self.ocx.register_obligation(Obligation::new(cause, self.param_env, predicate)); } fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - fn subst(&self, value: T, substs: &[GenericArg<'tcx>]) -> T - where - T: TypeFoldable<'tcx>, - { - EarlyBinder(value).subst(self.tcx(), substs) + self.ocx.infcx.tcx } #[instrument(level = "debug", skip(self))] fn relate_mir_and_user_ty( - &mut self, + &self, mir_ty: Ty<'tcx>, def_id: DefId, user_substs: UserSubsts<'tcx>, @@ -130,20 +108,18 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { let UserSubsts { user_self_ty, substs } = user_substs; let tcx = self.tcx(); - let ty = tcx.type_of(def_id); - let ty = self.subst(ty, substs); + let ty = tcx.bound_type_of(def_id).subst(tcx, substs); let ty = self.normalize(ty); debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); - self.relate(mir_ty, Variance::Invariant, ty)?; + self.eq(mir_ty, ty)?; // Prove the predicates coming along with `def_id`. // // Also, normalize the `instantiated_predicates` // because otherwise we wind up with duplicate "type // outlives" error messages. - let instantiated_predicates = - self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs); + let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs); let cause = ObligationCause::dummy_with_span(self.span); @@ -163,15 +139,14 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { } if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { - let impl_self_ty = self.tcx().type_of(impl_def_id); - let impl_self_ty = self.subst(impl_self_ty, &substs); + let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs); let impl_self_ty = self.normalize(impl_self_ty); - self.relate(self_ty, Variance::Invariant, impl_self_ty)?; + self.eq(self_ty, impl_self_ty)?; self.prove_predicate( ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into())) - .to_predicate(self.tcx()), + .to_predicate(tcx), cause.clone(), ); } @@ -188,7 +163,7 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { // type were ill-formed but did not appear in `ty`, // which...could happen with normalization... self.prove_predicate( - ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(tcx), cause, ); Ok(()) @@ -199,19 +174,14 @@ fn type_op_eq<'tcx>( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { - tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { + tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { let (param_env, Eq { a, b }) = key.into_parts(); - infcx - .at(&ObligationCause::dummy(), param_env) - .eq(a, b)? - .into_value_registering_obligations(infcx, fulfill_cx); - Ok(()) + Ok(ocx.eq(&ObligationCause::dummy(), param_env, a, b)?) }) } fn type_op_normalize<'tcx, T>( - infcx: &InferCtxt<'tcx>, - fulfill_cx: &mut dyn TraitEngine<'tcx>, + ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Normalize>, ) -> Fallible where @@ -219,8 +189,8 @@ where { let (param_env, Normalize { value }) = key.into_parts(); let Normalized { value, obligations } = - infcx.at(&ObligationCause::dummy(), param_env).normalize(value)?; - fulfill_cx.register_predicate_obligations(infcx, obligations); + ocx.infcx.at(&ObligationCause::dummy(), param_env).normalize(value)?; + ocx.register_obligations(obligations); Ok(value) } @@ -256,13 +226,9 @@ fn type_op_subtype<'tcx>( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { - tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { + tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { let (param_env, Subtype { sub, sup }) = key.into_parts(); - infcx - .at(&ObligationCause::dummy(), param_env) - .sup(sup, sub)? - .into_value_registering_obligations(infcx, fulfill_cx); - Ok(()) + Ok(ocx.sup(&ObligationCause::dummy(), param_env, sup, sub)?) }) } @@ -274,8 +240,8 @@ fn type_op_prove_predicate<'tcx>( // impl-trait/issue-99642.rs tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter_canonical_trait_query( &canonicalized, - |infcx, fulfill_cx, key| { - type_op_prove_predicate_with_cause(infcx, fulfill_cx, key, ObligationCause::dummy()); + |ocx, key| { + type_op_prove_predicate_with_cause(ocx, key, ObligationCause::dummy()); Ok(()) }, ) @@ -284,12 +250,11 @@ fn type_op_prove_predicate<'tcx>( /// The core of the `type_op_prove_predicate` query: for diagnostics purposes in NLL HRTB errors, /// this query can be re-run to better track the span of the obligation cause, and improve the error /// message. Do not call directly unless you're in that very specific context. -pub fn type_op_prove_predicate_with_cause<'a, 'tcx: 'a>( - infcx: &'a InferCtxt<'tcx>, - fulfill_cx: &'a mut dyn TraitEngine<'tcx>, +pub fn type_op_prove_predicate_with_cause<'tcx>( + ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, ProvePredicate<'tcx>>, cause: ObligationCause<'tcx>, ) { let (param_env, ProvePredicate { predicate }) = key.into_parts(); - fulfill_cx.register_predicate_obligation(infcx, Obligation::new(cause, param_env, predicate)); + ocx.register_obligation(Obligation::new(cause, param_env, predicate)); }