about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-05-23 05:30:45 +0000
committerbors <bors@rust-lang.org>2025-05-23 05:30:45 +0000
commit52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9 (patch)
tree13f410e99a4095b87dd23702e83e9940e132e0ab
parente7f4317ea0e891296163414c6f681ccec976abc3 (diff)
parentfdccb42167028b33a7ceee7343cfe3500c1c4b8b (diff)
downloadrust-52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9.tar.gz
rust-52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9.zip
Auto merge of #140553 - BoxyUwU:defer_type_system_ctfe, r=compiler-errors
Defer evaluating type system constants when they use infers or params

Split out of #137972, the parts necessary for associated const equality and min generic const args to make progress and have correct semantics around when CTFE is invoked. According to a [previous perf run](https://perf.rust-lang.org/compare.html?start=93257e2d20809d82d1bc0fcc1942480d1a66d7cd&end=01b4cbf0f47c3f782330db88fa5ba199bba1f8a2&stat=instructions:u) of adding the new `const_arg_kind` query we should expect minor regressions here.

I think this is acceptable as we should be able to remove this query relatively soon once mgca is more complete as we'll then be able to implement GCE in terms of mgca and rip out `GCEConst` at which point it's trivial to determine what kind of anon const we're dealing with (either it has generics and is a repeat expr hack, or it doesnt and is a normal anon const).

This should only affect unstable code as we handle repeat exprs specially and those are the only kinds of type system consts that are allowed to make use of generic parameters.

Fixes #133066
Fixes #133199
Fixes #136894
Fixes #137813

r? compiler-errors
-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