diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs b/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs index 4d685ec3c6810..5fbc87aed6340 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs @@ -779,8 +779,14 @@ fn field_tys_satisfy_relation_after_normalization_and_resolution<'tcx>( match relation { FieldRelation::Equal => { if infcx - .at(&cause, param_env) - .relate(DefineOpaqueTypes::Yes, source_ty, ty::Variance::Invariant, target_ty) + .relate( + &cause, + param_env, + DefineOpaqueTypes::Yes, + source_ty, + ty::Variance::Invariant, + target_ty, + ) .is_err() { return false; diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 496994096d69b..9f43e1b2656f9 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -371,11 +371,8 @@ fn orphan_check<'tcx>( for (arg, id_arg) in std::iter::zip(args, ty::GenericArgs::identity_for_item(tcx, impl_def_id)) { - let _ = infcx.at(&cause, ty::ParamEnv::empty()).eq( - DefineOpaqueTypes::No, - arg, - id_arg, - ); + let _ = + infcx.eq(&cause, ty::ParamEnv::empty(), DefineOpaqueTypes::No, arg, id_arg); } infcx.deeply_resolve_ignoring_regions(tys) }); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 025c64896edb7..5ff9b5134b00a 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -730,8 +730,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // adjustments search for mapped arguments. let cause = self.cause(call_expr.span, ObligationCauseCode::Misc); if self - .at(&cause, self.param_env) - .sup(DefineOpaqueTypes::Yes, formal_input_tys[0], adjusted_arg_type) + .sup( + &cause, + self.param_env, + DefineOpaqueTypes::Yes, + formal_input_tys[0], + adjusted_arg_type, + ) .is_err() { return do_check(); diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 02e6b8188a876..fc050669ca1b3 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -1091,8 +1091,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { // This is `fcx.demand_eqtype`, but inlined to give a better error. let cause = fcx.misc(self.span); if fcx - .at(&cause, fcx.param_env) - .eq(DefineOpaqueTypes::Yes, src_obj, dst_obj) + .eq(&cause, fcx.param_env, DefineOpaqueTypes::Yes, src_obj, dst_obj) .map(|infer_ok| fcx.register_infer_ok_obligations(infer_ok)) .is_err() { diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 79b4eff9153b0..3c5de55bcac89 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -798,7 +798,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { // Check that E' = S'. let cause = self.misc(hir_ty.span); - let InferOk { value: (), obligations } = self.at(&cause, self.param_env).eq( + let InferOk { value: (), obligations } = self.eq( + &cause, + self.param_env, DefineOpaqueTypes::Yes, *expected_ty, supplied_ty, @@ -808,7 +810,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let supplied_output_ty = supplied_sig.output(); let cause = &self.misc(decl.output.span()); - let InferOk { value: (), obligations } = self.at(cause, self.param_env).eq( + let InferOk { value: (), obligations } = self.eq( + cause, + self.param_env, DefineOpaqueTypes::Yes, expected_sigs.liberated_sig.output(), supplied_output_ty, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index af00194a95bf0..2c4a3dbf66955 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -165,12 +165,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { self.commit_if_ok(|snapshot| { let outer_universe = self.infcx.universe(); - let at = self.at(&self.cause, self.fcx.param_env); - let res = if self.use_lub { - at.lub(b, a) + self.lub(&self.cause, self.fcx.param_env, b, a) } else { - at.sup(DefineOpaqueTypes::Yes, b, a) + self.sup(&self.cause, self.fcx.param_env, DefineOpaqueTypes::Yes, b, a) .map(|InferOk { value: (), obligations }| InferOk { value: b, obligations }) }; @@ -1045,9 +1043,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { match b.kind() { ty::FnPtr(_, b_hdr) => { let a_sig = self.sig_for_fn_def_coercion(a, Some(b_hdr.safety()))?; - - let InferOk { value: a_sig, mut obligations } = - self.at(&self.cause, self.param_env).normalize(Unnormalized::new_wip(a_sig)); + let InferOk { value: a_sig, mut obligations } = NormalizeExt::normalize( + &self.infcx, + &self.cause, + self.param_env.clone(), + Unnormalized::new_wip(a_sig), + ); let a = Ty::new_fn_ptr(self.tcx, a_sig); let adjust = Adjust::Pointer(PointerCoercion::ReifyFnPointer(b_hdr.safety())); @@ -1372,7 +1373,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(TypeError::Mismatch) } } else { - self.at(cause, self.param_env).lub(prev_ty, new_ty) + self.lub(cause, self.param_env, prev_ty, new_ty) }; self.leak_check(outer_universe, Some(snapshot))?; @@ -1411,8 +1412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The signature must match. let (a_sig, b_sig) = self.normalize(new.span, Unnormalized::new_wip((a_sig, b_sig))); let sig = self - .at(cause, self.param_env) - .lub(a_sig, b_sig) + .lub(cause, self.param_env, a_sig, b_sig) .map(|ok| self.register_infer_ok_obligations(ok))?; // Reify both sides and return the reified fn pointer type. @@ -1726,17 +1726,18 @@ impl<'tcx> CoerceMany<'tcx> { // // Another example is `break` with no argument expression. assert!(expression_ty.is_unit(), "if let hack without unit type"); - fcx.at(cause, fcx.param_env) - .eq( - // needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs - DefineOpaqueTypes::Yes, - expected, - found, - ) - .map(|infer_ok| { - fcx.register_infer_ok_obligations(infer_ok); - expression_ty - }) + fcx.eq( + // needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs + cause, + fcx.param_env, + DefineOpaqueTypes::Yes, + expected, + found, + ) + .map(|infer_ok| { + fcx.register_infer_ok_obligations(infer_ok); + expression_ty + }) }; debug!(?result); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index e1ad43f0c00c9..1922734a5304f 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -190,8 +190,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, ) -> Result<(), Diag<'a>> { - self.at(cause, self.param_env) - .sup(DefineOpaqueTypes::Yes, expected, actual) + self.sup(cause, self.param_env, DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) .map_err(|e| { self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e) @@ -219,8 +218,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, ) -> Result<(), Diag<'a>> { - self.at(cause, self.param_env) - .eq(DefineOpaqueTypes::Yes, expected, actual) + self.eq(cause, self.param_env, DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) .map_err(|e| { self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e) @@ -416,8 +414,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; let _ = self - .at(&ObligationCause::dummy(), self.param_env) - .eq(DefineOpaqueTypes::Yes, *input_arg, arg_ty) + .eq( + &ObligationCause::dummy(), + self.param_env, + DefineOpaqueTypes::Yes, + *input_arg, + arg_ty, + ) .ok()?; self.select_obligations_where_possible(|errs| { // Yeet the errors, we're already reporting errors. @@ -498,8 +501,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .ok() .and_then(|method| { let _ = self - .at(&ObligationCause::dummy(), self.param_env) - .eq(DefineOpaqueTypes::Yes, ideal_rcvr_ty, expected_ty) + .eq( + &ObligationCause::dummy(), + self.param_env, + DefineOpaqueTypes::Yes, + ideal_rcvr_ty, + expected_ty, + ) .ok()?; Some(method) }); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index dbe5a51b25b45..b3f20c873cc42 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2101,11 +2101,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(_) = remaining_fields.remove(&ident) { let target_ty = self.field_ty(base_expr.span, f, args); let cause = self.misc(base_expr.span); - match self.at(&cause, self.param_env).sup( + match self.sup( // We're already using inference variables for any params, // and don't allow converting between different structs, // so there is no way this ever actually defines an opaque // type. Thus choosing `Yes` is fine. + &cause, + self.param_env, DefineOpaqueTypes::Yes, target_ty, fru_ty, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 1ad6225a8c467..ef316652a5aa5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -465,9 +465,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { where T: TypeFoldable>, { - self.register_infer_ok_obligations( - self.at(&self.misc(span), self.param_env).normalize(value), - ) + self.register_infer_ok_obligations(self.infcx.normalize( + &self.misc(span), + self.param_env, + value, + )) } pub(crate) fn require_type_meets( @@ -1447,7 +1449,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This also occurs for an enum variant on a type alias. let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args)); let self_ty = self.normalize(span, Unnormalized::new_wip(self_ty)); - match self.at(&self.misc(span), self.param_env).eq( + match self.eq( + &self.misc(span), + self.param_env, DefineOpaqueTypes::Yes, impl_ty, self_ty, @@ -1520,9 +1524,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We need to use a separate variable here as otherwise the temporary for // `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting // in a reentrant borrow, causing an ICE. - let result = self.at(&self.misc(sp), self.param_env).structurally_normalize_const( + let result = self.structurally_normalize_const( Unnormalized::new_wip(ct), &mut *self.fulfillment_cx.borrow_mut(), + self.param_env, + &self.misc(sp), ); match result { Ok(normalized_ct) => normalized_ct, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 937182c2030da..71b0249012bad 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -396,7 +396,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 3. Check if the formal type is actually equal to the checked one // and register any such obligations for future type checks. - let formal_ty_error = self.at(&self.misc(provided_arg.span), self.param_env).eq( + let formal_ty_error = self.eq( + &self.misc(provided_arg.span), + self.param_env, DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty, @@ -3223,9 +3225,14 @@ impl<'a, 'tcx> ArgMatchingCtxt<'a, 'tcx> { // Using probe here, since we don't want this subtyping to affect inference. let subtyping_error = self.probe(|_| { - self.at(&self.misc(arg_span), self.param_env) - .sup(DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty) - .err() + self.sup( + &self.misc(arg_span), + self.param_env, + DefineOpaqueTypes::Yes, + formal_input_ty, + coerced_ty, + ) + .err() }); // Same as above: if either the coerce type or the checked type is an error type, diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 4518e419aea0f..6097d4de5079a 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -560,7 +560,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self_ty, method_self_ty, self.span, pick ); let cause = self.cause(self.self_expr.span, ObligationCauseCode::Misc); - match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::Yes, method_self_ty, self_ty) { + match self.sup(&cause, self.param_env, DefineOpaqueTypes::Yes, method_self_ty, self_ty) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 16127b7d87f3d..7059f8afb29ae 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -427,8 +427,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_sig, ); - let InferOk { value: fn_sig, obligations: o } = - self.at(&obligation.cause, self.param_env).normalize(Unnormalized::new_wip(fn_sig)); + let InferOk { value: fn_sig, obligations: o } = NormalizeExt::normalize( + &self.infcx, + &obligation.cause, + self.param_env, + Unnormalized::new_wip(fn_sig), + ); obligations.extend(o); // Register obligations for the parameters. This will include the @@ -447,7 +451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { move |_, _| predicates_cause.clone(), |clause| { let InferOk { value: pred, obligations: o } = - self.at(&obligation.cause, self.param_env).normalize(clause); + NormalizeExt::normalize(&self.infcx, &obligation.cause, self.param_env, clause); normalization_obligations.extend(o); assert!(!pred.has_escaping_bound_vars()); pred diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index aee246a61fb1e..2328949f58ed4 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1971,7 +1971,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.xform_self_ty(candidate.item, trait_ref.self_ty(), trait_ref.args); // Guide the trait selection to show impls that have methods whose type matches // up with the `self` parameter of the method. - let _ = self.at(&ObligationCause::dummy(), self.param_env).sup( + let _ = self.sup( + &ObligationCause::dummy(), + self.param_env, DefineOpaqueTypes::Yes, xform_self_ty, self_ty, diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index c96144d849944..6bc5b6c7bb696 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -246,8 +246,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> { } let cause = ObligationCause::misc(hidden_type.span, self.body_def_id); - let at = self.at(&cause, self.param_env); - let hidden_type = match solve::deeply_normalize(at, Unnormalized::new_wip(hidden_type)) { + let hidden_type = match solve::deeply_normalize( + &self.infcx, + Unnormalized::new_wip(hidden_type), + self.param_env, + &cause, + ) { Ok(hidden_type) => hidden_type, Err(errors) => { let guar = self.err_ctxt().report_fulfillment_errors(errors); diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 923c0d49936c8..ba66020aec777 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -968,12 +968,13 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { let mut value = if self.should_normalize && self.fcx.next_trait_solver() { let body_def_id = tcx.hir_body_owner_def_id(self.body.id()); let cause = ObligationCause::misc(self.span.to_span(tcx), body_def_id); - let at = self.fcx.at(&cause, self.fcx.param_env); let universes = vec![None; outer_exclusive_binder(&value).as_usize()]; match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( - at, + &self.fcx.infcx, Unnormalized::new_wip(value), universes, + self.fcx.param_env, + &cause, ) { Ok((value, goals)) => { self.nested_goals.extend(goals); diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 341ea9a70dbc7..30b9fe19b774b 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -46,23 +46,7 @@ pub enum DefineOpaqueTypes { No, } -#[derive(Clone, Copy)] -pub struct At<'a, 'tcx> { - pub infcx: &'a InferCtxt<'tcx>, - pub cause: &'a ObligationCause<'tcx>, - pub param_env: ty::ParamEnv<'tcx>, -} - impl<'tcx> InferCtxt<'tcx> { - #[inline] - pub fn at<'a>( - &'a self, - cause: &'a ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> At<'a, 'tcx> { - At { infcx: self, cause, param_env } - } - /// Forks the inference context, creating a new inference context with the same inference /// variables in the same state. This can be used to "branch off" many tests from the same /// common state. @@ -122,19 +106,11 @@ impl<'tcx> InferCtxt<'tcx> { forked.inner.borrow_mut().projection_cache().clear(); forked } -} - -pub trait ToTrace<'tcx>: Relate> + Copy { - fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>; -} -impl<'a, 'tcx> At<'a, 'tcx> { - /// Makes `actual <: expected`. For example, if type-checking a - /// call like `foo(x)`, where `foo: fn(i32)`, you might have - /// `sup(i32, x)`, since the "expected" type is the type that - /// appears in the signature. pub fn sup( - self, + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, define_opaque_types: DefineOpaqueTypes, expected: T, actual: T, @@ -142,21 +118,21 @@ impl<'a, 'tcx> At<'a, 'tcx> { where T: ToTrace<'tcx>, { - if self.infcx.next_trait_solver { + if self.next_trait_solver { NextSolverRelate::relate( - self.infcx, - self.param_env, + self, + param_env, expected, ty::Contravariant, actual, - self.cause.span, + cause.span, ) - .map(|goals| self.goals_to_obligations(goals)) + .map(|goals| self.goals_to_obligations_at(cause, goals)) } else { let mut op = TypeRelating::new( - self.infcx, - ToTrace::to_trace(self.cause, expected, actual), - self.param_env, + &self, + ToTrace::to_trace(cause, expected, actual), + param_env, define_opaque_types, ty::Contravariant, ); @@ -167,7 +143,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// Makes `expected <: actual`. pub fn sub( - self, + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, define_opaque_types: DefineOpaqueTypes, expected: T, actual: T, @@ -175,21 +153,14 @@ impl<'a, 'tcx> At<'a, 'tcx> { where T: ToTrace<'tcx>, { - if self.infcx.next_trait_solver { - NextSolverRelate::relate( - self.infcx, - self.param_env, - expected, - ty::Covariant, - actual, - self.cause.span, - ) - .map(|goals| self.goals_to_obligations(goals)) + if self.next_trait_solver { + NextSolverRelate::relate(self, param_env, expected, ty::Covariant, actual, cause.span) + .map(|goals| self.goals_to_obligations_at(cause, goals)) } else { let mut op = TypeRelating::new( - self.infcx, - ToTrace::to_trace(self.cause, expected, actual), - self.param_env, + &self, + ToTrace::to_trace(cause, expected, actual), + param_env, define_opaque_types, ty::Covariant, ); @@ -198,9 +169,10 @@ impl<'a, 'tcx> At<'a, 'tcx> { } } - /// Makes `expected == actual`. pub fn eq( - self, + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, define_opaque_types: DefineOpaqueTypes, expected: T, actual: T, @@ -209,16 +181,19 @@ impl<'a, 'tcx> At<'a, 'tcx> { T: ToTrace<'tcx>, { self.eq_trace( + cause, + param_env, define_opaque_types, - ToTrace::to_trace(self.cause, expected, actual), + ToTrace::to_trace(cause, expected, actual), expected, actual, ) } - /// Makes `expected == actual`. pub fn eq_trace( - self, + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, define_opaque_types: DefineOpaqueTypes, trace: TypeTrace<'tcx>, expected: T, @@ -227,31 +202,21 @@ impl<'a, 'tcx> At<'a, 'tcx> { where T: Relate>, { - if self.infcx.next_trait_solver { - NextSolverRelate::relate( - self.infcx, - self.param_env, - expected, - ty::Invariant, - actual, - self.cause.span, - ) - .map(|goals| self.goals_to_obligations(goals)) + if self.next_trait_solver { + NextSolverRelate::relate(self, param_env, expected, ty::Invariant, actual, cause.span) + .map(|goals| self.goals_to_obligations_at(cause, goals)) } else { - let mut op = TypeRelating::new( - self.infcx, - trace, - self.param_env, - define_opaque_types, - ty::Invariant, - ); + let mut op = + TypeRelating::new(&self, trace, param_env, define_opaque_types, ty::Invariant); op.relate(expected, actual)?; Ok(InferOk { value: (), obligations: op.into_obligations() }) } } pub fn relate( - self, + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, define_opaque_types: DefineOpaqueTypes, expected: T, variance: ty::Variance, @@ -261,15 +226,15 @@ impl<'a, 'tcx> At<'a, 'tcx> { T: ToTrace<'tcx>, { match variance { - ty::Covariant => self.sub(define_opaque_types, expected, actual), - ty::Invariant => self.eq(define_opaque_types, expected, actual), - ty::Contravariant => self.sup(define_opaque_types, expected, actual), + ty::Covariant => self.sub(cause, param_env, define_opaque_types, expected, actual), + ty::Invariant => self.eq(cause, param_env, define_opaque_types, expected, actual), + ty::Contravariant => self.sup(cause, param_env, define_opaque_types, expected, actual), // We could make this make sense but it's not readily // exposed and I don't feel like dealing with it. Note // that bivariance in general does a bit more than just // *nothing*, it checks that the types are the same - // "modulo variance" basically. + // "modulo variance" basically. - Niko ty::Bivariant => panic!("Bivariant given to `relate()`"), } } @@ -279,22 +244,29 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// this can result in an error (e.g., if asked to compute LUB of /// u32 and i32), it is meaningful to call one of them the /// "expected type". - pub fn lub(self, expected: T, actual: T) -> InferResult<'tcx, T> + pub fn lub( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + expected: T, + actual: T, + ) -> InferResult<'tcx, T> where T: ToTrace<'tcx>, { let mut op = LatticeOp::new( - self.infcx, - ToTrace::to_trace(self.cause, expected, actual), - self.param_env, + &self, + ToTrace::to_trace(cause, expected, actual), + param_env, LatticeOpKind::Lub, ); let value = op.relate(expected, actual)?; Ok(InferOk { value, obligations: op.into_obligations() }) } - fn goals_to_obligations( + fn goals_to_obligations_at( &self, + cause: &ObligationCause<'tcx>, goals: Vec>>, ) -> InferOk<'tcx, ()> { InferOk { @@ -302,18 +274,17 @@ impl<'a, 'tcx> At<'a, 'tcx> { obligations: goals .into_iter() .map(|goal| { - Obligation::new( - self.infcx.tcx, - self.cause.clone(), - goal.param_env, - goal.predicate, - ) + Obligation::new(self.tcx, cause.clone(), goal.param_env, goal.predicate) }) .collect(), } } } +pub trait ToTrace<'tcx>: Relate> + Copy { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>; +} + impl<'tcx> ToTrace<'tcx> for Ty<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 3a245a5b25759..9070d5e91f20c 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -305,16 +305,14 @@ impl<'tcx> InferCtxt<'tcx> { (GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => { obligations.extend( - self.at(&cause, param_env) - .eq(DefineOpaqueTypes::Yes, v1, v2)? + self.eq(cause, param_env, DefineOpaqueTypes::Yes, v1, v2)? .into_obligations(), ); } (GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => { obligations.extend( - self.at(&cause, param_env) - .eq(DefineOpaqueTypes::Yes, v1, v2)? + self.eq(cause, param_env, DefineOpaqueTypes::Yes, v1, v2)? .into_obligations(), ); } @@ -523,13 +521,14 @@ impl<'tcx> InferCtxt<'tcx> { // variable that got constrained to the opaque type itself. In that case we want to equate // the generic args of the opaque with the generic params of its hidden type version. obligations.extend( - self.at(cause, param_env) - .eq( - DefineOpaqueTypes::Yes, - Ty::new_opaque(self.tcx, ty::IsRigid::No, a.def_id.to_def_id(), a.args), - b, - )? - .obligations, + self.eq( + cause, + param_env, + DefineOpaqueTypes::Yes, + Ty::new_opaque(self.tcx, ty::IsRigid::No, a.def_id.to_def_id(), a.args), + b, + )? + .obligations, ); } @@ -582,8 +581,7 @@ impl<'tcx> InferCtxt<'tcx> { match (value1.kind(), value2.kind()) { (GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => { obligations.extend( - self.at(cause, param_env) - .eq(DefineOpaqueTypes::Yes, v1, v2)? + self.eq(cause, param_env, DefineOpaqueTypes::Yes, v1, v2)? .into_obligations(), ); } @@ -601,7 +599,7 @@ impl<'tcx> InferCtxt<'tcx> { ); } (GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => { - let ok = self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, v1, v2)?; + let ok = self.eq(cause, param_env, DefineOpaqueTypes::Yes, v1, v2)?; obligations.extend(ok.into_obligations()); } _ => { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e02cc9a7acd1f..27a0736c9d6e9 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -881,9 +881,9 @@ impl<'tcx> InferCtxt<'tcx> { self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| { if a_is_expected { - Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b)) + Ok(self.sub(cause, param_env, DefineOpaqueTypes::Yes, a, b)) } else { - Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a)) + Ok(self.sup(cause, param_env, DefineOpaqueTypes::Yes, b, a)) } }) } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 3cca843157b8f..5a17b1668747b 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -245,11 +245,16 @@ impl<'tcx> InferCtxt<'tcx> { .register(opaque_type_key, ProvisionalHiddenType { ty: hidden_ty, span }); if let Some(prev) = prev { goals.extend( - self.at(&ObligationCause::dummy_with_span(span), param_env) - .eq(DefineOpaqueTypes::Yes, prev, hidden_ty)? - .obligations - .into_iter() - .map(|obligation| obligation.as_goal()), + self.eq( + &ObligationCause::dummy_with_span(span), + param_env, + DefineOpaqueTypes::Yes, + prev, + hidden_ty, + )? + .obligations + .into_iter() + .map(|obligation| obligation.as_goal()), ); } } @@ -275,11 +280,16 @@ impl<'tcx> InferCtxt<'tcx> { }); goals.extend( - self.at(&ObligationCause::dummy_with_span(span), param_env) - .eq(DefineOpaqueTypes::Yes, hidden_ty, actual)? - .obligations - .into_iter() - .map(|obligation| obligation.as_goal()), + self.eq( + &ObligationCause::dummy_with_span(span), + param_env, + DefineOpaqueTypes::Yes, + hidden_ty, + actual, + )? + .obligations + .into_iter() + .map(|obligation| obligation.as_goal()), ); } mode @ (ty::TypingMode::PostBorrowck { .. } diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 648bccbb618bc..c0742a88d8a9f 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -99,8 +99,14 @@ impl<'tcx> TypeRelation> for LatticeOp<'_, 'tcx> { ty::Invariant => { self.obligations.extend( self.infcx - .at(&self.trace.cause, self.param_env) - .eq_trace(DefineOpaqueTypes::Yes, self.trace.clone(), a, b)? + .eq_trace( + &self.trace.cause, + self.param_env, + DefineOpaqueTypes::Yes, + self.trace.clone(), + a, + b, + )? .into_obligations(), ); Ok(a) @@ -255,15 +261,30 @@ impl<'infcx, 'tcx> LatticeOp<'infcx, 'tcx> { // relates `v` to `a` first, which may help us to avoid unnecessary // type variable obligations. See caller for details. fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { - let at = self.infcx.at(&self.trace.cause, self.param_env); match self.kind { LatticeOpKind::Glb => { - self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, v, a)?.into_obligations()); - self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, v, b)?.into_obligations()); + self.obligations.extend( + self.infcx + .sub(&self.trace.cause, self.param_env, DefineOpaqueTypes::Yes, v, a)? + .into_obligations(), + ); + self.obligations.extend( + self.infcx + .sub(&self.trace.cause, self.param_env, DefineOpaqueTypes::Yes, v, b)? + .into_obligations(), + ); } LatticeOpKind::Lub => { - self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, a, v)?.into_obligations()); - self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, b, v)?.into_obligations()); + self.obligations.extend( + self.infcx + .sub(&self.trace.cause, self.param_env, DefineOpaqueTypes::Yes, a, v)? + .into_obligations(), + ); + self.obligations.extend( + self.infcx + .sub(&self.trace.cause, self.param_env, DefineOpaqueTypes::Yes, b, v)? + .into_obligations(), + ); } } Ok(()) diff --git a/compiler/rustc_lint/src/runtime_symbols.rs b/compiler/rustc_lint/src/runtime_symbols.rs index f0e186c34ca0f..0c29f9acd8d57 100644 --- a/compiler/rustc_lint/src/runtime_symbols.rs +++ b/compiler/rustc_lint/src/runtime_symbols.rs @@ -220,7 +220,7 @@ fn check<'tcx>( // Compare the two signatures with an inference context let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); let cause = rustc_middle::traits::ObligationCause::misc(sp, did); - let result = infcx.at(&cause, cx.param_env).eq(DefineOpaqueTypes::No, lang_sig, user_sig); + let result = infcx.eq(&cause, cx.param_env, DefineOpaqueTypes::No, lang_sig, user_sig); // If they don't match, emit our own mismatch signatures if result.is_err() { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index d83df2dfdf291..e84dbc74c4ff6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -277,7 +277,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let expected_trait_ref = alias.trait_ref(tcx); - if let Err(_) = self.infcx.at(&ObligationCause::dummy(), param_env).eq( + if let Err(_) = self.infcx.eq( + &ObligationCause::dummy(), + param_env, DefineOpaqueTypes::No, expected_trait_ref, impl_trait_ref, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index ed0ecf459c3b8..5a346351eae95 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -3048,10 +3048,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let cleaned_pred = pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); - let InferOk { value: cleaned_pred, .. } = self - .infcx - .at(&ObligationCause::dummy(), param_env) - .normalize(Unnormalized::new_wip(cleaned_pred)); + let InferOk { value: cleaned_pred, .. } = self.infcx.normalize( + &ObligationCause::dummy(), + param_env, + Unnormalized::new_wip(cleaned_pred), + ); let obligation = Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 47d2b7a8c98d5..465b613a62bc6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1617,7 +1617,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // implied by wf, but also because that would possibly result in // erroneous errors later on. let InferOk { value: output, obligations: _ } = - self.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(output)); + self.normalize(&ObligationCause::dummy(), param_env, Unnormalized::new_wip(output)); if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) } } @@ -5033,9 +5033,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { [trait_pred.self_ty()], ) }); - let InferOk { value: projection_ty, .. } = self - .at(&obligation.cause, obligation.param_env) - .normalize(Unnormalized::new_wip(projection_ty)); + let InferOk { value: projection_ty, .. } = self.normalize( + &obligation.cause, + obligation.param_env, + Unnormalized::new_wip(projection_ty), + ); debug!( normalized_projection_type = ?self.deeply_resolve_ignoring_regions(projection_ty) @@ -5390,11 +5392,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { for (expected, actual) in zipped { self.probe(|_| { match self - .at(&ObligationCause::misc(expr.span, body_def_id), param_env) // Doesn't actually matter if we define opaque types here, this is just used for // diagnostics, and the result is never kept around. - .eq(DefineOpaqueTypes::Yes, expected, actual) - { + .eq( + &ObligationCause::misc(expr.span, body_def_id), + param_env, + DefineOpaqueTypes::Yes, + expected, + actual, + ) { Ok(_) => (), // We ignore nested obligations here for now. Err(err) => type_diffs.push(err), } @@ -5520,7 +5526,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Extract `::Target` assoc type and check that it is `T` && let Some(deref_target_did) = tcx.lang_items().deref_target() && let projection = Ty::new_projection_from_args(tcx,ty::IsRigid::No, deref_target_did, tcx.mk_args(&[ty::GenericArg::from(found_ty)])) - && let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(projection)) + && let InferOk { value: deref_target, obligations } = infcx.normalize(&ObligationCause::dummy(), param_env, Unnormalized::new_wip(projection)) && obligations.iter().all(|obligation| infcx.predicate_must_hold_modulo_regions(obligation)) && infcx.can_eq(param_env, deref_target, target_ty) { diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index f54d774e32670..7cbb312d35fc8 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -99,8 +99,10 @@ pub fn ty_known_to_outlive<'tcx>( // Types in region obligations should be normalized. let ty = if infcx.next_trait_solver() { let Ok(ty) = crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>( - infcx.at(&ObligationCause::dummy_with_span(DUMMY_SP), param_env), + infcx, ty, + param_env, + &ObligationCause::dummy_with_span(DUMMY_SP), ) else { return Err(()); }; diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 9430b6c4b3307..3455ea0211feb 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -1,5 +1,4 @@ use rustc_infer::infer::InferCtxt; -use rustc_infer::infer::at::At; use rustc_infer::traits::solve::Goal; use rustc_infer::traits::{ FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine, TraitErrors, @@ -18,11 +17,16 @@ use crate::solve::{Certainty, SolverDelegate}; use crate::traits::{BoundVarReplacer, ScrubbedTraitError}; /// see `normalize_with_universes`. -pub fn normalize<'tcx, T>(at: At<'_, 'tcx>, value: Unnormalized<'tcx, T>) -> Normalized<'tcx, T> +pub fn normalize<'tcx, T>( + infcx: &InferCtxt<'tcx>, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + value: Unnormalized<'tcx, T>, +) -> Normalized<'tcx, T> where T: TypeFoldable>, { - normalize_with_universes(at, value, vec![]) + normalize_with_universes(infcx, value, vec![], param_env, cause) } /// Like `deeply_normalize`, but we handle ambiguity and inference variables in this routine. @@ -33,14 +37,15 @@ where /// - otherwise: return the normalized result. It can be (partially) inferred /// even if the evaluation result is ambiguous. fn normalize_with_universes<'tcx, T>( - at: At<'_, 'tcx>, + infcx: &InferCtxt<'tcx>, value: Unnormalized<'tcx, T>, universes: Vec>, + param_env: ty::ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Normalized<'tcx, T> where T: TypeFoldable>, { - let infcx = at.infcx; let value = value.skip_normalization(); let value = infcx.deeply_resolve_ignoring_regions(value); @@ -52,10 +57,10 @@ where let mut stalled_goals = vec![]; let mut folder = NormalizationFolder::new(infcx, universes.clone(), |alias_term| { let delegate = <&SolverDelegate<'tcx>>::from(infcx); - let infer_term = delegate.next_term_var_of_alias_kind(alias_term, at.cause.span); + let infer_term = delegate.next_term_var_of_alias_kind(alias_term, cause.span); let predicate = ty::ProjectionClause { projection_term: alias_term, term: infer_term }; - let goal = Goal::new(infcx.tcx, at.param_env, predicate); - let result = match delegate.evaluate_root_goal(goal, at.cause.span, None) { + let goal = Goal::new(infcx.tcx, param_env, predicate); + let result = match delegate.evaluate_root_goal(goal, cause.span, None) { Ok(result) => result, Err(err) => return Err(err), }; @@ -72,32 +77,38 @@ where if let Ok(value) = value.try_fold_with(&mut folder) { let obligations = stalled_goals .into_iter() - .map(|goal| { - Obligation::new(infcx.tcx, at.cause.clone(), goal.param_env, goal.predicate) - }) + .map(|goal| Obligation::new(infcx.tcx, cause.clone(), goal.param_env, goal.predicate)) .collect(); Normalized { value, obligations } } else { - let mut replacer = ReplaceAliasWithInfer { at, obligations: Default::default(), universes }; + let mut replacer = ReplaceAliasWithInfer { + infcx, + obligations: Default::default(), + universes, + param_env, + cause, + }; let value = original_value.fold_with(&mut replacer); Normalized { value, obligations: replacer.obligations } } } struct ReplaceAliasWithInfer<'me, 'tcx> { - at: At<'me, 'tcx>, + infcx: &'me InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + cause: &'me ObligationCause<'tcx>, obligations: PredicateObligations<'tcx>, universes: Vec>, } impl<'me, 'tcx> ReplaceAliasWithInfer<'me, 'tcx> { fn term_to_infer(&mut self, alias_term: ty::AliasTerm<'tcx>) -> ty::Term<'tcx> { - let infcx = self.at.infcx; - let infer_term = infcx.next_term_var_of_alias_kind(alias_term, self.at.cause.span); + let infcx = self.infcx; + let infer_term = infcx.next_term_var_of_alias_kind(alias_term, self.cause.span); let obligation = Obligation::new( infcx.tcx, - self.at.cause.clone(), - self.at.param_env, + self.cause.clone(), + self.param_env, ty::ProjectionClause { projection_term: alias_term, term: infer_term }, ); self.obligations.push(obligation); @@ -107,7 +118,7 @@ impl<'me, 'tcx> ReplaceAliasWithInfer<'me, 'tcx> { impl<'me, 'tcx> TypeFolder> for ReplaceAliasWithInfer<'me, 'tcx> { fn cx(&self) -> TyCtxt<'tcx> { - self.at.infcx.tcx + self.infcx.tcx } fn fold_binder>>( @@ -133,7 +144,7 @@ impl<'me, 'tcx> TypeFolder> for ReplaceAliasWithInfer<'me, 'tcx> { if ty.has_escaping_bound_vars() { let (replaced, ..) = - BoundVarReplacer::replace_bound_vars(self.at.infcx, &mut self.universes, alias); + BoundVarReplacer::replace_bound_vars(self.infcx, &mut self.universes, alias); let _ = self.term_to_infer(replaced.into()); ty } else { @@ -153,11 +164,8 @@ impl<'me, 'tcx> TypeFolder> for ReplaceAliasWithInfer<'me, 'tcx> { } if ct.has_escaping_bound_vars() { - let (replaced, ..) = BoundVarReplacer::replace_bound_vars( - self.at.infcx, - &mut self.universes, - alias_const, - ); + let (replaced, ..) = + BoundVarReplacer::replace_bound_vars(self.infcx, &mut self.universes, alias_const); let _ = self.term_to_infer(replaced.into()); ct } else { @@ -169,15 +177,17 @@ impl<'me, 'tcx> TypeFolder> for ReplaceAliasWithInfer<'me, 'tcx> { /// Deeply normalize all aliases in `value`. This does not handle inference and expects /// its input to be already fully resolved. pub fn deeply_normalize<'tcx, T, E>( - at: At<'_, 'tcx>, + infcx: &InferCtxt<'tcx>, value: Unnormalized<'tcx, T>, + param_env: ty::ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Result> where T: TypeFoldable>, E: FromSolverError<'tcx, NextSolverError<'tcx>>, { assert!(!value.as_ref().skip_normalization().has_escaping_bound_vars()); - deeply_normalize_with_skipped_universes(at, value, vec![]) + deeply_normalize_with_skipped_universes(infcx, value, vec![], param_env, cause) } /// Deeply normalize all aliases in `value`. This does not handle inference and expects @@ -187,9 +197,11 @@ where /// entered before passing `value` to the function. This is currently needed for /// `normalize_erasing_regions`, which skips binders as it walks through a type. pub fn deeply_normalize_with_skipped_universes<'tcx, T, E>( - at: At<'_, 'tcx>, + infcx: &InferCtxt<'tcx>, value: Unnormalized<'tcx, T>, universes: Vec>, + param_env: ty::ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Result> where T: TypeFoldable>, @@ -197,7 +209,7 @@ where { let (value, coroutine_goals) = deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( - at, value, universes, + infcx, value, universes, param_env, cause, )?; assert_eq!(coroutine_goals, vec![]); @@ -214,33 +226,36 @@ where /// This returns a set of stalled obligations involving coroutines if the typing mode of /// the underlying infcx has any stalled coroutine def ids. pub fn deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals<'tcx, T, E>( - at: At<'_, 'tcx>, + infcx: &InferCtxt<'tcx>, value: Unnormalized<'tcx, T>, universes: Vec>, + param_env: ty::ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Result<(T, Vec>>), ThinVec> where T: TypeFoldable>, E: FromSolverError<'tcx, NextSolverError<'tcx>>, { - let Normalized { value, obligations } = normalize_with_universes(at, value, universes); + let Normalized { value, obligations } = + normalize_with_universes(infcx, value, universes, param_env, cause); - let mut fulfill_cx = FulfillmentCtxt::new(at.infcx); + let mut fulfill_cx = FulfillmentCtxt::new(infcx); for pred in obligations { - fulfill_cx.register_predicate_obligation(at.infcx, pred); + fulfill_cx.register_predicate_obligation(infcx, pred); } - let errors = fulfill_cx.try_evaluate_obligations(at.infcx); + let errors = fulfill_cx.try_evaluate_obligations(infcx); if let TraitErrors::HasErrors(errors) = errors { return Err(errors); } let stalled_coroutine_goals = fulfill_cx - .drain_stalled_obligations_for_coroutines(at.infcx) + .drain_stalled_obligations_for_coroutines(infcx) .into_iter() .map(|obl| obl.as_goal()) .collect(); - let errors = fulfill_cx.collect_remaining_errors(at.infcx); + let errors = fulfill_cx.collect_remaining_errors(infcx); if let TraitErrors::HasErrors(errors) = errors { return Err(errors); } @@ -255,26 +270,37 @@ pub(crate) fn deeply_normalize_for_diagnostics<'tcx, T: TypeFoldable T { t.fold_with(&mut DeeplyNormalizeForDiagnosticsFolder { - at: infcx.at(&ObligationCause::dummy(), param_env), + infcx, + cause: &ObligationCause::dummy(), + param_env, }) } +/// A type folder struct. +/// +/// This is isomorphic to what was previously called `At`. This should remain +/// specific to its use as a TypeFolder, and not expanded back into another +/// "God Object." struct DeeplyNormalizeForDiagnosticsFolder<'a, 'tcx> { - at: At<'a, 'tcx>, + pub infcx: &'a InferCtxt<'tcx>, + pub cause: &'a ObligationCause<'tcx>, + pub param_env: ty::ParamEnv<'tcx>, } impl<'tcx> TypeFolder> for DeeplyNormalizeForDiagnosticsFolder<'_, 'tcx> { fn cx(&self) -> TyCtxt<'tcx> { - self.at.infcx.tcx + self.infcx.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - let infcx = self.at.infcx; + let infcx = self.infcx; let result: Result<_, ThinVec>> = infcx.commit_if_ok(|_| { deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( - self.at, + self.infcx, Unnormalized::new_wip(ty), vec![None; ty.outer_exclusive_binder().as_usize()], + self.param_env, + self.cause, ) }); match result { @@ -284,12 +310,14 @@ impl<'tcx> TypeFolder> for DeeplyNormalizeForDiagnosticsFolder<'_, } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - let infcx = self.at.infcx; + let infcx = self.infcx; let result: Result<_, ThinVec>> = infcx.commit_if_ok(|_| { deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( - self.at, + self.infcx, Unnormalized::new_wip(ct), vec![None; ct.outer_exclusive_binder().as_usize()], + self.param_env, + self.cause, ) }); match result { diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 71dee3de72cb8..683c16a8b6249 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -872,7 +872,9 @@ impl<'tcx> AutoTraitFinder<'tcx> { match (evaluate(c1), evaluate(c2)) { (Ok(c1), Ok(c2)) => { - match selcx.infcx.at(&obligation.cause, obligation.param_env).eq( + match selcx.infcx.eq( + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, c1, c2, diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index d3c118b33e8ce..b5059552f0bc3 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -226,7 +226,7 @@ fn fresh_impl_header_normalized<'tcx>( let header = fresh_impl_header(infcx, impl_def_id, is_of_trait); let InferOk { value: mut header, obligations } = - infcx.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(header)); + infcx.normalize(&ObligationCause::dummy(), param_env, Unnormalized::new_wip(header)); header.predicates.extend(obligations.into_iter().map(|o| o.predicate)); header @@ -354,18 +354,23 @@ fn equate_impl_headers<'tcx>( impl1: &ImplHeader<'tcx>, impl2: &ImplHeader<'tcx>, ) -> Option> { - let result = - match (impl1.trait_ref, impl2.trait_ref) { - (Some(impl1_ref), Some(impl2_ref)) => infcx - .at(&ObligationCause::dummy(), param_env) - .eq(DefineOpaqueTypes::Yes, impl1_ref, impl2_ref), - (None, None) => infcx.at(&ObligationCause::dummy(), param_env).eq( - DefineOpaqueTypes::Yes, - impl1.self_ty, - impl2.self_ty, - ), - _ => bug!("equate_impl_headers given mismatched impl kinds"), - }; + let result = match (impl1.trait_ref, impl2.trait_ref) { + (Some(impl1_ref), Some(impl2_ref)) => infcx.eq( + &ObligationCause::dummy(), + param_env, + DefineOpaqueTypes::Yes, + impl1_ref, + impl2_ref, + ), + (None, None) => infcx.eq( + &ObligationCause::dummy(), + param_env, + DefineOpaqueTypes::Yes, + impl1.self_ty, + impl2.self_ty, + ), + _ => bug!("equate_impl_headers given mismatched impl kinds"), + }; result.map(|infer_ok| infer_ok.obligations).ok() } @@ -582,20 +587,20 @@ fn plug_infer_with_placeholders<'tcx>( fn visit_ty(&mut self, ty: Ty<'tcx>) { let ty = self.infcx.shallow_resolve(ty); if ty.is_ty_var() { - let Ok(InferOk { value: (), obligations }) = - self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( - // Comparing against a type variable never registers hidden types anyway - DefineOpaqueTypes::Yes, - ty, - Ty::new_placeholder( - self.infcx.tcx, - ty::PlaceholderType::new( - self.universe, - ty::BoundTy { var: self.next_var(), kind: ty::BoundTyKind::Anon }, - ), + let Ok(InferOk { value: (), obligations }) = self.infcx.eq( + // Comparing against a type variable never registers hidden types anyway + &ObligationCause::dummy(), + ty::ParamEnv::empty(), + DefineOpaqueTypes::Yes, + ty, + Ty::new_placeholder( + self.infcx.tcx, + ty::PlaceholderType::new( + self.universe, + ty::BoundTy { var: self.next_var(), kind: ty::BoundTyKind::Anon }, ), - ) - else { + ), + ) else { bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations.len(), 0); @@ -607,21 +612,21 @@ fn plug_infer_with_placeholders<'tcx>( fn visit_const(&mut self, ct: ty::Const<'tcx>) { let ct = self.infcx.shallow_resolve_const(ct); if ct.is_ct_infer() { - let Ok(InferOk { value: (), obligations }) = - self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( - // The types of the constants are the same, so there is no hidden type - // registration happening anyway. - DefineOpaqueTypes::Yes, - ct, - ty::Const::new_placeholder( - self.infcx.tcx, - ty::PlaceholderConst::new( - self.universe, - ty::BoundConst::new(self.next_var()), - ), + let Ok(InferOk { value: (), obligations }) = self.infcx.eq( + // The types of the constants are the same, so there is no hidden type + // registration happening anyway. + &ObligationCause::dummy(), + ty::ParamEnv::empty(), + DefineOpaqueTypes::Yes, + ct, + ty::Const::new_placeholder( + self.infcx.tcx, + ty::PlaceholderConst::new( + self.universe, + ty::BoundConst::new(self.next_var()), ), - ) - else { + ), + ) else { bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations.len(), 0); @@ -639,23 +644,23 @@ fn plug_infer_with_placeholders<'tcx>( .unwrap_region_constraints() .shallow_resolve_region_var(self.infcx.tcx, vid); if r.is_var() { - let Ok(InferOk { value: (), obligations }) = - self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( - // Lifetimes don't contain opaque types (or any types for that matter). - DefineOpaqueTypes::Yes, - r, - ty::Region::new_placeholder( - self.infcx.tcx, - ty::PlaceholderRegion::new( - self.universe, - ty::BoundRegion { - var: self.next_var(), - kind: ty::BoundRegionKind::Anon, - }, - ), + let Ok(InferOk { value: (), obligations }) = self.infcx.eq( + // Lifetimes don't contain opaque types (or any types for that matter). + &ObligationCause::dummy(), + ty::ParamEnv::empty(), + DefineOpaqueTypes::Yes, + r, + ty::Region::new_placeholder( + self.infcx.tcx, + ty::PlaceholderRegion::new( + self.universe, + ty::BoundRegion { + var: self.next_var(), + kind: ty::BoundRegionKind::Anon, + }, ), - ) - else { + ), + ) else { bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations.len(), 0); diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 5892e376126eb..3f4524eb30872 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -113,8 +113,13 @@ fn match_candidate<'tcx>( nested.extend( selcx .infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, obligation.predicate.trait_ref, candidate.trait_ref)? + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::Yes, + obligation.predicate.trait_ref, + candidate.trait_ref, + )? .into_obligations(), ); diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 3e6d14625c6b2..6e70056373e30 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -215,7 +215,7 @@ where param_env: ty::ParamEnv<'tcx>, value: Unnormalized<'tcx, T>, ) -> T { - let infer_ok = self.infcx.at(cause, param_env).normalize(value); + let infer_ok = self.infcx.normalize(cause, param_env, value); self.register_infer_ok_obligations(infer_ok) } @@ -227,8 +227,7 @@ where actual: T, ) -> Result<(), TypeError<'tcx>> { self.infcx - .at(cause, param_env) - .eq(DefineOpaqueTypes::Yes, expected, actual) + .eq(cause, param_env, DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -241,8 +240,7 @@ where actual: T, ) -> Result<(), TypeError<'tcx>> { self.infcx - .at(cause, param_env) - .eq_trace(DefineOpaqueTypes::Yes, trace, expected, actual) + .eq_trace(cause, param_env, DefineOpaqueTypes::Yes, trace, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -255,8 +253,7 @@ where actual: T, ) -> Result<(), TypeError<'tcx>> { self.infcx - .at(cause, param_env) - .sub(DefineOpaqueTypes::Yes, expected, actual) + .sub(cause, param_env, DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -269,8 +266,7 @@ where actual: T, ) -> Result<(), TypeError<'tcx>> { self.infcx - .at(cause, param_env) - .relate(DefineOpaqueTypes::Yes, expected, variance, actual) + .relate(cause, param_env, DefineOpaqueTypes::Yes, expected, variance, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -283,8 +279,7 @@ where actual: T, ) -> Result<(), TypeError<'tcx>> { self.infcx - .at(cause, param_env) - .sup(DefineOpaqueTypes::Yes, expected, actual) + .sup(cause, param_env, DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -297,8 +292,7 @@ where actual: T, ) -> Result> { self.infcx - .at(cause, param_env) - .lub(expected, actual) + .lub(cause, param_env, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -428,11 +422,13 @@ where // implied_bounds.insert(ty); let cause = ObligationCause::misc(span, def_id); - match self - .infcx - .at(&cause, param_env) - .deeply_normalize(Unnormalized::new_wip(ty), &mut *self.engine.borrow_mut()) - { + let infcx = self.infcx; + match infcx.deeply_normalize( + Unnormalized::new_wip(ty), + &mut *self.engine.borrow_mut(), + param_env, + &cause, + ) { // Insert well-formed types, ignoring duplicates. Ok(normalized) => drop(implied_bounds.insert(normalized)), Err(normalization_errors) => errors.extend(normalization_errors), @@ -448,7 +444,7 @@ where param_env: ty::ParamEnv<'tcx>, value: Unnormalized<'tcx, T>, ) -> Result> { - self.infcx.at(cause, param_env).deeply_normalize(value, &mut *self.engine.borrow_mut()) + self.infcx.deeply_normalize(value, &mut *self.engine.borrow_mut(), param_env, cause) } pub fn structurally_normalize_ty( @@ -457,9 +453,12 @@ where param_env: ty::ParamEnv<'tcx>, value: Unnormalized<'tcx, Ty<'tcx>>, ) -> Result, ThinVec> { - self.infcx - .at(cause, param_env) - .structurally_normalize_ty(value, &mut *self.engine.borrow_mut()) + self.infcx.structurally_normalize_ty( + value, + &mut *self.engine.borrow_mut(), + param_env, + cause, + ) } pub fn structurally_normalize_const( @@ -468,9 +467,12 @@ where param_env: ty::ParamEnv<'tcx>, value: Unnormalized<'tcx, ty::Const<'tcx>>, ) -> Result, ThinVec> { - self.infcx - .at(cause, param_env) - .structurally_normalize_const(value, &mut *self.engine.borrow_mut()) + self.infcx.structurally_normalize_const( + value, + &mut *self.engine.borrow_mut(), + param_env, + cause, + ) } pub fn structurally_normalize_term( @@ -479,8 +481,11 @@ where param_env: ty::ParamEnv<'tcx>, value: Unnormalized<'tcx, ty::Term<'tcx>>, ) -> Result, ThinVec> { - self.infcx - .at(cause, param_env) - .structurally_normalize_term(value, &mut *self.engine.borrow_mut()) + self.infcx.structurally_normalize_term( + value, + &mut *self.engine.borrow_mut(), + param_env, + cause, + ) } } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index aae323ae1671f..334ffe977abbb 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -577,8 +577,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } }; - match infcx.at(&obligation.cause, obligation.param_env).eq( + match infcx.eq( // Only really exercised by generic_const_exprs + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, ct_ty, ty, @@ -727,10 +729,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ) => { if let Ok(new_obligations) = infcx - .at(&obligation.cause, obligation.param_env) // Can define opaque types as this is only reachable with // `generic_const_exprs` .eq( + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, ty::AliasTerm::from(a), ty::AliasTerm::from(b), @@ -745,10 +748,15 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { (_, ty::ConstKind::Alias(_, _)) | (ty::ConstKind::Alias(_, _), _) => (), (_, _) => { if let Ok(new_obligations) = infcx - .at(&obligation.cause, obligation.param_env) // Can define opaque types as this is only reachable with // `generic_const_exprs` - .eq(DefineOpaqueTypes::Yes, c1, c2) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::Yes, + c1, + c2, + ) { return ProcessResult::Changed(mk_pending( obligation, @@ -788,9 +796,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { match (evaluate(c1), evaluate(c2)) { (Ok(c1), Ok(c2)) => { - match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( + match self.selcx.infcx.eq( // Can define opaque types as this is only reachable with // `generic_const_exprs` + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, c1, c2, diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 5a66fafd57361..79bed35e87830 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -1,7 +1,6 @@ //! Deeply normalize types using the old trait solver. use rustc_errors::msg; -use rustc_infer::infer::at::At; use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::traits::{ FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine, TraitErrors, @@ -22,22 +21,25 @@ use crate::error_reporting::traits::OverflowCause; use crate::solve::NextSolverError; #[extension(pub trait NormalizeExt<'tcx>)] -impl<'tcx> At<'_, 'tcx> { +impl<'tcx> InferCtxt<'tcx> { /// Normalize a value using the `AssocTypeNormalizer`. /// /// This normalization should be used when the type contains inference variables or the /// projection may be fallible. fn normalize>>( &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, value: Unnormalized<'tcx, T>, ) -> InferOk<'tcx, T> { - if self.infcx.next_trait_solver() { - let Normalized { value, obligations } = crate::solve::normalize(*self, value); + if self.next_trait_solver() { + let Normalized { value, obligations } = + crate::solve::normalize(self, cause, param_env, value); InferOk { value, obligations } } else { - let mut selcx = SelectionContext::new(self.infcx); + let mut selcx = SelectionContext::new(self); let Normalized { value, obligations } = - normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value); + normalize_with_depth(&mut selcx, param_env, cause.clone(), 0, value); InferOk { value, obligations } } } @@ -55,16 +57,18 @@ impl<'tcx> At<'_, 'tcx> { /// fulfillment context in the old solver. Once we have removed the old solver, we /// can remove the `fulfill_cx` parameter on this function. fn deeply_normalize( - self, + &self, value: Unnormalized<'tcx, T>, fulfill_cx: &mut dyn TraitEngine<'tcx, E>, + param_env: ty::ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Result> where T: TypeFoldable>, E: FromSolverError<'tcx, NextSolverError<'tcx>>, { - if self.infcx.next_trait_solver() { - crate::solve::deeply_normalize(self, value) + if self.next_trait_solver() { + crate::solve::deeply_normalize(&self, value, param_env, cause) } else { if fulfill_cx.has_pending_obligations() { let pending_obligations = fulfill_cx.pending_obligations(); @@ -75,17 +79,17 @@ impl<'tcx> At<'_, 'tcx> { ); } let value = self - .normalize(value) - .into_value_registering_obligations(self.infcx, &mut *fulfill_cx); - let errors = fulfill_cx.evaluate_obligations_error_on_ambiguity(self.infcx); - let value = self.infcx.deeply_resolve_ignoring_regions(value); + .normalize(cause, param_env, value) + .into_value_registering_obligations(&self, &mut *fulfill_cx); + let errors = fulfill_cx.evaluate_obligations_error_on_ambiguity(&self); + let value = self.deeply_resolve_ignoring_regions(value); match errors { TraitErrors::NoErrors => Ok(value), TraitErrors::HasErrors(errors) => { // Drop pending obligations, since deep normalization may happen // in a loop and we don't want to trigger the assertion on the next // iteration due to pending ambiguous obligations we've left over. - let _ = fulfill_cx.collect_remaining_errors(self.infcx); + let _ = fulfill_cx.collect_remaining_errors(&self); Err(errors) } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 6f7c46089632f..33faeae22a232 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -235,7 +235,9 @@ fn project_and_unify_term<'cx, 'tcx>( obligations.extend(new); // Need to define opaque types to support nested opaque types like `impl Fn() -> impl Trait` - match infcx.at(&obligation.cause, obligation.param_env).eq( + match infcx.eq( + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, normalized, actual, @@ -636,7 +638,7 @@ pub fn compute_inherent_assoc_term_args<'a, 'b, 'tcx>( self_ty.skip_normalization() }; - match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::Yes, impl_ty, self_ty) { + match selcx.infcx.eq(&cause, param_env, DefineOpaqueTypes::Yes, impl_ty, self_ty) { Ok(mut ok) => obligations.append(&mut ok.obligations), Err(_) => { tcx.dcx().span_bug( @@ -2019,7 +2021,9 @@ fn confirm_param_env_candidate<'cx, 'tcx>( debug!(?cache_projection, ?obligation_projection); - match infcx.at(cause, param_env).eq( + match infcx.eq( + cause, + param_env, DefineOpaqueTypes::Yes, cache_projection, obligation_projection, diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 31d2e8620af90..e46b0cd5b1d1b 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -192,7 +192,7 @@ where // to push them onto the stack to be expanded. for ty in constraints.dtorck_types.drain(..) { let ty = if let Ok(Normalized { value: ty, obligations }) = - ocx.infcx.at(&cause, param_env).query_normalize(ty) + ocx.infcx.query_normalize(ty, param_env, cause.clone()) { ocx.register_obligations(obligations); diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 782697782f94c..5331030c24699 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -16,17 +16,13 @@ use tracing::{debug, info, instrument}; use super::NoSolution; use crate::error_reporting::InferCtxtErrorExt; use crate::error_reporting::traits::OverflowCause; -use crate::infer::at::At; use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; use crate::traits::normalize::needs_normalization; -use crate::traits::{ - BoundVarReplacer, FulfillmentError, FulfillmentErrorCode, Normalized, ObligationCause, - PlaceholderReplacer, -}; +use crate::traits::{BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer}; #[extension(pub trait QueryNormalizeExt<'tcx>)] -impl<'a, 'tcx> At<'a, 'tcx> { +impl<'tcx> InferCtxt<'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 @@ -45,16 +41,20 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// N.B. Once the new solver is stabilized this method of normalization will /// likely be removed as trait solver operations are already cached by the query /// system making this redundant. - fn query_normalize(self, value: T) -> Result, NoSolution> + fn query_normalize( + &self, + value: T, + param_env: ty::ParamEnv<'tcx>, + cause: ObligationCause<'tcx>, + ) -> Result, NoSolution> where T: TypeFoldable>, { debug!( - "normalize::<{}>(value={:?}, param_env={:?}, cause={:?})", + "normalize::<{}>(value={:?}, param_env={:?})", std::any::type_name::(), value, - self.param_env, - self.cause, + param_env, ); // This is actually a consequence by the way `normalize_erasing_regions` works currently. @@ -76,45 +76,29 @@ impl<'a, 'tcx> At<'a, 'tcx> { vec![] }; - if self.infcx.next_trait_solver() { - match crate::solve::deeply_normalize_with_skipped_universes::<_, FulfillmentError<'tcx>>( - self, - Unnormalized::new_wip(value), - universes, - ) { + if self.next_trait_solver() { + match crate::solve::deeply_normalize_with_skipped_universes::< + _, + rustc_infer::traits::ScrubbedTraitError<'tcx>, + >(&self, Unnormalized::new_wip(value), universes, param_env, &cause) + { Ok(value) => { return Ok(Normalized { value, obligations: PredicateObligations::new() }); } - Err(errors) => { - // We're imitating the old solver's behavior of eagerly reporting overflow - // errors here. Otherwise we might silently ignore such errors. See #161542. - if let Some((overflowed_obligation, suggest_higher_limit)) = - errors.into_iter().find_map(|e| match e.code { - FulfillmentErrorCode::Ambiguity { - overflow: Some(suggest_higher_limit), - } => Some((e.root_obligation, suggest_higher_limit)), - _ => None, - }) - { - self.infcx.err_ctxt().report_overflow_obligation( - &overflowed_obligation, - suggest_higher_limit, - ); - } else { - return Err(NoSolution); - } + Err(_errors) => { + return Err(NoSolution); } } } - if !needs_normalization(self.infcx, &value) { + if !needs_normalization(&self, &value) { return Ok(Normalized { value, obligations: PredicateObligations::new() }); } let mut normalizer = QueryNormalizer { - infcx: self.infcx, - cause: self.cause, - param_env: self.param_env, + infcx: &self, + cause: &cause, + param_env, obligations: PredicateObligations::new(), cache: SsoHashMap::new(), anon_depth: 0, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 81517955181ee..e1308177bb259 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -189,8 +189,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligations.extend( self.infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::No, + placeholder_trait_predicate, + candidate, + ) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| SelectionError::Unimplemented)?, ); @@ -525,8 +530,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { nested.extend( self.infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, trait_predicate.trait_ref, upcast_trait_ref) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::No, + trait_predicate.trait_ref, + upcast_trait_ref, + ) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| SelectionError::Unimplemented)?, ); @@ -977,8 +987,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs self.infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, obligation_trait_ref, found_trait_ref) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::Yes, + obligation_trait_ref, + found_trait_ref, + ) .map(|InferOk { mut obligations, .. }| { obligations.extend(nested); obligations @@ -1084,8 +1099,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // only the **lifetime bound** is changed. let InferOk { mut obligations, .. } = self .infcx - .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::Yes, target, source_trait) + .sup( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::Yes, + target, + source_trait, + ) .map_err(|_| SelectionError::Unimplemented)?; // Register one obligation for 'a: 'b. @@ -1151,8 +1171,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { (&ty::Array(a, _), &ty::Slice(b)) => { let InferOk { obligations, .. } = self .infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, b, a) + .eq(&obligation.cause, obligation.param_env, DefineOpaqueTypes::Yes, b, a) .map_err(|_| SelectionError::Unimplemented)?; ImplSource::Builtin(BuiltinImplSource::Misc, obligations) @@ -1199,8 +1218,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let new_struct = Ty::new_adt(tcx, def, args); let InferOk { obligations, .. } = self .infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, target, new_struct) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::Yes, + target, + new_struct, + ) .map_err(|_| SelectionError::Unimplemented)?; nested.extend(obligations); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4846d75339cd6..0ab0cd3805a67 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -881,10 +881,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { if let Ok(InferOk { obligations, value: () }) = self .infcx - .at(&obligation.cause, obligation.param_env) // Can define opaque types as this is only reachable with // `generic_const_exprs` .eq( + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, ty::AliasTerm::from(a), ty::AliasTerm::from(b), @@ -898,10 +899,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { (_, _) => { if let Ok(InferOk { obligations, value: () }) = self .infcx - .at(&obligation.cause, obligation.param_env) // Can define opaque types as this is only reachable with // `generic_const_exprs` - .eq(DefineOpaqueTypes::Yes, c1, c2) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::Yes, + c1, + c2, + ) { return self .evaluate_predicates_recursively(previous_stack, obligations); @@ -925,9 +931,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match (evaluate(c1), evaluate(c2)) { (Ok(c1), Ok(c2)) => { - match self.infcx.at(&obligation.cause, obligation.param_env).eq( + match self.infcx.eq( // Can define opaque types as this is only reachable with // `generic_const_exprs` + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, c1, c2, @@ -980,8 +988,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } }; - match self.infcx.at(&obligation.cause, obligation.param_env).eq( + match self.infcx.eq( // Only really exercised by generic_const_exprs + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, ct_ty, ty, @@ -1691,8 +1701,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Unnormalized::new_wip(trait_bound), ); self.infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, placeholder_trait_ref, trait_bound) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::No, + placeholder_trait_ref, + trait_bound, + ) .map(|InferOk { obligations: _, value: () }| { // This method is called within a probe, so we can't have // inference variables and placeholders escape. @@ -1753,8 +1768,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let is_match = self .infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, obligation.predicate, infer_projection) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::No, + obligation.predicate, + infer_projection, + ) .is_ok_and(|InferOk { obligations, value: () }| { self.evaluate_predicates_recursively( TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()), @@ -2513,8 +2533,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let InferOk { obligations, .. } = self .infcx - .at(&cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref) + .eq( + &cause, + obligation.param_env, + DefineOpaqueTypes::No, + placeholder_obligation_trait_ref, + impl_trait_ref, + ) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) })?; @@ -2597,7 +2622,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { HigherRankedType, hr_source_principal, ); - self.infcx.at(&obligation.cause, obligation.param_env).eq_trace( + self.infcx.eq_trace( + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, ToTrace::to_trace( &obligation.cause, @@ -2634,18 +2661,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> { HigherRankedType, hr_source_projection, ); - self.infcx - .at(&obligation.cause, obligation.param_env) - .eq_trace( - DefineOpaqueTypes::Yes, - ToTrace::to_trace( - &obligation.cause, - hr_target_projection, - hr_source_projection, - ), - target_projection, - source_projection, - ) + self.infcx.eq_trace( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::Yes, + ToTrace::to_trace( + &obligation.cause, + hr_target_projection, + hr_source_projection, + ), + target_projection, + source_projection, + ) }) .is_ok() }) @@ -2666,7 +2693,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { HigherRankedType, hr_source_projection, ); - self.infcx.at(&obligation.cause, obligation.param_env).eq_trace( + self.infcx.eq_trace( + &obligation.cause, + obligation.param_env, DefineOpaqueTypes::Yes, ToTrace::to_trace( &obligation.cause, @@ -2727,8 +2756,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> { poly_trait_ref, ); self.infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, predicate.trait_ref, trait_ref) + .eq( + &obligation.cause, + obligation.param_env, + DefineOpaqueTypes::No, + predicate.trait_ref, + trait_ref, + ) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| ()) } diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index 2313ceaabd1ca..4d327bc62496f 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -1,19 +1,21 @@ -use rustc_infer::infer::at::At; -use rustc_infer::traits::{TraitEngine, TraitErrors}; +use rustc_infer::infer::InferCtxt; +use rustc_infer::traits::{ObligationCause, TraitEngine, TraitErrors}; use rustc_macros::extension; -use rustc_middle::ty::{self, Ty, Unnormalized}; +use rustc_middle::ty::{self, ParamEnv, Ty, Unnormalized}; use thin_vec::ThinVec; use crate::traits::{NormalizeExt, Obligation}; #[extension(pub trait StructurallyNormalizeExt<'tcx>)] -impl<'tcx> At<'_, 'tcx> { +impl<'tcx> InferCtxt<'tcx> { fn structurally_normalize_ty( &self, ty: Unnormalized<'tcx, Ty<'tcx>>, fulfill_cx: &mut dyn TraitEngine<'tcx, E>, + param_env: ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Result, ThinVec> { - self.structurally_normalize_term(ty.map(Into::into), fulfill_cx) + self.structurally_normalize_term(ty.map(Into::into), fulfill_cx, param_env, cause) .map(|term| term.expect_type()) } @@ -21,12 +23,14 @@ impl<'tcx> At<'_, 'tcx> { &self, ct: Unnormalized<'tcx, ty::Const<'tcx>>, fulfill_cx: &mut dyn TraitEngine<'tcx, E>, + param_env: ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Result, ThinVec> { - if self.infcx.tcx.features().generic_const_exprs() { - return Ok(super::evaluate_const(&self.infcx, ct.skip_normalization(), self.param_env)); + if self.tcx.features().generic_const_exprs() { + return Ok(super::evaluate_const(&self, ct.skip_normalization(), param_env)); } - self.structurally_normalize_term(ct.map(Into::into), fulfill_cx) + self.structurally_normalize_term(ct.map(Into::into), fulfill_cx, param_env, cause) .map(|term| term.expect_const()) } @@ -34,16 +38,18 @@ impl<'tcx> At<'_, 'tcx> { &self, term: Unnormalized<'tcx, ty::Term<'tcx>>, fulfill_cx: &mut dyn TraitEngine<'tcx, E>, + param_env: ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Result, ThinVec> { assert!( !term.as_ref().skip_normalization().is_infer(), "should have resolved vars before calling" ); - if self.infcx.next_trait_solver() { + if self.next_trait_solver() { let term = term.skip_normalization(); - if !self.infcx.tcx.renormalize_rigid_aliases() && !term.is_non_rigid_alias() { + if !self.tcx.renormalize_rigid_aliases() && !term.is_non_rigid_alias() { return Ok(term); }; @@ -51,27 +57,29 @@ impl<'tcx> At<'_, 'tcx> { return Ok(term); }; - let new_infer = self.infcx.next_term_var_of_alias_kind(alias, self.cause.span); + let new_infer = self.next_term_var_of_alias_kind(alias, cause.span); // We simply emit an `Projection` goal here, since that will take care of // normalizing the LHS of the projection until it is a rigid projection // (or a not-yet-defined opaque in scope). let obligation = Obligation::new( - self.infcx.tcx, - self.cause.clone(), - self.param_env, + self.tcx, + cause.clone(), + param_env, ty::ProjectionClause { projection_term: alias, term: new_infer }, ); - fulfill_cx.register_predicate_obligation(self.infcx, obligation); - let errors = fulfill_cx.try_evaluate_obligations(self.infcx); + fulfill_cx.register_predicate_obligation(&self, obligation); + let errors = fulfill_cx.try_evaluate_obligations(&self); if let TraitErrors::HasErrors(errors) = errors { return Err(errors); } - Ok(self.infcx.deeply_resolve_ignoring_regions(new_infer)) + Ok(self.deeply_resolve_ignoring_regions(new_infer)) } else { - Ok(self.normalize(term).into_value_registering_obligations(self.infcx, fulfill_cx)) + Ok(self + .normalize(cause, param_env, term) + .into_value_registering_obligations(&self, fulfill_cx)) } } } diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 5ee83ae651713..18c2cb5c3682f 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -24,7 +24,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable> + Par let PseudoCanonicalInput { typing_env, value } = goal; let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env); let cause = ObligationCause::dummy(); - match infcx.at(&cause, param_env).query_normalize(value) { + match infcx.query_normalize(value, param_env, cause) { 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 3ab1e80622623..4c773e6f269bd 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -46,10 +46,11 @@ where T: fmt::Debug + TypeFoldable>, { let ParamEnvAnd { param_env, value: Normalize { value } } = key; - let Normalized { value, obligations } = ocx - .infcx - .at(&ObligationCause::dummy(), param_env) - .query_normalize(value.skip_normalization())?; + let Normalized { value, obligations } = ocx.infcx.query_normalize( + value.skip_normalization(), + param_env, + ObligationCause::dummy(), + )?; ocx.register_obligations(obligations); Ok(value) } diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 7b4af6ac0dbcb..d0ed33fe280ee 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -48,7 +48,9 @@ pub(crate) fn synthesize_blanket_impls( // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. - let Ok(eq_result) = infcx.at(&traits::ObligationCause::dummy(), param_env).eq( + let Ok(eq_result) = infcx.eq( + &traits::ObligationCause::dummy(), + param_env, DefineOpaqueTypes::Yes, impl_trait_ref.self_ty(), impl_ty, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 09dbd279988f6..8db6fbe90ed98 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2026,8 +2026,7 @@ fn normalize<'tcx>( // Try to normalize `::T` to a type let infcx = cx.tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let normalized = infcx - .at(&ObligationCause::dummy(), cx.param_env) - .query_normalize(ty) + .query_normalize(ty, cx.param_env, ObligationCause::dummy()) .map(|resolved| infcx.deeply_resolve_ignoring_regions(resolved.value)); match normalized { Ok(normalized_value) => { @@ -2604,8 +2603,7 @@ pub(crate) fn clean_variant_def_with_args<'tcx>( // note: we do not use try_normalize_erasing_regions since we // do care about showing the regions let ty = infcx - .at(&ObligationCause::dummy(), cx.param_env) - .query_normalize(ty) + .query_normalize(ty, cx.param_env, ObligationCause::dummy()) .map(|normalized| normalized.value) .unwrap_or(ty); @@ -2629,8 +2627,7 @@ pub(crate) fn clean_variant_def_with_args<'tcx>( // note: we do not use try_normalize_erasing_regions since we // do care about showing the regions let ty = infcx - .at(&ObligationCause::dummy(), cx.param_env) - .query_normalize(ty) + .query_normalize(ty, cx.param_env, ObligationCause::dummy()) .map(|normalized| normalized.value) .unwrap_or(ty); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f779fce47cd2f..9f8d864e5639a 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -18,10 +18,13 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::{DefKind, MacroKinds}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::traits::ObligationCause; use rustc_metadata::creader::CStore; use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode}; use rustc_span::symbol::kw; use rustc_span::{Ident, Symbol}; +use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use tracing::{debug, trace}; use super::url_parts_builder::UrlPartsBuilder; @@ -420,8 +423,11 @@ fn impl_self_ty(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Ty<'_> { let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ty = tcx.type_of(impl_def_id); infcx - .at(&ObligationCause::dummy(), tcx.param_env(impl_def_id)) - .query_normalize(ty::Binder::dummy(ty.instantiate_identity().skip_norm_wip())) + .query_normalize( + ty::Binder::dummy(ty.instantiate_identity().skip_norm_wip()), + tcx.param_env(impl_def_id), + ObligationCause::dummy(), + ) .map(|resolved| infcx.deeply_resolve_ignoring_regions(resolved.value).skip_binder()) .unwrap_or(ty.skip_binder()) } @@ -517,20 +523,17 @@ fn generate_item_def_id_path( if def_id != original_def_id && let DefKind::Impl { of_trait } = tcx.def_kind(def_id) { - let ty = impl_self_ty(tcx, def_id); - // If this is a dyn trait, we want to get the actual trait from which the method comes from. - // Since a `dyn trait` (as of 2026) can only be composed of a trait plus auto traits, we - // look for the trait and ignore auto traits. - if let ty::Dynamic(traits, _) = ty.kind() - && let Some(trait_def_id) = - traits.iter().find_map(|trait_| match trait_.skip_binder() { - ty::ExistentialPredicate::Trait(t) => Some(t.def_id), - ty::ExistentialPredicate::Projection(p) => Some(p.trait_ref(tcx).def_id), - ty::ExistentialPredicate::AutoTrait(_) => None, - }) - { - def_id = trait_def_id; - } else if let Some(new_def_id) = ty.ty_adt_def().map(|adt| adt.did()) { + let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); + let ty = tcx.type_of(def_id); + let ty = infcx + .query_normalize( + ty::Binder::dummy(ty.instantiate_identity().skip_norm_wip()), + tcx.param_env(def_id), + ObligationCause::dummy(), + ) + .map(|resolved| infcx.deeply_resolve_ignoring_regions(resolved.value).skip_binder()) + .unwrap_or(ty.skip_binder()); + if let Some(new_def_id) = ty.ty_adt_def().map(|adt| adt.did()) { def_id = new_def_id; maybe_have_impl_not_in_def_crate = !of_trait && !original_def_id.is_local() diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 89174b281b773..41d79accbd036 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -1411,8 +1411,7 @@ pub fn make_normalized_projection_with_regions<'tcx>( let cause = ObligationCause::dummy(); let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); match infcx - .at(&cause, param_env) - .query_normalize(Ty::new_alias(tcx, ty::IsRigid::No, ty)) + .query_normalize(Ty::new_alias(tcx, ty::IsRigid::No, ty), param_env, cause) { Ok(ty) => Some(ty.value), Err(e) => { @@ -1428,8 +1427,7 @@ pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv let cause = ObligationCause::dummy(); let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); infcx - .at(&cause, param_env) - .query_normalize(ty) + .query_normalize(ty, param_env, cause) .map_or(ty, |ty| ty.value) }