about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-12 03:35:31 +0000
committerbors <bors@rust-lang.org>2024-06-12 03:35:31 +0000
commit76c73827dcd0b363e60b22c3cef64bde4171bf17 (patch)
treefd68f4571bdb2039c0dd6a0f7b7726b2a5c276fb /compiler
parent9a7bf4ae947feddac27007cbe26d161f4ff5a910 (diff)
parente4be97cfe763fc5550e048ae3db288fd27a1954c (diff)
downloadrust-76c73827dcd0b363e60b22c3cef64bde4171bf17.tar.gz
rust-76c73827dcd0b363e60b22c3cef64bde4171bf17.zip
Auto merge of #126130 - compiler-errors:goal-relations, r=lcnr
Make `ObligationEmittingRelation`s emit `Goal` rather than `Obligation`

Helps avoid needing to uplift `Obligation` into the solver. We still can't get rid of `ObligationCause`, but we can keep it as an associated type for `InferCtxtLike` and just give it a `dummy` function.

There's some shuttling between `Goal` and `Obligation` that may be perf-sensitive... Let's see what rust-timer says.

r? lcnr
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs41
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs2
-rw-r--r--compiler/rustc_infer/src/infer/at.rs52
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs13
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs107
-rw-r--r--compiler/rustc_infer/src/infer/projection.rs11
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs56
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs6
-rw-r--r--compiler/rustc_infer/src/infer/relate/glb.rs16
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs10
-rw-r--r--compiler/rustc_infer/src/infer/relate/lub.rs16
-rw-r--r--compiler/rustc_infer/src/infer/relate/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs35
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs4
17 files changed, 216 insertions, 178 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index 2c34fc583c8..c531c9b209b 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -1,9 +1,10 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::ErrorGuaranteed;
-use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases};
+use rustc_infer::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
 use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation};
 use rustc_infer::infer::NllRegionVariableOrigin;
-use rustc_infer::traits::{Obligation, PredicateObligations};
+use rustc_infer::traits::solve::Goal;
+use rustc_infer::traits::Obligation;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::span_bug;
 use rustc_middle::traits::query::NoSolution;
@@ -153,9 +154,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
                 "expected at least one opaque type in `relate_opaques`, got {a} and {b}."
             ),
         };
-        let cause = ObligationCause::dummy_with_span(self.span());
-        let obligations = infcx.handle_opaque_type(a, b, &cause, self.param_env())?.obligations;
-        self.register_obligations(obligations);
+        self.register_goals(infcx.handle_opaque_type(a, b, self.span(), self.param_env())?);
         Ok(())
     }
 
@@ -533,7 +532,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
     }
 }
 
-impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
+impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
     fn span(&self) -> Span {
         self.locations.span(self.type_checker.body)
     }
@@ -550,22 +549,32 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx
         &mut self,
         obligations: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
     ) {
-        self.register_obligations(
-            obligations
-                .into_iter()
-                .map(|to_pred| {
-                    Obligation::new(self.tcx(), ObligationCause::dummy(), self.param_env(), to_pred)
-                })
-                .collect(),
+        let tcx = self.tcx();
+        let param_env = self.param_env();
+        self.register_goals(
+            obligations.into_iter().map(|to_pred| Goal::new(tcx, param_env, to_pred)),
         );
     }
 
-    fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
+    fn register_goals(
+        &mut self,
+        obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+    ) {
         let _: Result<_, ErrorGuaranteed> = self.type_checker.fully_perform_op(
             self.locations,
             self.category,
             InstantiateOpaqueType {
-                obligations,
+                obligations: obligations
+                    .into_iter()
+                    .map(|goal| {
+                        Obligation::new(
+                            self.tcx(),
+                            ObligationCause::dummy_with_span(self.span()),
+                            goal.param_env,
+                            goal.predicate,
+                        )
+                    })
+                    .collect(),
                 // These fields are filled in during execution of the operation
                 base_universe: None,
                 region_constraints: None,
@@ -573,7 +582,7 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx
         );
     }
 
-    fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
+    fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
         self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
             ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
                 a.into(),
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index dbaa6e398c8..e54a07786cd 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -113,7 +113,7 @@ fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'
 fn success<'tcx>(
     adj: Vec<Adjustment<'tcx>>,
     target: Ty<'tcx>,
-    obligations: traits::PredicateObligations<'tcx>,
+    obligations: Vec<traits::PredicateObligation<'tcx>>,
 ) -> CoerceResult<'tcx> {
     Ok(InferOk { value: (adj, target), obligations })
 }
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 046d908d148..01bd732a4cd 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -31,6 +31,8 @@ use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation};
 use rustc_middle::bug;
 use rustc_middle::ty::{Const, ImplSubject};
 
+use crate::traits::Obligation;
+
 /// Whether we should define opaque types or just treat them opaquely.
 ///
 /// Currently only used to prevent predicate matching from matching anything
@@ -119,10 +121,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
             self.param_env,
             define_opaque_types,
         );
-        fields
-            .sup()
-            .relate(expected, actual)
-            .map(|_| InferOk { value: (), obligations: fields.obligations })
+        fields.sup().relate(expected, actual)?;
+        Ok(InferOk { value: (), obligations: fields.into_obligations() })
     }
 
     /// Makes `expected <: actual`.
@@ -141,10 +141,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
             self.param_env,
             define_opaque_types,
         );
-        fields
-            .sub()
-            .relate(expected, actual)
-            .map(|_| InferOk { value: (), obligations: fields.obligations })
+        fields.sub().relate(expected, actual)?;
+        Ok(InferOk { value: (), obligations: fields.into_obligations() })
     }
 
     /// Makes `expected == actual`.
@@ -163,10 +161,22 @@ impl<'a, 'tcx> At<'a, 'tcx> {
             self.param_env,
             define_opaque_types,
         );
-        fields
-            .equate(StructurallyRelateAliases::No)
-            .relate(expected, actual)
-            .map(|_| InferOk { value: (), obligations: fields.obligations })
+        fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?;
+        Ok(InferOk {
+            value: (),
+            obligations: fields
+                .goals
+                .into_iter()
+                .map(|goal| {
+                    Obligation::new(
+                        self.infcx.tcx,
+                        fields.trace.cause.clone(),
+                        goal.param_env,
+                        goal.predicate,
+                    )
+                })
+                .collect(),
+        })
     }
 
     /// Equates `expected` and `found` while structurally relating aliases.
@@ -187,10 +197,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
             self.param_env,
             DefineOpaqueTypes::Yes,
         );
-        fields
-            .equate(StructurallyRelateAliases::Yes)
-            .relate(expected, actual)
-            .map(|_| InferOk { value: (), obligations: fields.obligations })
+        fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
+        Ok(InferOk { value: (), obligations: fields.into_obligations() })
     }
 
     pub fn relate<T>(
@@ -237,10 +245,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
             self.param_env,
             define_opaque_types,
         );
-        fields
-            .lub()
-            .relate(expected, actual)
-            .map(|value| InferOk { value, obligations: fields.obligations })
+        let value = fields.lub().relate(expected, actual)?;
+        Ok(InferOk { value, obligations: fields.into_obligations() })
     }
 
     /// Computes the greatest-lower-bound, or mutual subtype, of two
@@ -261,10 +267,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
             self.param_env,
             define_opaque_types,
         );
-        fields
-            .glb()
-            .relate(expected, actual)
-            .map(|value| InferOk { value, obligations: fields.obligations })
+        let value = fields.glb().relate(expected, actual)?;
+        Ok(InferOk { value, obligations: fields.into_obligations() })
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index c606ab808ef..32b50053b50 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1,6 +1,9 @@
 pub use at::DefineOpaqueTypes;
 pub use freshen::TypeFreshener;
 pub use lexical_region_resolve::RegionResolutionError;
+pub use relate::combine::CombineFields;
+pub use relate::combine::PredicateEmittingRelation;
+pub use relate::StructurallyRelateAliases;
 pub use rustc_macros::{TypeFoldable, TypeVisitable};
 pub use rustc_middle::ty::IntVarValue;
 pub use BoundRegionConversionTime::*;
@@ -8,10 +11,8 @@ pub use RegionVariableOrigin::*;
 pub use SubregionOrigin::*;
 pub use ValuePairs::*;
 
-use crate::infer::relate::{CombineFields, RelateResult};
-use crate::traits::{
-    self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine,
-};
+use crate::infer::relate::RelateResult;
+use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
 use error_reporting::TypeErrCtxt;
 use free_regions::RegionRelations;
 use lexical_region_resolve::LexicalRegionResolutions;
@@ -68,7 +69,7 @@ pub mod type_variable;
 #[derive(Debug)]
 pub struct InferOk<'tcx, T> {
     pub value: T,
-    pub obligations: PredicateObligations<'tcx>,
+    pub obligations: Vec<PredicateObligation<'tcx>>,
 }
 pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
 
@@ -748,7 +749,7 @@ impl<'tcx, T> InferOk<'tcx, T> {
 }
 
 impl<'tcx> InferOk<'tcx, ()> {
-    pub fn into_obligations(self) -> PredicateObligations<'tcx> {
+    pub fn into_obligations(self) -> Vec<PredicateObligation<'tcx>> {
         self.obligations
     }
 }
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index 8eb3185673b..7114b888718 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -1,11 +1,11 @@
-use super::{DefineOpaqueTypes, InferResult};
 use crate::errors::OpaqueHiddenTypeDiag;
 use crate::infer::{InferCtxt, InferOk};
-use crate::traits::{self, PredicateObligation};
+use crate::traits::{self, Obligation};
 use hir::def_id::{DefId, LocalDefId};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
+use rustc_middle::traits::solve::Goal;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::BottomUpFolder;
@@ -21,6 +21,8 @@ mod table;
 pub type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
 pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
 
+use super::DefineOpaqueTypes;
+
 /// Information about the opaque types whose values we
 /// are inferring in this function (these are the `impl Trait` that
 /// appear in the return type).
@@ -62,11 +64,23 @@ impl<'tcx> InferCtxt<'tcx> {
                 {
                     let def_span = self.tcx.def_span(def_id);
                     let span = if span.contains(def_span) { def_span } else { span };
-                    let code = traits::ObligationCauseCode::OpaqueReturnType(None);
-                    let cause = ObligationCause::new(span, body_id, code);
                     let ty_var = self.next_ty_var(span);
                     obligations.extend(
-                        self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations,
+                        self.handle_opaque_type(ty, ty_var, span, param_env)
+                            .unwrap()
+                            .into_iter()
+                            .map(|goal| {
+                                Obligation::new(
+                                    self.tcx,
+                                    ObligationCause::new(
+                                        span,
+                                        body_id,
+                                        traits::ObligationCauseCode::OpaqueReturnType(None),
+                                    ),
+                                    goal.param_env,
+                                    goal.predicate,
+                                )
+                            }),
                     );
                     ty_var
                 }
@@ -80,9 +94,9 @@ impl<'tcx> InferCtxt<'tcx> {
         &self,
         a: Ty<'tcx>,
         b: Ty<'tcx>,
-        cause: &ObligationCause<'tcx>,
+        span: Span,
         param_env: ty::ParamEnv<'tcx>,
-    ) -> InferResult<'tcx, ()> {
+    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
         let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
                 let def_id = def_id.expect_local();
@@ -90,7 +104,7 @@ impl<'tcx> InferCtxt<'tcx> {
                     // See comment on `insert_hidden_type` for why this is sufficient in coherence
                     return Some(self.register_hidden_type(
                         OpaqueTypeKey { def_id, args },
-                        cause.clone(),
+                        span,
                         param_env,
                         b,
                     ));
@@ -143,18 +157,13 @@ impl<'tcx> InferCtxt<'tcx> {
                         && self.tcx.is_type_alias_impl_trait(b_def_id)
                     {
                         self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag {
-                            span: cause.span,
+                            span,
                             hidden_type: self.tcx.def_span(b_def_id),
                             opaque_type: self.tcx.def_span(def_id),
                         });
                     }
                 }
-                Some(self.register_hidden_type(
-                    OpaqueTypeKey { def_id, args },
-                    cause.clone(),
-                    param_env,
-                    b,
-                ))
+                Some(self.register_hidden_type(OpaqueTypeKey { def_id, args }, span, param_env, b))
             }
             _ => None,
         };
@@ -464,24 +473,23 @@ impl<'tcx> InferCtxt<'tcx> {
     fn register_hidden_type(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
-        cause: ObligationCause<'tcx>,
+        span: Span,
         param_env: ty::ParamEnv<'tcx>,
         hidden_ty: Ty<'tcx>,
-    ) -> InferResult<'tcx, ()> {
-        let mut obligations = Vec::new();
+    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
+        let mut goals = Vec::new();
 
-        self.insert_hidden_type(opaque_type_key, &cause, param_env, hidden_ty, &mut obligations)?;
+        self.insert_hidden_type(opaque_type_key, span, param_env, hidden_ty, &mut goals)?;
 
         self.add_item_bounds_for_hidden_type(
             opaque_type_key.def_id.to_def_id(),
             opaque_type_key.args,
-            cause,
             param_env,
             hidden_ty,
-            &mut obligations,
+            &mut goals,
         );
 
-        Ok(InferOk { value: (), obligations })
+        Ok(goals)
     }
 
     /// Insert a hidden type into the opaque type storage, making sure
@@ -507,27 +515,21 @@ impl<'tcx> InferCtxt<'tcx> {
     pub fn insert_hidden_type(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
-        cause: &ObligationCause<'tcx>,
+        span: Span,
         param_env: ty::ParamEnv<'tcx>,
         hidden_ty: Ty<'tcx>,
-        obligations: &mut Vec<PredicateObligation<'tcx>>,
+        goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
     ) -> Result<(), TypeError<'tcx>> {
         // Ideally, we'd get the span where *this specific `ty` came
         // from*, but right now we just use the span from the overall
         // value being folded. In simple cases like `-> impl Foo`,
         // these are the same span, but not in cases like `-> (impl
         // Foo, impl Bar)`.
-        let span = cause.span;
         if self.intercrate {
             // During intercrate we do not define opaque types but instead always
             // force ambiguity unless the hidden type is known to not implement
             // our trait.
-            obligations.push(traits::Obligation::new(
-                self.tcx,
-                cause.clone(),
-                param_env,
-                ty::PredicateKind::Ambiguous,
-            ))
+            goals.push(Goal::new(self.tcx, param_env, ty::PredicateKind::Ambiguous))
         } else {
             let prev = self
                 .inner
@@ -535,10 +537,13 @@ impl<'tcx> InferCtxt<'tcx> {
                 .opaque_types()
                 .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span });
             if let Some(prev) = prev {
-                obligations.extend(
-                    self.at(cause, param_env)
+                goals.extend(
+                    self.at(&ObligationCause::dummy_with_span(span), param_env)
                         .eq(DefineOpaqueTypes::Yes, prev, hidden_ty)?
-                        .obligations,
+                        .obligations
+                        .into_iter()
+                        // FIXME: Shuttling between obligations and goals is awkward.
+                        .map(Goal::from),
                 );
             }
         };
@@ -550,10 +555,9 @@ impl<'tcx> InferCtxt<'tcx> {
         &self,
         def_id: DefId,
         args: ty::GenericArgsRef<'tcx>,
-        cause: ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         hidden_ty: Ty<'tcx>,
-        obligations: &mut Vec<PredicateObligation<'tcx>>,
+        goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
     ) {
         let tcx = self.tcx;
         // Require that the hidden type is well-formed. We have to
@@ -567,12 +571,7 @@ impl<'tcx> InferCtxt<'tcx> {
         // type during MIR borrowck, causing us to infer the wrong
         // lifetime for its member constraints which then results in
         // unexpected region errors.
-        obligations.push(traits::Obligation::new(
-            tcx,
-            cause.clone(),
-            param_env,
-            ty::ClauseKind::WellFormed(hidden_ty.into()),
-        ));
+        goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into())));
 
         let item_bounds = tcx.explicit_item_bounds(def_id);
         for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
@@ -588,13 +587,18 @@ impl<'tcx> InferCtxt<'tcx> {
                             && !tcx.is_impl_trait_in_trait(projection_ty.def_id)
                             && !self.next_trait_solver() =>
                     {
-                        self.projection_ty_to_infer(
+                        let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id));
+                        goals.push(Goal::new(
+                            self.tcx,
                             param_env,
-                            projection_ty,
-                            cause.clone(),
-                            0,
-                            obligations,
-                        )
+                            ty::PredicateKind::Clause(ty::ClauseKind::Projection(
+                                ty::ProjectionPredicate {
+                                    projection_term: projection_ty.into(),
+                                    term: ty_var.into(),
+                                },
+                            )),
+                        ));
+                        ty_var
                     }
                     // Replace all other mentions of the same opaque type with the hidden type,
                     // as the bounds must hold on the hidden type after all.
@@ -611,12 +615,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
             // Require that the predicate holds for the concrete type.
             debug!(?predicate);
-            obligations.push(traits::Obligation::new(
-                self.tcx,
-                cause.clone(),
-                param_env,
-                predicate,
-            ));
+            goals.push(Goal::new(self.tcx, param_env, predicate));
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs
index 16786347980..a1ba43eb171 100644
--- a/compiler/rustc_infer/src/infer/projection.rs
+++ b/compiler/rustc_infer/src/infer/projection.rs
@@ -21,11 +21,12 @@ impl<'tcx> InferCtxt<'tcx> {
         obligations: &mut Vec<PredicateObligation<'tcx>>,
     ) -> Ty<'tcx> {
         debug_assert!(!self.next_trait_solver());
-        let def_id = projection_ty.def_id;
-        let ty_var = self.next_ty_var(self.tcx.def_span(def_id));
-        let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection(
-            ty::ProjectionPredicate { projection_term: projection_ty.into(), term: ty_var.into() },
-        )));
+        let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id));
+        let projection =
+            ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
+                projection_term: projection_ty.into(),
+                term: ty_var.into(),
+            }));
         let obligation =
             Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection);
         obligations.push(obligation);
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 30cb2bab900..0a2e85cc891 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -25,9 +25,10 @@ use super::StructurallyRelateAliases;
 use super::{RelateResult, TypeRelation};
 use crate::infer::relate;
 use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
-use crate::traits::{Obligation, PredicateObligations};
+use crate::traits::{Obligation, PredicateObligation};
 use rustc_middle::bug;
 use rustc_middle::infer::unify_key::EffectVarValue;
+use rustc_middle::traits::solve::Goal;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
 use rustc_middle::ty::{IntType, UintType};
@@ -38,7 +39,7 @@ pub struct CombineFields<'infcx, 'tcx> {
     pub infcx: &'infcx InferCtxt<'tcx>,
     pub trace: TypeTrace<'tcx>,
     pub param_env: ty::ParamEnv<'tcx>,
-    pub obligations: PredicateObligations<'tcx>,
+    pub goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
     pub define_opaque_types: DefineOpaqueTypes,
 }
 
@@ -49,7 +50,21 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         define_opaque_types: DefineOpaqueTypes,
     ) -> Self {
-        Self { infcx, trace, param_env, define_opaque_types, obligations: vec![] }
+        Self { infcx, trace, param_env, define_opaque_types, goals: vec![] }
+    }
+
+    pub(crate) fn into_obligations(self) -> Vec<PredicateObligation<'tcx>> {
+        self.goals
+            .into_iter()
+            .map(|goal| {
+                Obligation::new(
+                    self.infcx.tcx,
+                    self.trace.cause.clone(),
+                    goal.param_env,
+                    goal.predicate,
+                )
+            })
+            .collect()
     }
 }
 
@@ -61,7 +76,7 @@ impl<'tcx> InferCtxt<'tcx> {
         b: Ty<'tcx>,
     ) -> RelateResult<'tcx, Ty<'tcx>>
     where
-        R: ObligationEmittingRelation<'tcx>,
+        R: PredicateEmittingRelation<'tcx>,
     {
         debug_assert!(!a.has_escaping_bound_vars());
         debug_assert!(!b.has_escaping_bound_vars());
@@ -125,7 +140,7 @@ impl<'tcx> InferCtxt<'tcx> {
                         relate::structurally_relate_tys(relation, a, b)
                     }
                     StructurallyRelateAliases::No => {
-                        relation.register_type_relate_obligation(a, b);
+                        relation.register_alias_relate_predicate(a, b);
                         Ok(a)
                     }
                 }
@@ -156,7 +171,7 @@ impl<'tcx> InferCtxt<'tcx> {
         b: ty::Const<'tcx>,
     ) -> RelateResult<'tcx, ty::Const<'tcx>>
     where
-        R: ObligationEmittingRelation<'tcx>,
+        R: PredicateEmittingRelation<'tcx>,
     {
         debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
         debug_assert!(!a.has_escaping_bound_vars());
@@ -290,21 +305,26 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
         Glb::new(self)
     }
 
-    pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
-        self.obligations.extend(obligations);
+    pub fn register_obligations(
+        &mut self,
+        obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+    ) {
+        self.goals.extend(obligations);
     }
 
     pub fn register_predicates(
         &mut self,
         obligations: impl IntoIterator<Item: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
     ) {
-        self.obligations.extend(obligations.into_iter().map(|to_pred| {
-            Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, to_pred)
-        }))
+        self.goals.extend(
+            obligations
+                .into_iter()
+                .map(|to_pred| Goal::new(self.infcx.tcx, self.param_env, to_pred)),
+        )
     }
 }
 
-pub trait ObligationEmittingRelation<'tcx>: TypeRelation<TyCtxt<'tcx>> {
+pub trait PredicateEmittingRelation<'tcx>: TypeRelation<TyCtxt<'tcx>> {
     fn span(&self) -> Span;
 
     fn param_env(&self) -> ty::ParamEnv<'tcx>;
@@ -315,16 +335,18 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<TyCtxt<'tcx>> {
     fn structurally_relate_aliases(&self) -> StructurallyRelateAliases;
 
     /// Register obligations that must hold in order for this relation to hold
-    fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>);
+    fn register_goals(
+        &mut self,
+        obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+    );
 
-    /// Register predicates that must hold in order for this relation to hold. Uses
-    /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should
-    /// be used if control over the obligation causes is required.
+    /// Register predicates that must hold in order for this relation to hold.
+    /// This uses the default `param_env` of the obligation.
     fn register_predicates(
         &mut self,
         obligations: impl IntoIterator<Item: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
     );
 
     /// Register `AliasRelate` obligation(s) that both types must be related to each other.
-    fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>);
+    fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>);
 }
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 5478afda455..87a2f0b4580 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -1,7 +1,7 @@
 use std::mem;
 
 use super::StructurallyRelateAliases;
-use super::{ObligationEmittingRelation, Relate, RelateResult, TypeRelation};
+use super::{PredicateEmittingRelation, Relate, RelateResult, TypeRelation};
 use crate::infer::relate;
 use crate::infer::type_variable::TypeVariableValue;
 use crate::infer::{InferCtxt, RegionVariableOrigin};
@@ -30,7 +30,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
     /// other usecases (i.e. setting the value of a type var).
     #[instrument(level = "debug", skip(self, relation))]
-    pub fn instantiate_ty_var<R: ObligationEmittingRelation<'tcx>>(
+    pub fn instantiate_ty_var<R: PredicateEmittingRelation<'tcx>>(
         &self,
         relation: &mut R,
         target_is_expected: bool,
@@ -178,7 +178,7 @@ impl<'tcx> InferCtxt<'tcx> {
     ///
     /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant.
     #[instrument(level = "debug", skip(self, relation))]
-    pub(super) fn instantiate_const_var<R: ObligationEmittingRelation<'tcx>>(
+    pub(super) fn instantiate_const_var<R: PredicateEmittingRelation<'tcx>>(
         &self,
         relation: &mut R,
         target_is_expected: bool,
diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs
index 98e8f07c7a2..cc17e60a79b 100644
--- a/compiler/rustc_infer/src/infer/relate/glb.rs
+++ b/compiler/rustc_infer/src/infer/relate/glb.rs
@@ -1,14 +1,15 @@
 //! Greatest lower bound. See [`lattice`].
 
-use super::{Relate, RelateResult, TypeRelation};
+use rustc_middle::traits::solve::Goal;
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::Span;
 
-use super::combine::{CombineFields, ObligationEmittingRelation};
+use super::combine::{CombineFields, PredicateEmittingRelation};
 use super::lattice::{self, LatticeDir};
 use super::StructurallyRelateAliases;
 use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
-use crate::traits::{ObligationCause, PredicateObligations};
+use crate::traits::ObligationCause;
 
 /// "Greatest lower bound" (common subtype)
 pub struct Glb<'combine, 'infcx, 'tcx> {
@@ -127,7 +128,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
     }
 }
 
-impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
+impl<'tcx> PredicateEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
     fn span(&self) -> Span {
         self.fields.trace.span()
     }
@@ -147,11 +148,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
         self.fields.register_predicates(obligations);
     }
 
-    fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
+    fn register_goals(
+        &mut self,
+        obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+    ) {
         self.fields.register_obligations(obligations);
     }
 
-    fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
+    fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
         self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
             a.into(),
             b.into(),
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index f05b984142a..6cc8d6d910a 100644
--- a/compiler/rustc_infer/src/infer/relate/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -17,11 +17,11 @@
 //!
 //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order)
 
-use super::combine::ObligationEmittingRelation;
+use super::combine::PredicateEmittingRelation;
 use crate::infer::{DefineOpaqueTypes, InferCtxt};
 use crate::traits::ObligationCause;
 
-use super::RelateResult;
+use rustc_middle::ty::relate::RelateResult;
 use rustc_middle::ty::TyVar;
 use rustc_middle::ty::{self, Ty};
 
@@ -30,7 +30,7 @@ use rustc_middle::ty::{self, Ty};
 ///
 /// GLB moves "down" the lattice (to smaller values); LUB moves
 /// "up" the lattice (to bigger values).
-pub trait LatticeDir<'f, 'tcx>: ObligationEmittingRelation<'tcx> {
+pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<'tcx> {
     fn infcx(&self) -> &'f InferCtxt<'tcx>;
 
     fn cause(&self) -> &ObligationCause<'tcx>;
@@ -108,9 +108,7 @@ where
                 && def_id.is_local()
                 && !this.infcx().next_trait_solver() =>
         {
-            this.register_obligations(
-                infcx.handle_opaque_type(a, b, this.cause(), this.param_env())?.obligations,
-            );
+            this.register_goals(infcx.handle_opaque_type(a, b, this.span(), this.param_env())?);
             Ok(a)
         }
 
diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs
index 28dbaa94f95..e9d300d349c 100644
--- a/compiler/rustc_infer/src/infer/relate/lub.rs
+++ b/compiler/rustc_infer/src/infer/relate/lub.rs
@@ -1,12 +1,13 @@
 //! Least upper bound. See [`lattice`].
 
-use super::combine::{CombineFields, ObligationEmittingRelation};
+use super::combine::{CombineFields, PredicateEmittingRelation};
 use super::lattice::{self, LatticeDir};
 use super::StructurallyRelateAliases;
 use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
-use crate::traits::{ObligationCause, PredicateObligations};
+use crate::traits::ObligationCause;
 
-use super::{Relate, RelateResult, TypeRelation};
+use rustc_middle::traits::solve::Goal;
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::Span;
 
@@ -127,7 +128,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
     }
 }
 
-impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
+impl<'tcx> PredicateEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
     fn span(&self) -> Span {
         self.fields.trace.span()
     }
@@ -147,11 +148,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
         self.fields.register_predicates(obligations);
     }
 
-    fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
+    fn register_goals(
+        &mut self,
+        obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+    ) {
         self.fields.register_obligations(obligations)
     }
 
-    fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
+    fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
         self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
             a.into(),
             b.into(),
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
index 627c527cba1..e7b50479b85 100644
--- a/compiler/rustc_infer/src/infer/relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -6,7 +6,7 @@ pub use rustc_middle::ty::relate::*;
 
 pub use self::_match::MatchAgainstFreshVars;
 pub use self::combine::CombineFields;
-pub use self::combine::ObligationEmittingRelation;
+pub use self::combine::PredicateEmittingRelation;
 
 pub mod _match;
 pub(super) mod combine;
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index fd0bc9f44f7..f7b2f11e3d7 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -1,11 +1,10 @@
 use super::combine::CombineFields;
+use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
 use crate::infer::BoundRegionConversionTime::HigherRankedType;
 use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
-use crate::traits::{Obligation, PredicateObligations};
-
-use super::{
-    relate_args_invariantly, relate_args_with_variances, ObligationEmittingRelation, Relate,
-    RelateResult, StructurallyRelateAliases, TypeRelation,
+use rustc_middle::traits::solve::Goal;
+use rustc_middle::ty::relate::{
+    relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation,
 };
 use rustc_middle::ty::TyVar;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -88,9 +87,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
                     ty::Covariant => {
                         // can't make progress on `A <: B` if both A and B are
                         // type variables, so record an obligation.
-                        self.fields.obligations.push(Obligation::new(
+                        self.fields.goals.push(Goal::new(
                             self.tcx(),
-                            self.fields.trace.cause.clone(),
                             self.fields.param_env,
                             ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
                                 a_is_expected: true,
@@ -102,9 +100,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
                     ty::Contravariant => {
                         // can't make progress on `B <: A` if both A and B are
                         // type variables, so record an obligation.
-                        self.fields.obligations.push(Obligation::new(
+                        self.fields.goals.push(Goal::new(
                             self.tcx(),
-                            self.fields.trace.cause.clone(),
                             self.fields.param_env,
                             ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
                                 a_is_expected: false,
@@ -153,11 +150,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
                     && def_id.is_local()
                     && !infcx.next_trait_solver() =>
             {
-                self.fields.obligations.extend(
-                    infcx
-                        .handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())?
-                        .obligations,
-                );
+                self.fields.goals.extend(infcx.handle_opaque_type(
+                    a,
+                    b,
+                    self.fields.trace.cause.span,
+                    self.param_env(),
+                )?);
             }
 
             _ => {
@@ -298,7 +296,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
     }
 }
 
-impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
+impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
     fn span(&self) -> Span {
         self.fields.trace.span()
     }
@@ -318,11 +316,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
         self.fields.register_predicates(obligations);
     }
 
-    fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
+    fn register_goals(
+        &mut self,
+        obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+    ) {
         self.fields.register_obligations(obligations);
     }
 
-    fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
+    fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
         self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
             ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
                 a.into(),
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index ca6c6570e07..556b3bd063d 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -114,8 +114,6 @@ impl<'tcx> PolyTraitObligation<'tcx> {
 #[cfg(target_pointer_width = "64")]
 rustc_data_structures::static_assert_size!(PredicateObligation<'_>, 48);
 
-pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
-
 pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;
 
 /// A callback that can be provided to `inspect_typeck`. Invoked on evaluation
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index b522022c206..43013a01069 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -961,15 +961,15 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
         param_env: ty::ParamEnv<'tcx>,
         hidden_ty: Ty<'tcx>,
     ) -> Result<(), NoSolution> {
-        let mut obligations = Vec::new();
+        let mut goals = Vec::new();
         self.infcx.insert_hidden_type(
             opaque_type_key,
-            &ObligationCause::dummy(),
+            DUMMY_SP,
             param_env,
             hidden_ty,
-            &mut obligations,
+            &mut goals,
         )?;
-        self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
+        self.add_goals(GoalSource::Misc, goals);
         Ok(())
     }
 
@@ -980,16 +980,15 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
         param_env: ty::ParamEnv<'tcx>,
         hidden_ty: Ty<'tcx>,
     ) {
-        let mut obligations = Vec::new();
+        let mut goals = Vec::new();
         self.infcx.add_item_bounds_for_hidden_type(
             opaque_def_id,
             opaque_args,
-            ObligationCause::dummy(),
             param_env,
             hidden_ty,
-            &mut obligations,
+            &mut goals,
         );
-        self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
+        self.add_goals(GoalSource::Misc, goals);
     }
 
     // Do something for each opaque/hidden pair defined with `def_id` in the
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 1ef2f26cd09..fc5c71252e1 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -12,9 +12,7 @@ use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::NormalizeExt;
 use crate::traits::SkipLeakCheck;
 use crate::traits::{util, FulfillmentErrorCode};
-use crate::traits::{
-    Obligation, ObligationCause, PredicateObligation, PredicateObligations, SelectionContext,
-};
+use crate::traits::{Obligation, ObligationCause, PredicateObligation, SelectionContext};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{Diag, EmissionGuarantee};
 use rustc_hir::def::DefKind;
@@ -305,7 +303,7 @@ fn equate_impl_headers<'tcx>(
     param_env: ty::ParamEnv<'tcx>,
     impl1: &ty::ImplHeader<'tcx>,
     impl2: &ty::ImplHeader<'tcx>,
-) -> Option<PredicateObligations<'tcx>> {
+) -> Option<Vec<PredicateObligation<'tcx>>> {
     let result =
         match (impl1.trait_ref, impl2.trait_ref) {
             (Some(impl1_ref), Some(impl2_ref)) => infcx
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index ae4cdb9258e..c1b1bfd300b 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
@@ -5,7 +5,7 @@ use crate::infer::{InferCtxt, InferOk};
 use crate::traits::{ObligationCause, ObligationCtxt};
 use rustc_errors::ErrorGuaranteed;
 use rustc_infer::infer::canonical::Certainty;
-use rustc_infer::traits::PredicateObligations;
+use rustc_infer::traits::PredicateObligation;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
@@ -103,7 +103,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
         (
             Self::QueryResponse,
             Option<Canonical<'tcx, ParamEnvAnd<'tcx, Self>>>,
-            PredicateObligations<'tcx>,
+            Vec<PredicateObligation<'tcx>>,
             Certainty,
         ),
         NoSolution,