about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs25
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs71
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_middle/src/query/erase.rs1
-rw-r--r--compiler/rustc_middle/src/query/mod.rs5
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs15
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs139
-rw-r--r--tests/crashes/133199.rs11
-rw-r--r--tests/crashes/136894.rs8
-rw-r--r--tests/crashes/137813.rs18
-rw-r--r--tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs24
-rw-r--r--tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.stderr17
-rw-r--r--tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs26
-rw-r--r--tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr39
-rw-r--r--tests/ui/const-generics/generic_const_exprs/auxiliary/cross-crate-2.rs (renamed from tests/crashes/auxiliary/aux133199.rs)4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/cross-crate-2.rs10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr6
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr19
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.rs3
-rw-r--r--tests/ui/const-generics/generic_const_exprs/different-fn.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/serializing_error_guaranteed.rs16
-rw-r--r--tests/ui/const-generics/issues/issue-71202.rs4
-rw-r--r--tests/ui/const-generics/issues/issue-71202.stderr46
-rw-r--r--tests/ui/const-generics/issues/issue-83765.rs16
-rw-r--r--tests/ui/const-generics/issues/issue-83765.stderr174
-rw-r--r--tests/ui/pattern/unused-parameters-const-pattern.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/in-where-clause.stderr5
31 files changed, 546 insertions, 189 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 350bdc7821d..f5206d9a015 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -88,6 +88,7 @@ pub(crate) fn provide(providers: &mut Providers) {
         opaque_ty_origin,
         rendered_precise_capturing_args,
         const_param_default,
+        anon_const_kind,
         ..*providers
     };
 }
@@ -1826,3 +1827,27 @@ fn const_param_default<'tcx>(
         .lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args));
     ty::EarlyBinder::bind(ct)
 }
+
+fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKind {
+    let hir_id = tcx.local_def_id_to_hir_id(def);
+    let const_arg_id = tcx.parent_hir_id(hir_id);
+    match tcx.hir_node(const_arg_id) {
+        hir::Node::ConstArg(_) => {
+            if tcx.features().generic_const_exprs() {
+                ty::AnonConstKind::GCE
+            } else if tcx.features().min_generic_const_args() {
+                ty::AnonConstKind::MCG
+            } else if let hir::Node::Expr(hir::Expr {
+                kind: hir::ExprKind::Repeat(_, repeat_count),
+                ..
+            }) = tcx.hir_node(tcx.parent_hir_id(const_arg_id))
+                && repeat_count.hir_id == const_arg_id
+            {
+                ty::AnonConstKind::RepeatExprCount
+            } else {
+                ty::AnonConstKind::MCG
+            }
+        }
+        _ => ty::AnonConstKind::NonTypeSystem,
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 2bed28d7b71..7eb896f0bf1 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -104,19 +104,27 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                 }
             }
 
-            if in_param_ty {
-                // We do not allow generic parameters in anon consts if we are inside
-                // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
-                None
-            } else if tcx.features().generic_const_exprs() {
-                let parent_node = tcx.parent_hir_node(hir_id);
-                debug!(?parent_node);
-                if let Node::Variant(Variant { disr_expr: Some(constant), .. }) = parent_node
-                    && constant.hir_id == hir_id
-                {
-                    // enum variant discriminants are not allowed to use any kind of generics
-                    None
-                } else if let Some(param_id) = tcx.hir_opt_const_param_default_param_def_id(hir_id)
+            match tcx.anon_const_kind(def_id) {
+                // Stable: anon consts are not able to use any generic parameters...
+                ty::AnonConstKind::MCG => None,
+                // we provide generics to repeat expr counts as a backwards compatibility hack. #76200
+                ty::AnonConstKind::RepeatExprCount => Some(parent_did),
+
+                // Even GCE anon const should not be allowed to use generic parameters as it would be
+                // trivially forward declared uses once desugared. E.g. `const N: [u8; ANON::<N>]`.
+                //
+                // We could potentially mirror the hack done for defaults of generic parameters but
+                // this case just doesn't come up much compared to `const N: u32 = ...`. Long term the
+                // hack for defaulted parameters should be removed eventually anyway.
+                ty::AnonConstKind::GCE if in_param_ty => None,
+                // GCE anon consts as a default for a generic parameter should have their provided generics
+                // "truncated" up to whatever generic parameter this anon const is within the default of.
+                //
+                // FIXME(generic_const_exprs): This only handles `const N: usize = /*defid*/` but not type
+                // parameter defaults, e.g. `T = Foo</*defid*/>`.
+                ty::AnonConstKind::GCE
+                    if let Some(param_id) =
+                        tcx.hir_opt_const_param_default_param_def_id(hir_id) =>
                 {
                     // If the def_id we are calling generics_of on is an anon ct default i.e:
                     //
@@ -160,36 +168,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                         has_self: generics.has_self,
                         has_late_bound_regions: generics.has_late_bound_regions,
                     };
-                } else {
-                    // HACK(eddyb) this provides the correct generics when
-                    // `feature(generic_const_expressions)` is enabled, so that const expressions
-                    // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
-                    //
-                    // Note that we do not supply the parent generics when using
-                    // `min_const_generics`.
-                    Some(parent_did)
                 }
-            } else {
-                let parent_node = tcx.parent_hir_node(hir_id);
-                let parent_node = match parent_node {
-                    Node::ConstArg(ca) => tcx.parent_hir_node(ca.hir_id),
-                    _ => parent_node,
-                };
-                match parent_node {
-                    // HACK(eddyb) this provides the correct generics for repeat
-                    // expressions' count (i.e. `N` in `[x; N]`), and explicit
-                    // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
-                    // as they shouldn't be able to cause query cycle errors.
-                    Node::Expr(Expr { kind: ExprKind::Repeat(_, ct), .. })
-                        if ct.anon_const_hir_id() == Some(hir_id) =>
-                    {
-                        Some(parent_did)
-                    }
-                    Node::TyPat(_) => Some(parent_did),
-                    // Field default values inherit the ADT's generics.
-                    Node::Field(_) => Some(parent_did),
-                    _ => None,
+                ty::AnonConstKind::GCE => Some(parent_did),
+
+                // Field defaults are allowed to use generic parameters, e.g. `field: u32 = /*defid: N + 1*/`
+                ty::AnonConstKind::NonTypeSystem
+                    if matches!(tcx.parent_hir_node(hir_id), Node::TyPat(_) | Node::Field(_)) =>
+                {
+                    Some(parent_did)
                 }
+                // Default to no generic parameters for other kinds of anon consts
+                ty::AnonConstKind::NonTypeSystem => None,
             }
         }
         Node::ConstBlock(_)
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 97d31565733..f40a2374bea 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -425,6 +425,7 @@ provide! { tcx, def_id, other, cdata,
     doc_link_traits_in_scope => {
         tcx.arena.alloc_from_iter(cdata.get_doc_link_traits_in_scope(def_id.index))
     }
+    anon_const_kind => { table }
 }
 
 pub(in crate::rmeta) fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 7ac72ef814a..3ab989d2d3b 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1569,6 +1569,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                         <- tcx.explicit_implied_const_bounds(def_id).skip_binder());
                 }
             }
+            if let DefKind::AnonConst = def_kind {
+                record!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id));
+            }
             if tcx.impl_method_has_trait_impl_trait_tys(def_id)
                 && let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
             {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index d3d928aa88e..077835283e9 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -480,6 +480,7 @@ define_tables! {
     doc_link_traits_in_scope: Table<DefIndex, LazyArray<DefId>>,
     assumed_wf_types_for_rpitit: Table<DefIndex, LazyArray<(Ty<'static>, Span)>>,
     opaque_ty_origin: Table<DefIndex, LazyValue<hir::OpaqueTyOrigin<DefId>>>,
+    anon_const_kind: Table<DefIndex, LazyValue<ty::AnonConstKind>>,
 }
 
 #[derive(TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 2d248e028fe..6035056baaf 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -316,6 +316,7 @@ trivial! {
     rustc_middle::ty::Asyncness,
     rustc_middle::ty::AsyncDestructor,
     rustc_middle::ty::BoundVariableKind,
+    rustc_middle::ty::AnonConstKind,
     rustc_middle::ty::DeducedParamAttrs,
     rustc_middle::ty::Destructor,
     rustc_middle::ty::fast_reject::SimplifiedType,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b6218fff0c4..30245bc82d4 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2592,6 +2592,11 @@ rustc_queries! {
         desc { "estimating codegen size of `{}`", key }
         cache_on_disk_if { true }
     }
+
+    query anon_const_kind(def_id: DefId) -> ty::AnonConstKind {
+        desc { |tcx| "looking up anon const kind of `{}`", tcx.def_path_str(def_id) }
+        separate_provide_extern
+    }
 }
 
 rustc_with_all_queries! { define_callbacks! }
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index dc5fe2d8f8b..455ac660412 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use rustc_data_structures::intern::Interned;
 use rustc_error_messages::MultiSpan;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_type_ir::walk::TypeWalker;
 use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
 
@@ -259,3 +259,16 @@ impl<'tcx> Const<'tcx> {
         TypeWalker::new(self.into())
     }
 }
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable, HashStable)]
+pub enum AnonConstKind {
+    /// `feature(generic_const_exprs)` anon consts are allowed to use arbitrary generic parameters in scope
+    GCE,
+    /// stable `min_const_generics` anon consts are not allowed to use any generic parameters
+    MCG,
+    /// anon consts used as the length of a repeat expr are syntactically allowed to use generic parameters
+    /// but must not depend on the actual instantiation. See #76200 for more information
+    RepeatExprCount,
+    /// anon consts outside of the type system, e.g. enum discriminants
+    NonTypeSystem,
+}
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index b2a58897c31..f57329608ef 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -74,8 +74,8 @@ pub use self::closure::{
     place_to_string_for_capture,
 };
 pub use self::consts::{
-    Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, ValTreeKind,
-    Value,
+    AnonConstKind, Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst,
+    ValTree, ValTreeKind, Value,
 };
 pub use self::context::{
     CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt,
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index ecd6132b3ef..3858778bfc8 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -68,6 +68,7 @@ trivially_parameterized_over_tcx! {
     ty::AsyncDestructor,
     ty::AssocItemContainer,
     ty::Asyncness,
+    ty::AnonConstKind,
     ty::DeducedParamAttrs,
     ty::Destructor,
     ty::Generics,
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index f73603c0053..a9bdb909bdc 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -540,10 +540,13 @@ pub fn try_evaluate_const<'tcx>(
         | ty::ConstKind::Placeholder(_)
         | ty::ConstKind::Expr(_) => Err(EvaluateConstErr::HasGenericsOrInfers),
         ty::ConstKind::Unevaluated(uv) => {
+            let opt_anon_const_kind =
+                (tcx.def_kind(uv.def) == DefKind::AnonConst).then(|| tcx.anon_const_kind(uv.def));
+
             // Postpone evaluation of constants that depend on generic parameters or
             // inference variables.
             //
-            // We use `TypingMode::PostAnalysis`  here which is not *technically* correct
+            // We use `TypingMode::PostAnalysis` here which is not *technically* correct
             // to be revealing opaque types here as borrowcheck has not run yet. However,
             // CTFE itself uses `TypingMode::PostAnalysis` unconditionally even during
             // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
@@ -551,65 +554,95 @@ pub fn try_evaluate_const<'tcx>(
             //
             // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
             // instead of having this logic here
-            let (args, typing_env) = if tcx.features().generic_const_exprs()
-                && uv.has_non_region_infer()
-            {
-                // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
-                // inference variables and generic parameters to show up in `ty::Const` even though the anon const
-                // does not actually make use of them. We handle this case specially and attempt to evaluate anyway.
-                match tcx.thir_abstract_const(uv.def) {
-                    Ok(Some(ct)) => {
-                        let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, uv.args));
-                        if let Err(e) = ct.error_reported() {
-                            return Err(EvaluateConstErr::EvaluationFailure(e));
-                        } else if ct.has_non_region_infer() || ct.has_non_region_param() {
-                            // If the anon const *does* actually use generic parameters or inference variables from
-                            // the generic arguments provided for it, then we should *not* attempt to evaluate it.
-                            return Err(EvaluateConstErr::HasGenericsOrInfers);
-                        } else {
-                            let args = replace_param_and_infer_args_with_placeholder(tcx, uv.args);
-                            let typing_env = infcx
-                                .typing_env(tcx.erase_regions(param_env))
-                                .with_post_analysis_normalized(tcx);
-                            (args, typing_env)
+            let (args, typing_env) = match opt_anon_const_kind {
+                // We handle `generic_const_exprs` separately as reasonable ways of handling constants in the type system
+                // completely fall apart under `generic_const_exprs` and makes this whole function Really hard to reason
+                // about if you have to consider gce whatsoever.
+                Some(ty::AnonConstKind::GCE) => {
+                    if uv.has_non_region_infer() || uv.has_non_region_param() {
+                        // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
+                        // inference variables and generic parameters to show up in `ty::Const` even though the anon const
+                        // does not actually make use of them. We handle this case specially and attempt to evaluate anyway.
+                        match tcx.thir_abstract_const(uv.def) {
+                            Ok(Some(ct)) => {
+                                let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, uv.args));
+                                if let Err(e) = ct.error_reported() {
+                                    return Err(EvaluateConstErr::EvaluationFailure(e));
+                                } else if ct.has_non_region_infer() || ct.has_non_region_param() {
+                                    // If the anon const *does* actually use generic parameters or inference variables from
+                                    // the generic arguments provided for it, then we should *not* attempt to evaluate it.
+                                    return Err(EvaluateConstErr::HasGenericsOrInfers);
+                                } else {
+                                    let args =
+                                        replace_param_and_infer_args_with_placeholder(tcx, uv.args);
+                                    let typing_env = infcx
+                                        .typing_env(tcx.erase_regions(param_env))
+                                        .with_post_analysis_normalized(tcx);
+                                    (args, typing_env)
+                                }
+                            }
+                            Err(_) | Ok(None) => {
+                                let args = GenericArgs::identity_for_item(tcx, uv.def);
+                                let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
+                                (args, typing_env)
+                            }
                         }
+                    } else {
+                        let typing_env = infcx
+                            .typing_env(tcx.erase_regions(param_env))
+                            .with_post_analysis_normalized(tcx);
+                        (uv.args, typing_env)
                     }
-                    Err(_) | Ok(None) => {
-                        let args = GenericArgs::identity_for_item(tcx, uv.def);
-                        let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
-                        (args, typing_env)
+                }
+                Some(ty::AnonConstKind::RepeatExprCount) => {
+                    if uv.has_non_region_infer() {
+                        // Diagnostics will sometimes replace the identity args of anon consts in
+                        // array repeat expr counts with inference variables so we have to handle this
+                        // even though it is not something we should ever actually encounter.
+                        //
+                        // Array repeat expr counts are allowed to syntactically use generic parameters
+                        // but must not actually depend on them in order to evalaute successfully. This means
+                        // that it is actually fine to evalaute them in their own environment rather than with
+                        // the actually provided generic arguments.
+                        tcx.dcx().delayed_bug("AnonConst with infer args but no error reported");
                     }
+
+                    // The generic args of repeat expr counts under `min_const_generics` are not supposed to
+                    // affect evaluation of the constant as this would make it a "truly" generic const arg.
+                    // To prevent this we discard all the generic arguments and evalaute with identity args
+                    // and in its own environment instead of the current environment we are normalizing in.
+                    let args = GenericArgs::identity_for_item(tcx, uv.def);
+                    let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
+
+                    (args, typing_env)
+                }
+                _ => {
+                    // We are only dealing with "truly" generic/uninferred constants here:
+                    // - GCEConsts have been handled separately
+                    // - Repeat expr count back compat consts have also been handled separately
+                    // So we are free to simply defer evaluation here.
+                    //
+                    // FIXME: This assumes that `args` are normalized which is not necessarily true
+                    //
+                    // Const patterns are converted to type system constants before being
+                    // evaluated. However, we don't care about them here as pattern evaluation
+                    // logic does not go through type system normalization. If it did this would
+                    // be a backwards compatibility problem as we do not enforce "syntactic" non-
+                    // usage of generic parameters like we do here.
+                    if uv.args.has_non_region_param() || uv.args.has_non_region_infer() {
+                        return Err(EvaluateConstErr::HasGenericsOrInfers);
+                    }
+
+                    let typing_env = infcx
+                        .typing_env(tcx.erase_regions(param_env))
+                        .with_post_analysis_normalized(tcx);
+                    (uv.args, typing_env)
                 }
-            } else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
-                // FIXME: remove this when `const_evaluatable_unchecked` is a hard error.
-                //
-                // Diagnostics will sometimes replace the identity args of anon consts in
-                // array repeat expr counts with inference variables so we have to handle this
-                // even though it is not something we should ever actually encounter.
-                //
-                // Array repeat expr counts are allowed to syntactically use generic parameters
-                // but must not actually depend on them in order to evalaute successfully. This means
-                // that it is actually fine to evalaute them in their own environment rather than with
-                // the actually provided generic arguments.
-                tcx.dcx().delayed_bug(
-                    "Encountered anon const with inference variable args but no error reported",
-                );
-
-                let args = GenericArgs::identity_for_item(tcx, uv.def);
-                let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
-                (args, typing_env)
-            } else {
-                // FIXME: This codepath is reachable under `associated_const_equality` and in the
-                // future will be reachable by `min_generic_const_args`. We should handle inference
-                // variables and generic parameters properly instead of doing nothing.
-                let typing_env = infcx
-                    .typing_env(tcx.erase_regions(param_env))
-                    .with_post_analysis_normalized(tcx);
-                (uv.args, typing_env)
             };
-            let uv = ty::UnevaluatedConst::new(uv.def, args);
 
+            let uv = ty::UnevaluatedConst::new(uv.def, args);
             let erased_uv = tcx.erase_regions(uv);
+
             use rustc_middle::mir::interpret::ErrorHandled;
             match tcx.const_eval_resolve_for_typeck(typing_env, erased_uv, DUMMY_SP) {
                 Ok(Ok(val)) => Ok(ty::Const::new_value(
diff --git a/tests/crashes/133199.rs b/tests/crashes/133199.rs
deleted file mode 100644
index 76535fa83a6..00000000000
--- a/tests/crashes/133199.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ known-bug: #133199
-//@ aux-build: aux133199.rs
-
-extern crate aux133199;
-
-use aux133199::FixedBitSet;
-
-fn main() {
-    FixedBitSet::<7>::new();
-    //~^ ERROR
-}
diff --git a/tests/crashes/136894.rs b/tests/crashes/136894.rs
deleted file mode 100644
index 26bbb78717e..00000000000
--- a/tests/crashes/136894.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #136894
-#![feature(generic_const_exprs)]
-#![crate_type = "lib"]
-#![allow(incomplete_features, dead_code)]
-
-struct X<T>([(); f::<T>()]) where [(); f::<T>()]:;
-
-const fn f<T>() -> usize { panic!() }
diff --git a/tests/crashes/137813.rs b/tests/crashes/137813.rs
deleted file mode 100644
index 5d205ee5331..00000000000
--- a/tests/crashes/137813.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//@ known-bug: #137813
-trait AssocConst {
-    const A: u8;
-}
-
-impl<T> AssocConst for (T,) {
-    const A: u8 = 0;
-}
-
-trait Trait {}
-
-impl<U> Trait for () where (U,): AssocConst<A = { 0 }> {}
-
-fn foo()
-where
-    (): Trait,
-{
-}
diff --git a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs
new file mode 100644
index 00000000000..f45b7c3268b
--- /dev/null
+++ b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs
@@ -0,0 +1,24 @@
+#![feature(generic_arg_infer, associated_const_equality, generic_const_items)]
+#![expect(incomplete_features)]
+
+// Regression test for #133066 where we would try to evaluate `<() as Foo>::ASSOC<_>` even
+// though it contained inference variables, which would cause ICEs.
+
+trait Foo {
+    const ASSOC<const N: u32>: u32;
+}
+
+impl Foo for () {
+    const ASSOC<const N: u32>: u32 = N;
+}
+
+fn bar<const N: u32, T: Foo<ASSOC<N> = 10>>() {}
+
+fn main() {
+    bar::<_, ()>();
+    //~^ ERROR: type mismatch resolving `<() as Foo>::ASSOC<_> == 10`
+
+    // FIXME(mgca):
+    // FIXME(associated_const_equality):
+    // This ought to start compiling once const items are aliases rather than bodies
+}
diff --git a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.stderr b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.stderr
new file mode 100644
index 00000000000..00741c901e4
--- /dev/null
+++ b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.stderr
@@ -0,0 +1,17 @@
+error[E0271]: type mismatch resolving `<() as Foo>::ASSOC<_> == 10`
+  --> $DIR/equality_bound_with_infer.rs:18:14
+   |
+LL |     bar::<_, ()>();
+   |              ^^ expected `10`, found `<() as Foo>::ASSOC::<_>`
+   |
+   = note: expected constant `10`
+              found constant `<() as Foo>::ASSOC::<_>`
+note: required by a bound in `bar`
+  --> $DIR/equality_bound_with_infer.rs:15:29
+   |
+LL | fn bar<const N: u32, T: Foo<ASSOC<N> = 10>>() {}
+   |                             ^^^^^^^^^^^^^ required by this bound in `bar`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs
new file mode 100644
index 00000000000..99318ef7598
--- /dev/null
+++ b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs
@@ -0,0 +1,26 @@
+// regression test for #137813 where we would assume all constants in the type system
+// cannot contain inference variables, even though associated const equality syntax
+// was still lowered without the feature gate enabled.
+
+trait AssocConst {
+    const A: u8;
+}
+
+impl<T> AssocConst for (T,) {
+    const A: u8 = 0;
+}
+
+trait Trait {}
+
+impl<U> Trait for () where (U,): AssocConst<A = { 0 }> {}
+//~^ ERROR associated const equality is incomplete
+//~| ERROR the type parameter `U` is not constrained by the impl trait
+
+fn foo()
+where
+    (): Trait,
+    //~^ ERROR type mismatch resolving
+{
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr
new file mode 100644
index 00000000000..e6799ec5c3a
--- /dev/null
+++ b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr
@@ -0,0 +1,39 @@
+error[E0658]: associated const equality is incomplete
+  --> $DIR/unconstrained_impl_param.rs:15:45
+   |
+LL | impl<U> Trait for () where (U,): AssocConst<A = { 0 }> {}
+   |                                             ^^^^^^^^^
+   |
+   = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+   = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/unconstrained_impl_param.rs:15:6
+   |
+LL | impl<U> Trait for () where (U,): AssocConst<A = { 0 }> {}
+   |      ^ unconstrained type parameter
+
+error[E0271]: type mismatch resolving `<(_,) as AssocConst>::A == 0`
+  --> $DIR/unconstrained_impl_param.rs:21:5
+   |
+LL |     (): Trait,
+   |     ^^^^^^^^^ expected `0`, found `<(_,) as AssocConst>::A`
+   |
+   = note: expected constant `0`
+              found constant `<(_,) as AssocConst>::A`
+note: required for `()` to implement `Trait`
+  --> $DIR/unconstrained_impl_param.rs:15:9
+   |
+LL | impl<U> Trait for () where (U,): AssocConst<A = { 0 }> {}
+   |         ^^^^^     ^^                        --------- unsatisfied trait bound introduced here
+   = help: see issue #48214
+help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+   |
+LL + #![feature(trivial_bounds)]
+   |
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0207, E0271, E0658.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/crashes/auxiliary/aux133199.rs b/tests/ui/const-generics/generic_const_exprs/auxiliary/cross-crate-2.rs
index 40765d92fbf..a8bda14f4bd 100644
--- a/tests/crashes/auxiliary/aux133199.rs
+++ b/tests/ui/const-generics/generic_const_exprs/auxiliary/cross-crate-2.rs
@@ -1,9 +1,9 @@
 #![allow(incomplete_features)]
 #![feature(generic_const_exprs)]
 
-pub struct FixedBitSet<const N: usize>;
+pub struct Foo<const N: usize>;
 
-impl<const N: usize> FixedBitSet<N>
+impl<const N: usize> Foo<N>
 where
     [u8; N.div_ceil(8)]: Sized,
 {
diff --git a/tests/ui/const-generics/generic_const_exprs/cross-crate-2.rs b/tests/ui/const-generics/generic_const_exprs/cross-crate-2.rs
new file mode 100644
index 00000000000..77998c7ec0a
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/cross-crate-2.rs
@@ -0,0 +1,10 @@
+//@ check-pass
+//@ aux-build: cross-crate-2.rs
+
+extern crate cross_crate_2;
+
+use cross_crate_2::Foo;
+
+fn main() {
+    Foo::<7>::new();
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
index f454ff4e6c0..6b095f3818a 100644
--- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/dependence_lint.rs:14:32
+  --> $DIR/dependence_lint.rs:15:32
    |
 LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    |                                ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/dependence_lint.rs:21:37
+  --> $DIR/dependence_lint.rs:22:37
    |
 LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
    |                                     ^ cannot perform const operation using `T`
@@ -27,7 +27,7 @@ LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_
    = note: `#[warn(const_evaluatable_unchecked)]` on by default
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/dependence_lint.rs:17:9
+  --> $DIR/dependence_lint.rs:18:9
    |
 LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
index f6119c17bf4..12ac980c975 100644
--- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
@@ -9,8 +9,19 @@ help: try adding a `where` bound
 LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
    |             ++++++++++++++++++++++++++++++++
 
+error: unconstrained generic constant
+  --> $DIR/dependence_lint.rs:10:5
+   |
+LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try adding a `where` bound
+   |
+LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
+   |             ++++++++++++++++++++++++++++++++
+
 error: overly complex generic constant
-  --> $DIR/dependence_lint.rs:17:9
+  --> $DIR/dependence_lint.rs:18:9
    |
 LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
@@ -18,7 +29,7 @@ LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error w
    = help: consider moving this anonymous constant into a `const` function
 
 error: unconstrained generic constant
-  --> $DIR/dependence_lint.rs:14:12
+  --> $DIR/dependence_lint.rs:15:12
    |
 LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -29,12 +40,12 @@ LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
    |             ++++++++++++++++++++++++++++++++
 
 error: overly complex generic constant
-  --> $DIR/dependence_lint.rs:21:17
+  --> $DIR/dependence_lint.rs:22:17
    |
 LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
    |
    = help: consider moving this anonymous constant into a `const` function
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs b/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs
index 107466cd1d9..6b3c8f84be3 100644
--- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs
@@ -9,7 +9,8 @@ use std::mem::size_of;
 fn foo<T>() {
     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
     //[gce]~^ ERROR unconstrained
-    //[full]~^^ WARNING cannot use constants
+    //[gce]~| ERROR unconstrained generic constant
+    //[full]~^^^ WARNING cannot use constants
     //[full]~| WARNING this was previously accepted
     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
     //[full]~^ ERROR generic parameters may not be used
diff --git a/tests/ui/const-generics/generic_const_exprs/different-fn.stderr b/tests/ui/const-generics/generic_const_exprs/different-fn.stderr
index ac80463480d..52917df0da1 100644
--- a/tests/ui/const-generics/generic_const_exprs/different-fn.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/different-fn.stderr
@@ -2,10 +2,10 @@ error[E0308]: mismatched types
   --> $DIR/different-fn.rs:10:5
    |
 LL |     [0; size_of::<Foo<T>>()]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ expected `size_of::<T>()`, found `0`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ expected `size_of::<T>()`, found `size_of::<Foo<T>>()`
    |
    = note: expected constant `size_of::<T>()`
-              found constant `0`
+              found constant `size_of::<Foo<T>>()`
 
 error: unconstrained generic constant
   --> $DIR/different-fn.rs:10:9
diff --git a/tests/ui/const-generics/generic_const_exprs/serializing_error_guaranteed.rs b/tests/ui/const-generics/generic_const_exprs/serializing_error_guaranteed.rs
new file mode 100644
index 00000000000..83b73350f83
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/serializing_error_guaranteed.rs
@@ -0,0 +1,16 @@
+//@ check-pass
+
+// regression test for #136894.
+// I (BoxyUwU) don't know what the underlying cause was here
+
+#![feature(generic_const_exprs)]
+#![crate_type = "lib"]
+#![allow(incomplete_features, dead_code)]
+
+struct X<T>([(); f::<T>()])
+where
+    [(); f::<T>()]:;
+
+const fn f<T>() -> usize {
+    panic!()
+}
diff --git a/tests/ui/const-generics/issues/issue-71202.rs b/tests/ui/const-generics/issues/issue-71202.rs
index 0f955414d84..8ff49b55e6f 100644
--- a/tests/ui/const-generics/issues/issue-71202.rs
+++ b/tests/ui/const-generics/issues/issue-71202.rs
@@ -25,7 +25,9 @@ impl<T: Copy> DataHolder<T> {
         }
 
         <IsCopy<T>>::VALUE
-    } as usize] = []; //~ ERROR unconstrained generic constant
+    } as usize] = [];
+    //~^ ERROR unconstrained generic constant
+    //~^^ ERROR mismatched types
 }
 
 fn main() {}
diff --git a/tests/ui/const-generics/issues/issue-71202.stderr b/tests/ui/const-generics/issues/issue-71202.stderr
index cc3603d1145..b7c3db494a5 100644
--- a/tests/ui/const-generics/issues/issue-71202.stderr
+++ b/tests/ui/const-generics/issues/issue-71202.stderr
@@ -59,5 +59,49 @@ LL +         <IsCopy<T>>::VALUE
 LL ~     } as usize]: = [];
    |
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-71202.rs:28:19
+   |
+LL |     } as usize] = [];
+   |                   ^^ expected `1 - {
+        trait NotCopy {
+            const VALUE: bool = false;
+        }
+
+        impl<__Type: ?Sized> NotCopy for __Type {}
+
+        struct IsCopy<__Type: ?Sized>(PhantomData<__Type>);
+
+        impl<__Type> IsCopy<__Type>
+        where
+            __Type: Sized + Copy,
+        {
+            const VALUE: bool = true;
+        }
+
+        <IsCopy<T>>::VALUE
+    } as usize`, found `0`
+   |
+   = note: expected constant `1 - {
+                   trait NotCopy {
+                       const VALUE: bool = false;
+                   }
+           
+                   impl<__Type: ?Sized> NotCopy for __Type {}
+           
+                   struct IsCopy<__Type: ?Sized>(PhantomData<__Type>);
+           
+                   impl<__Type> IsCopy<__Type>
+                   where
+                       __Type: Sized + Copy,
+                   {
+                       const VALUE: bool = true;
+                   }
+           
+                   <IsCopy<T>>::VALUE
+               } as usize`
+              found constant `0`
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/issues/issue-83765.rs b/tests/ui/const-generics/issues/issue-83765.rs
index 0959f771c22..f31c61408e9 100644
--- a/tests/ui/const-generics/issues/issue-83765.rs
+++ b/tests/ui/const-generics/issues/issue-83765.rs
@@ -3,10 +3,6 @@
 
 trait TensorDimension {
     const DIM: usize;
-    //~^ ERROR cycle detected when resolving instance
-    //~| ERROR cycle detected when resolving instance
-    // FIXME Given the current state of the compiler its expected that we cycle here,
-    // but the cycle is still wrong.
     const ISSCALAR: bool = Self::DIM == 0;
     fn is_scalar(&self) -> bool {
         Self::ISSCALAR
@@ -49,6 +45,7 @@ impl<'a, T: Broadcastable, const DIM: usize> TensorDimension for LazyUpdim<'a, T
 
 impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T::DIM }, DIM> {
     fn size(&self) -> [usize; DIM] {
+        //~^ ERROR: method not compatible with trait
         self.size
     }
 }
@@ -56,12 +53,17 @@ impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T
 impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> {
     type Element = T::Element;
     fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
+        //~^ ERROR: method not compatible with trait
         assert!(DIM >= T::DIM);
         if !self.inbounds(index) {
+            //~^ ERROR: unconstrained generic constant
+            //~| ERROR: mismatched types
             return None;
         }
         let size = self.size();
+        //~^ ERROR: unconstrained generic constant
         let newindex: [usize; T::DIM] = Default::default();
+        //~^ ERROR: the trait bound
         self.reference.bget(newindex)
     }
 }
@@ -82,6 +84,8 @@ impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorSi
     fn size(&self) -> [usize; DIM] {
         //~^ ERROR: method not compatible with trait
         self.reference.size()
+        //~^ ERROR: unconstrained generic constant
+        //~| ERROR: mismatched types
     }
 }
 
@@ -92,6 +96,8 @@ impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> Broadcas
     fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
         //~^ ERROR: method not compatible with trait
         self.reference.bget(index).map(&self.closure)
+        //~^ ERROR: unconstrained generic constant
+        //~| ERROR: mismatched types
     }
 }
 
@@ -100,12 +106,14 @@ impl<T> TensorDimension for Vec<T> {
 }
 impl<T> TensorSize for Vec<T> {
     fn size(&self) -> [usize; 1] {
+        //~^ ERROR: method not compatible with trait
         [self.len()]
     }
 }
 impl<T: Clone> Broadcastable for Vec<T> {
     type Element = T;
     fn bget(&self, index: [usize; 1]) -> Option<T> {
+        //~^ ERROR: method not compatible with trait
         self.get(index[0]).cloned()
     }
 }
diff --git a/tests/ui/const-generics/issues/issue-83765.stderr b/tests/ui/const-generics/issues/issue-83765.stderr
index 6b62012c14f..5a06ee7ddbc 100644
--- a/tests/ui/const-generics/issues/issue-83765.stderr
+++ b/tests/ui/const-generics/issues/issue-83765.stderr
@@ -1,43 +1,23 @@
-error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`
-  --> $DIR/issue-83765.rs:5:5
-   |
-LL |     const DIM: usize;
-   |     ^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>`...
-  --> $DIR/issue-83765.rs:4:1
-   |
-LL | trait TensorDimension {
-   | ^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`, completing the cycle
-note: cycle used when checking assoc item `<impl at $DIR/issue-83765.rs:50:1: 50:94>::size` is compatible with trait definition
-  --> $DIR/issue-83765.rs:51:5
+error[E0308]: method not compatible with trait
+  --> $DIR/issue-83765.rs:47:5
    |
 LL |     fn size(&self) -> [usize; DIM] {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`
-  --> $DIR/issue-83765.rs:5:5
-   |
-LL |     const DIM: usize;
-   |     ^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>`...
-  --> $DIR/issue-83765.rs:4:1
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
    |
-LL | trait TensorDimension {
-   | ^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`, completing the cycle
-note: cycle used when checking assoc item `<impl at $DIR/issue-83765.rs:56:1: 56:97>::bget` is compatible with trait definition
-  --> $DIR/issue-83765.rs:58:5
+   = note: expected constant `Self::DIM`
+              found constant `DIM`
+
+error[E0308]: method not compatible with trait
+  --> $DIR/issue-83765.rs:55:5
    |
 LL |     fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
+   |
+   = note: expected constant `Self::DIM`
+              found constant `DIM`
 
 error[E0308]: method not compatible with trait
-  --> $DIR/issue-83765.rs:82:5
+  --> $DIR/issue-83765.rs:84:5
    |
 LL |     fn size(&self) -> [usize; DIM] {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
@@ -46,7 +26,7 @@ LL |     fn size(&self) -> [usize; DIM] {
               found constant `DIM`
 
 error[E0308]: method not compatible with trait
-  --> $DIR/issue-83765.rs:92:5
+  --> $DIR/issue-83765.rs:96:5
    |
 LL |     fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
@@ -54,7 +34,127 @@ LL |     fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
    = note: expected constant `Self::DIM`
               found constant `DIM`
 
-error: aborting due to 4 previous errors
+error[E0308]: method not compatible with trait
+  --> $DIR/issue-83765.rs:108:5
+   |
+LL |     fn size(&self) -> [usize; 1] {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `1`
+   |
+   = note: expected constant `Self::DIM`
+              found constant `1`
+
+error[E0308]: method not compatible with trait
+  --> $DIR/issue-83765.rs:115:5
+   |
+LL |     fn bget(&self, index: [usize; 1]) -> Option<T> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `1`
+   |
+   = note: expected constant `Self::DIM`
+              found constant `1`
+
+error: unconstrained generic constant
+  --> $DIR/issue-83765.rs:58:13
+   |
+LL |         if !self.inbounds(index) {
+   |             ^^^^
+   |
+note: required by a bound in `TensorSize::inbounds`
+  --> $DIR/issue-83765.rs:14:39
+   |
+LL |     fn inbounds(&self, index: [usize; Self::DIM]) -> bool {
+   |                                       ^^^^^^^^^ required by this bound in `TensorSize::inbounds`
+help: try adding a `where` bound
+   |
+LL |     fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> where [(); Self::DIM]: {
+   |                                                                  ++++++++++++++++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/issue-83765.rs:58:27
+   |
+LL |         if !self.inbounds(index) {
+   |                           ^^^^^ expected `Self::DIM`, found `DIM`
+   |
+   = note: expected constant `Self::DIM`
+              found constant `DIM`
+
+error: unconstrained generic constant
+  --> $DIR/issue-83765.rs:63:25
+   |
+LL |         let size = self.size();
+   |                         ^^^^
+   |
+note: required by a bound in `TensorSize::size`
+  --> $DIR/issue-83765.rs:13:31
+   |
+LL |     fn size(&self) -> [usize; Self::DIM];
+   |                               ^^^^^^^^^ required by this bound in `TensorSize::size`
+help: try adding a `where` bound
+   |
+LL |     fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> where [(); Self::DIM]: {
+   |                                                                  ++++++++++++++++++++++
+
+error[E0277]: the trait bound `[usize; T::DIM]: Default` is not satisfied
+  --> $DIR/issue-83765.rs:65:41
+   |
+LL |         let newindex: [usize; T::DIM] = Default::default();
+   |                                         ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[usize; T::DIM]`
+   |
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> where [usize; T::DIM]: Default {
+   |                                                                                                  ++++++++++++++++++++++++++++++
+
+error: unconstrained generic constant
+  --> $DIR/issue-83765.rs:86:24
+   |
+LL |         self.reference.size()
+   |                        ^^^^
+   |
+note: required by a bound in `TensorSize::size`
+  --> $DIR/issue-83765.rs:13:31
+   |
+LL |     fn size(&self) -> [usize; Self::DIM];
+   |                               ^^^^^^^^^ required by this bound in `TensorSize::size`
+help: try adding a `where` bound
+   |
+LL |     fn size(&self) -> [usize; DIM] where [(); Self::DIM]: {
+   |                                    ++++++++++++++++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/issue-83765.rs:86:9
+   |
+LL |         self.reference.size()
+   |         ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM`
+   |
+   = note: expected constant `DIM`
+              found constant `Self::DIM`
+
+error: unconstrained generic constant
+  --> $DIR/issue-83765.rs:98:9
+   |
+LL |         self.reference.bget(index).map(&self.closure)
+   |         ^^^^^^^^^^^^^^
+   |
+note: required by a bound in `Broadcastable::bget`
+  --> $DIR/issue-83765.rs:21:35
+   |
+LL |     fn bget(&self, index: [usize; Self::DIM]) -> Option<Self::Element>;
+   |                                   ^^^^^^^^^ required by this bound in `Broadcastable::bget`
+help: try adding a `where` bound
+   |
+LL |     fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> where [(); Self::DIM]: {
+   |                                                                  ++++++++++++++++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/issue-83765.rs:98:29
+   |
+LL |         self.reference.bget(index).map(&self.closure)
+   |                             ^^^^^ expected `Self::DIM`, found `DIM`
+   |
+   = note: expected constant `Self::DIM`
+              found constant `DIM`
+
+error: aborting due to 14 previous errors
 
-Some errors have detailed explanations: E0308, E0391.
-For more information about an error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/pattern/unused-parameters-const-pattern.rs b/tests/ui/pattern/unused-parameters-const-pattern.rs
new file mode 100644
index 00000000000..107c65ddfd3
--- /dev/null
+++ b/tests/ui/pattern/unused-parameters-const-pattern.rs
@@ -0,0 +1,19 @@
+//@ check-pass
+
+// Tests that const patterns that use generic parameters are
+// allowed if we are still able to evaluate them.
+
+trait Trait { const ASSOC: usize; }
+
+impl<T> Trait for T {
+    const ASSOC: usize = 10;
+}
+
+fn foo<T>(a: usize) {
+    match a {
+        <T as Trait>::ASSOC => (),
+        _ => (),
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
index 9fcb26c20a6..81be8c8362e 100644
--- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr
+++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
@@ -62,6 +62,11 @@ LL | / fn foo() -> Bar
 LL | | where
 LL | |     Bar: Send,
    | |______________^
+note: ...which requires computing revealed normalized predicates of `foo::{constant#0}`...
+  --> $DIR/in-where-clause.rs:13:9
+   |
+LL |     [0; 1 + 2]
+   |         ^^^^^
    = note: ...which requires revealing opaque types in `[Binder { value: TraitPredicate(<Bar as core::marker::Send>, polarity:Positive), bound_vars: [] }]`...
 note: ...which requires computing type of `Bar::{opaque#0}`...
   --> $DIR/in-where-clause.rs:5:12