about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-10-10 05:40:56 -0400
committerMichael Goulet <michael@errs.io>2024-10-10 06:07:52 -0400
commit8715bfbf0ef398780451e9f45d036cf8353b1e60 (patch)
tree186ffa99d02fe5d7ff703d26d98bf06122bb75c1
parenta4cd2202ef10e217e2905ba905dd5536958528ab (diff)
downloadrust-8715bfbf0ef398780451e9f45d036cf8353b1e60.tar.gz
rust-8715bfbf0ef398780451e9f45d036cf8353b1e60.zip
Make super combine into fns
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs8
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs8
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs8
-rw-r--r--compiler/rustc_type_ir/src/relate/combine.rs365
-rw-r--r--compiler/rustc_type_ir/src/relate/solver_relating.rs6
5 files changed, 193 insertions, 202 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index e72c21e8fad..cfc14d146bd 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -11,7 +11,7 @@ use rustc_middle::span_bug;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::fold::FnMutDelegate;
-use rustc_middle::ty::relate::combine::InferCtxtCombineExt;
+use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
@@ -363,7 +363,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
                 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
                 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
             ) if a_def_id == b_def_id || infcx.next_trait_solver() => {
-                infcx.super_combine_tys(self, a, b).map(|_| ()).or_else(|err| {
+                super_combine_tys(&infcx.infcx, self, a, b).map(|_| ()).or_else(|err| {
                     // This behavior is only there for the old solver, the new solver
                     // shouldn't ever fail. Instead, it unconditionally emits an
                     // alias-relate goal.
@@ -386,7 +386,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
                 debug!(?a, ?b, ?self.ambient_variance);
 
                 // Will also handle unification of `IntVar` and `FloatVar`.
-                self.type_checker.infcx.super_combine_tys(self, a, b)?;
+                super_combine_tys(&self.type_checker.infcx.infcx, self, a, b)?;
             }
         }
 
@@ -423,7 +423,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
         assert!(!a.has_non_region_infer(), "unexpected inference var {:?}", a);
         assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b);
 
-        self.type_checker.infcx.super_combine_consts(self, a, b)
+        super_combine_consts(&self.type_checker.infcx.infcx, self, a, b)
     }
 
     #[instrument(skip(self), level = "trace")]
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index fc208a08471..7eb61abfbc1 100644
--- a/compiler/rustc_infer/src/infer/relate/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -18,7 +18,7 @@
 //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order)
 
 use rustc_middle::traits::solve::Goal;
-use rustc_middle::ty::relate::combine::InferCtxtCombineExt;
+use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, Ty, TyCtxt, TyVar, TypeVisitableExt};
 use rustc_span::Span;
@@ -149,7 +149,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
             (
                 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
                 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
-            ) if a_def_id == b_def_id => infcx.super_combine_tys(self, a, b),
+            ) if a_def_id == b_def_id => super_combine_tys(infcx, self, a, b),
 
             (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
             | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
@@ -164,7 +164,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
                 Ok(a)
             }
 
-            _ => infcx.super_combine_tys(self, a, b),
+            _ => super_combine_tys(infcx, self, a, b),
         }
     }
 
@@ -192,7 +192,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
         a: ty::Const<'tcx>,
         b: ty::Const<'tcx>,
     ) -> RelateResult<'tcx, ty::Const<'tcx>> {
-        self.infcx.super_combine_consts(self, a, b)
+        super_combine_consts(self.infcx, self, a, b)
     }
 
     fn binders<T>(
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index 1cc968ca275..35103c070c2 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -1,5 +1,5 @@
 use rustc_middle::traits::solve::Goal;
-use rustc_middle::ty::relate::combine::InferCtxtCombineExt;
+use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
 use rustc_middle::ty::relate::{
     Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances,
 };
@@ -186,7 +186,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
                 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
                 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
             ) if a_def_id == b_def_id => {
-                infcx.super_combine_tys(self, a, b)?;
+                super_combine_tys(infcx, self, a, b)?;
             }
 
             (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
@@ -202,7 +202,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
             }
 
             _ => {
-                infcx.super_combine_tys(self, a, b)?;
+                super_combine_tys(infcx, self, a, b)?;
             }
         }
 
@@ -257,7 +257,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
         a: ty::Const<'tcx>,
         b: ty::Const<'tcx>,
     ) -> RelateResult<'tcx, ty::Const<'tcx>> {
-        self.infcx.super_combine_consts(self, a, b)
+        super_combine_consts(self.infcx, self, a, b)
     }
 
     fn binders<T>(
diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs
index 9dfcde609c7..60a953801a4 100644
--- a/compiler/rustc_type_ir/src/relate/combine.rs
+++ b/compiler/rustc_type_ir/src/relate/combine.rs
@@ -39,217 +39,208 @@ where
     fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty);
 }
 
-pub trait InferCtxtCombineExt<I: Interner>: InferCtxtLike {
-    fn super_combine_tys<R>(&self, relation: &mut R, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty>
-    where
-        R: PredicateEmittingRelation<Self>;
-
-    fn super_combine_consts<R>(
-        &self,
-        relation: &mut R,
-        a: I::Const,
-        b: I::Const,
-    ) -> RelateResult<I, I::Const>
-    where
-        R: PredicateEmittingRelation<Self>;
-}
-
-impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for Infcx {
-    fn super_combine_tys<R>(&self, relation: &mut R, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty>
-    where
-        R: PredicateEmittingRelation<Infcx>,
-    {
-        debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
-        debug_assert!(!a.has_escaping_bound_vars());
-        debug_assert!(!b.has_escaping_bound_vars());
-
-        match (a.kind(), b.kind()) {
-            (ty::Error(e), _) | (_, ty::Error(e)) => {
-                self.set_tainted_by_errors(e);
-                return Ok(Ty::new_error(self.cx(), e));
-            }
+pub fn super_combine_tys<Infcx, I, R>(
+    infcx: &Infcx,
+    relation: &mut R,
+    a: I::Ty,
+    b: I::Ty,
+) -> RelateResult<I, I::Ty>
+where
+    Infcx: InferCtxtLike<Interner = I>,
+    I: Interner,
+    R: PredicateEmittingRelation<Infcx>,
+{
+    debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
+    debug_assert!(!a.has_escaping_bound_vars());
+    debug_assert!(!b.has_escaping_bound_vars());
+
+    match (a.kind(), b.kind()) {
+        (ty::Error(e), _) | (_, ty::Error(e)) => {
+            infcx.set_tainted_by_errors(e);
+            return Ok(Ty::new_error(infcx.cx(), e));
+        }
 
-            // Relate integral variables to other types
-            (ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) => {
-                self.equate_int_vids_raw(a_id, b_id);
-                Ok(a)
-            }
-            (ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => {
-                self.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
-                Ok(b)
-            }
-            (ty::Int(v), ty::Infer(ty::IntVar(v_id))) => {
-                self.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
-                Ok(a)
-            }
-            (ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => {
-                self.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
-                Ok(b)
-            }
-            (ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => {
-                self.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
-                Ok(a)
-            }
+        // Relate integral variables to other types
+        (ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) => {
+            infcx.equate_int_vids_raw(a_id, b_id);
+            Ok(a)
+        }
+        (ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => {
+            infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
+            Ok(b)
+        }
+        (ty::Int(v), ty::Infer(ty::IntVar(v_id))) => {
+            infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
+            Ok(a)
+        }
+        (ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => {
+            infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
+            Ok(b)
+        }
+        (ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => {
+            infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
+            Ok(a)
+        }
 
-            // Relate floating-point variables to other types
-            (ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id))) => {
-                self.equate_float_vids_raw(a_id, b_id);
-                Ok(a)
-            }
-            (ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => {
-                self.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
-                Ok(b)
-            }
-            (ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => {
-                self.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
-                Ok(a)
-            }
+        // Relate floating-point variables to other types
+        (ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id))) => {
+            infcx.equate_float_vids_raw(a_id, b_id);
+            Ok(a)
+        }
+        (ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => {
+            infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
+            Ok(b)
+        }
+        (ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => {
+            infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
+            Ok(a)
+        }
 
-            // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
-            (ty::Alias(..), ty::Infer(ty::TyVar(_))) | (ty::Infer(ty::TyVar(_)), ty::Alias(..))
-                if self.next_trait_solver() =>
-            {
-                panic!(
-                    "We do not expect to encounter `TyVar` this late in combine \
+        // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
+        (ty::Alias(..), ty::Infer(ty::TyVar(_))) | (ty::Infer(ty::TyVar(_)), ty::Alias(..))
+            if infcx.next_trait_solver() =>
+        {
+            panic!(
+                "We do not expect to encounter `TyVar` this late in combine \
                     -- they should have been handled earlier"
-                )
-            }
-            (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)))
-            | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _)
-                if self.next_trait_solver() =>
-            {
-                panic!("We do not expect to encounter `Fresh` variables in the new solver")
-            }
+            )
+        }
+        (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)))
+        | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _)
+            if infcx.next_trait_solver() =>
+        {
+            panic!("We do not expect to encounter `Fresh` variables in the new solver")
+        }
 
-            (_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
-                match relation.structurally_relate_aliases() {
-                    StructurallyRelateAliases::Yes => structurally_relate_tys(relation, a, b),
-                    StructurallyRelateAliases::No => {
-                        relation.register_alias_relate_predicate(a, b);
-                        Ok(a)
-                    }
+        (_, ty::Alias(..)) | (ty::Alias(..), _) if infcx.next_trait_solver() => {
+            match relation.structurally_relate_aliases() {
+                StructurallyRelateAliases::Yes => structurally_relate_tys(relation, a, b),
+                StructurallyRelateAliases::No => {
+                    relation.register_alias_relate_predicate(a, b);
+                    Ok(a)
                 }
             }
+        }
 
-            // All other cases of inference are errors
-            (ty::Infer(_), _) | (_, ty::Infer(_)) => {
-                Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
-            }
+        // All other cases of inference are errors
+        (ty::Infer(_), _) | (_, ty::Infer(_)) => {
+            Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
+        }
 
-            (ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => {
-                match self.solver_mode() {
-                    SolverMode::Normal => {
-                        assert!(!self.next_trait_solver());
-                        structurally_relate_tys(relation, a, b)
-                    }
-                    // During coherence, opaque types should be treated as *possibly*
-                    // equal to any other type (except for possibly itself). This is an
-                    // extremely heavy hammer, but can be relaxed in a forwards-compatible
-                    // way later.
-                    SolverMode::Coherence => {
-                        relation
-                            .register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
-                        Ok(a)
-                    }
+        (ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => {
+            match infcx.solver_mode() {
+                SolverMode::Normal => {
+                    assert!(!infcx.next_trait_solver());
+                    structurally_relate_tys(relation, a, b)
+                }
+                // During coherence, opaque types should be treated as *possibly*
+                // equal to any other type (except for possibly itinfcx). This is an
+                // extremely heavy hammer, but can be relaxed in a forwards-compatible
+                // way later.
+                SolverMode::Coherence => {
+                    relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
+                    Ok(a)
                 }
             }
-
-            _ => structurally_relate_tys(relation, a, b),
         }
+
+        _ => structurally_relate_tys(relation, a, b),
     }
+}
 
-    fn super_combine_consts<R>(
-        &self,
-        relation: &mut R,
-        a: I::Const,
-        b: I::Const,
-    ) -> RelateResult<I, I::Const>
-    where
-        R: PredicateEmittingRelation<Infcx>,
-    {
-        debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
-        debug_assert!(!a.has_escaping_bound_vars());
-        debug_assert!(!b.has_escaping_bound_vars());
-
-        if a == b {
-            return Ok(a);
-        }
-
-        let a = self.shallow_resolve_const(a);
-        let b = self.shallow_resolve_const(b);
-
-        match (a.kind(), b.kind()) {
-            (
-                ty::ConstKind::Infer(ty::InferConst::Var(a_vid)),
-                ty::ConstKind::Infer(ty::InferConst::Var(b_vid)),
-            ) => {
-                self.equate_const_vids_raw(a_vid, b_vid);
-                Ok(a)
-            }
+pub fn super_combine_consts<Infcx, I, R>(
+    infcx: &Infcx,
+    relation: &mut R,
+    a: I::Const,
+    b: I::Const,
+) -> RelateResult<I, I::Const>
+where
+    Infcx: InferCtxtLike<Interner = I>,
+    I: Interner,
+    R: PredicateEmittingRelation<Infcx>,
+{
+    debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
+    debug_assert!(!a.has_escaping_bound_vars());
+    debug_assert!(!b.has_escaping_bound_vars());
 
-            (
-                ty::ConstKind::Infer(ty::InferConst::EffectVar(a_vid)),
-                ty::ConstKind::Infer(ty::InferConst::EffectVar(b_vid)),
-            ) => {
-                self.equate_effect_vids_raw(a_vid, b_vid);
-                Ok(a)
-            }
+    if a == b {
+        return Ok(a);
+    }
+
+    let a = infcx.shallow_resolve_const(a);
+    let b = infcx.shallow_resolve_const(b);
 
-            // All other cases of inference with other variables are errors.
-            (
-                ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)),
-                ty::ConstKind::Infer(_),
+    match (a.kind(), b.kind()) {
+        (
+            ty::ConstKind::Infer(ty::InferConst::Var(a_vid)),
+            ty::ConstKind::Infer(ty::InferConst::Var(b_vid)),
+        ) => {
+            infcx.equate_const_vids_raw(a_vid, b_vid);
+            Ok(a)
+        }
+
+        (
+            ty::ConstKind::Infer(ty::InferConst::EffectVar(a_vid)),
+            ty::ConstKind::Infer(ty::InferConst::EffectVar(b_vid)),
+        ) => {
+            infcx.equate_effect_vids_raw(a_vid, b_vid);
+            Ok(a)
+        }
+
+        // All other cases of inference with other variables are errors.
+        (
+            ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)),
+            ty::ConstKind::Infer(_),
+        )
+        | (
+            ty::ConstKind::Infer(_),
+            ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)),
+        ) => {
+            panic!(
+                "tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var): {a:?} and {b:?}"
             )
-            | (
-                ty::ConstKind::Infer(_),
-                ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)),
-            ) => {
-                panic!(
-                    "tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var): {a:?} and {b:?}"
-                )
-            }
+        }
 
-            (ty::ConstKind::Infer(ty::InferConst::Var(vid)), _) => {
-                self.instantiate_const_var_raw(relation, true, vid, b)?;
-                Ok(b)
-            }
+        (ty::ConstKind::Infer(ty::InferConst::Var(vid)), _) => {
+            infcx.instantiate_const_var_raw(relation, true, vid, b)?;
+            Ok(b)
+        }
 
-            (_, ty::ConstKind::Infer(ty::InferConst::Var(vid))) => {
-                self.instantiate_const_var_raw(relation, false, vid, a)?;
-                Ok(a)
-            }
+        (_, ty::ConstKind::Infer(ty::InferConst::Var(vid))) => {
+            infcx.instantiate_const_var_raw(relation, false, vid, a)?;
+            Ok(a)
+        }
 
-            (ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)), _) => {
-                self.instantiate_effect_var_raw(vid, b);
-                Ok(b)
-            }
+        (ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)), _) => {
+            infcx.instantiate_effect_var_raw(vid, b);
+            Ok(b)
+        }
 
-            (_, ty::ConstKind::Infer(ty::InferConst::EffectVar(vid))) => {
-                self.instantiate_effect_var_raw(vid, a);
-                Ok(a)
-            }
+        (_, ty::ConstKind::Infer(ty::InferConst::EffectVar(vid))) => {
+            infcx.instantiate_effect_var_raw(vid, a);
+            Ok(a)
+        }
 
-            (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
-                if self.cx().features().generic_const_exprs() || self.next_trait_solver() =>
-            {
-                match relation.structurally_relate_aliases() {
-                    StructurallyRelateAliases::No => {
-                        relation.register_predicates([if self.next_trait_solver() {
-                            ty::PredicateKind::AliasRelate(
-                                a.into(),
-                                b.into(),
-                                ty::AliasRelationDirection::Equate,
-                            )
-                        } else {
-                            ty::PredicateKind::ConstEquate(a, b)
-                        }]);
-
-                        Ok(b)
-                    }
-                    StructurallyRelateAliases::Yes => structurally_relate_consts(relation, a, b),
+        (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
+            if infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver() =>
+        {
+            match relation.structurally_relate_aliases() {
+                StructurallyRelateAliases::No => {
+                    relation.register_predicates([if infcx.next_trait_solver() {
+                        ty::PredicateKind::AliasRelate(
+                            a.into(),
+                            b.into(),
+                            ty::AliasRelationDirection::Equate,
+                        )
+                    } else {
+                        ty::PredicateKind::ConstEquate(a, b)
+                    }]);
+
+                    Ok(b)
                 }
+                StructurallyRelateAliases::Yes => structurally_relate_consts(relation, a, b),
             }
-            _ => structurally_relate_consts(relation, a, b),
         }
+        _ => structurally_relate_consts(relation, a, b),
     }
 }
diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs
index edbfaed9709..ad10ad5af9c 100644
--- a/compiler/rustc_type_ir/src/relate/solver_relating.rs
+++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs
@@ -3,7 +3,7 @@ use rustc_type_ir::solve::Goal;
 use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
 use tracing::{debug, instrument};
 
-use self::combine::{InferCtxtCombineExt, PredicateEmittingRelation};
+use self::combine::{PredicateEmittingRelation, super_combine_consts, super_combine_tys};
 use crate::data_structures::DelayedSet;
 
 pub trait RelateExt: InferCtxtLike {
@@ -228,7 +228,7 @@ where
             }
 
             _ => {
-                self.infcx.super_combine_tys(self, a, b)?;
+                super_combine_tys(self.infcx, self, a, b)?;
             }
         }
 
@@ -255,7 +255,7 @@ where
 
     #[instrument(skip(self), level = "trace")]
     fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult<I, I::Const> {
-        self.infcx.super_combine_consts(self, a, b)
+        super_combine_consts(self.infcx, self, a, b)
     }
 
     fn binders<T>(