Add a normalize_ty callback to try_evaluate_const
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 071c62d..98d0cd3 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -326,7 +326,9 @@ fn evaluate_const(
     ) -> Option<ty::Const<'tcx>> {
         let ct = ty::Const::new_alias(self.tcx, ty::IsRigid::No, alias_const);
 
-        match crate::traits::try_evaluate_const(&self.0, ct, param_env) {
+        match crate::traits::try_evaluate_const(&self.0, ct, param_env, |ty| {
+            Ok::<_, !>(ty.skip_norm_wip())
+        }) {
             Ok(ct) => Some(ct),
             Err(EvaluateConstErr::EvaluationFailure(e)) => Some(ty::Const::new_error(self.tcx, e)),
             Err(
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index c885406..798bca8 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -853,8 +853,12 @@ fn evaluate_nested_obligations(
                 ty::PredicateKind::ConstEquate(c1, c2) => {
                     let evaluate = |c: ty::Const<'tcx>| {
                         if let ty::ConstKind::Alias(_, alias_const) = c.kind() {
-                            let ct =
-                                super::try_evaluate_const(selcx.infcx, c, obligation.param_env);
+                            let ct = super::try_evaluate_const(
+                                selcx.infcx,
+                                c,
+                                obligation.param_env,
+                                |ty| Ok::<_, !>(ty.skip_norm_wip()),
+                            );
 
                             if let Err(EvaluateConstErr::InvalidConstParamTy(_)) = ct {
                                 let span = alias_const.kind.def_span(self.tcx);
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 74413d4..2a1cb4c 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -67,7 +67,9 @@ pub fn is_const_evaluatable<'tcx>(
                 tcx.dcx().span_bug(span, "evaluating `ConstKind::Expr` is not currently supported");
             }
             ty::ConstKind::Alias(_, _) => {
-                match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env) {
+                match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env, |ty| {
+                    Ok::<_, !>(ty.skip_norm_wip())
+                }) {
                     Err(EvaluateConstErr::HasGenericsOrInfers) => {
                         Err(NotConstEvaluatable::Error(infcx.dcx().span_delayed_bug(
                             span,
@@ -98,7 +100,9 @@ pub fn is_const_evaluatable<'tcx>(
             _ => bug!("unexpected constkind in `is_const_evalautable: {unexpanded_ct:?}`"),
         };
 
-        match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env) {
+        match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env, |ty| {
+            Ok::<_, !>(ty.skip_norm_wip())
+        }) {
             // If we're evaluating a generic foreign constant, under a nightly compiler while
             // the current crate does not enable `feature(generic_const_exprs)`, abort
             // compilation with a useful error.
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index d045205..941d80d 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -764,6 +764,7 @@ fn process_obligation(
                                 self.selcx.infcx,
                                 c,
                                 obligation.param_env,
+                                |ty| Ok::<_, !>(ty.skip_norm_wip()),
                             ) {
                                 Ok(val) => Ok(val),
                                 e @ Err(EvaluateConstErr::HasGenericsOrInfers) => {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index eda63e0..8b9b21b 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -572,8 +572,7 @@ fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
     ty::ParamEnv::new(tcx.mk_clauses(&clauses))
 }
 
-#[derive(Debug)]
-pub enum EvaluateConstErr {
+pub enum EvaluateConstErr<E> {
     /// The constant being evaluated was either a generic parameter or inference variable, *or*,
     /// some alias const with either generic parameters or inference variables in its
     /// generic arguments.
@@ -585,6 +584,18 @@ pub enum EvaluateConstErr {
     /// CTFE failed to evaluate the constant in some unrecoverable way (e.g. encountered a `panic!`).
     /// This is also used when the constant was already tainted by error.
     EvaluationFailure(ErrorGuaranteed),
+    FailedNormalization(E),
+}
+
+impl<E> std::fmt::Debug for EvaluateConstErr<E> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::HasGenericsOrInfers => f.write_str("HasGenericsOrInfers"),
+            Self::InvalidConstParamTy(e) => f.debug_tuple("InvalidConstParamTy").field(e).finish(),
+            Self::EvaluationFailure(e) => f.debug_tuple("EvaluationFailure").field(e).finish(),
+            Self::FailedNormalization(_) => f.write_str("FailedNormalization(..)"),
+        }
+    }
 }
 
 // FIXME(BoxyUwU): Private this once we `generic_const_exprs` isn't doing its own normalization routine
@@ -601,7 +612,7 @@ pub fn evaluate_const<'tcx>(
     ct: ty::Const<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 ) -> ty::Const<'tcx> {
-    match try_evaluate_const(infcx, ct, param_env) {
+    match try_evaluate_const(infcx, ct, param_env, |v| Ok::<_, !>(v.skip_norm_wip())) {
         Ok(ct) => ct,
         Err(EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e)) => {
             ty::Const::new_error(infcx.tcx, e)
@@ -618,12 +629,13 @@ pub fn evaluate_const<'tcx>(
 ///
 /// You should not call this function unless you are implementing normalization itself. Prefer to use
 /// `normalize_erasing_regions` or the `normalize` functions on `ObligationCtxt`/`FnCtxt`/`InferCtxt`.
-#[instrument(level = "debug", skip(infcx), ret)]
-pub fn try_evaluate_const<'tcx>(
+#[instrument(level = "debug", skip(infcx, normalize_ty), ret)]
+pub fn try_evaluate_const<'tcx, E>(
     infcx: &InferCtxt<'tcx>,
     ct: ty::Const<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-) -> Result<ty::Const<'tcx>, EvaluateConstErr> {
+    normalize_ty: impl FnOnce(Unnormalized<'tcx, Ty<'tcx>>) -> Result<Ty<'tcx>, E>,
+) -> Result<ty::Const<'tcx>, EvaluateConstErr<E>> {
     let tcx = infcx.tcx;
     let ct = infcx.resolve_vars_if_possible(ct);
     debug!(?ct);
@@ -762,7 +774,9 @@ pub fn try_evaluate_const<'tcx>(
             let span = alias_const.kind.def_span(tcx);
             match tcx.const_eval_resolve_for_typeck(typing_env, erased_alias_const, span) {
                 Ok(Ok(val)) => {
-                    Ok(ty::Const::new_value(tcx, val, alias_const.type_of(tcx).skip_norm_wip()))
+                    let ty = normalize_ty(alias_const.type_of(tcx))
+                        .map_err(EvaluateConstErr::FailedNormalization)?;
+                    Ok(ty::Const::new_value(tcx, val, ty))
                 }
                 Ok(Err(_)) => {
                     let e = tcx.dcx().delayed_bug(
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 9b4ee13..038b0ae 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -921,8 +921,12 @@ fn evaluate_predicate_recursively<'o>(
 
                 let evaluate = |c: ty::Const<'tcx>| {
                     if let ty::ConstKind::Alias(_, _) = c.kind() {
-                        match crate::traits::try_evaluate_const(self.infcx, c, obligation.param_env)
-                        {
+                        match crate::traits::try_evaluate_const(
+                            self.infcx,
+                            c,
+                            obligation.param_env,
+                            |v| Ok::<_, !>(v.skip_norm_wip()),
+                        ) {
                             Ok(val) => Ok(val),
                             Err(e) => Err(e),
                         }