about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs138
-rw-r--r--tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs2
6 files changed, 85 insertions, 79 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index dfe9d7af3ad..8b9fae732c1 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1836,9 +1836,9 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
     match tcx.hir_node(const_arg_id) {
         hir::Node::ConstArg(_) => {
             if tcx.features().generic_const_exprs() {
-                ty::AnonConstKind::GCEConst
+                ty::AnonConstKind::GCE
             } else if tcx.features().min_generic_const_args() {
-                ty::AnonConstKind::MCGConst
+                ty::AnonConstKind::MCG
             } else if let hir::Node::Expr(hir::Expr {
                 kind: hir::ExprKind::Repeat(_, repeat_count),
                 ..
@@ -1847,7 +1847,7 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
             {
                 ty::AnonConstKind::RepeatExprCount
             } else {
-                ty::AnonConstKind::MCGConst
+                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 d261f3f85fe..7eb896f0bf1 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -106,7 +106,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
 
             match tcx.anon_const_kind(def_id) {
                 // Stable: anon consts are not able to use any generic parameters...
-                ty::AnonConstKind::MCGConst => None,
+                ty::AnonConstKind::MCG => None,
                 // we provide generics to repeat expr counts as a backwards compatibility hack. #76200
                 ty::AnonConstKind::RepeatExprCount => Some(parent_did),
 
@@ -116,13 +116,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                 // 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::GCEConst if in_param_ty => None,
+                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::GCEConst
+                ty::AnonConstKind::GCE
                     if let Some(param_id) =
                         tcx.hir_opt_const_param_default_param_def_id(hir_id) =>
                 {
@@ -169,7 +169,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                         has_late_bound_regions: generics.has_late_bound_regions,
                     };
                 }
-                ty::AnonConstKind::GCEConst => Some(parent_did),
+                ty::AnonConstKind::GCE => Some(parent_did),
 
                 // Field defaults are allowed to use generic parameters, e.g. `field: u32 = /*defid: N + 1*/`
                 ty::AnonConstKind::NonTypeSystem
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 2e8a2bceb38..6937b54eba2 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2589,7 +2589,6 @@ rustc_queries! {
 
     query anon_const_kind(def_id: DefId) -> ty::AnonConstKind {
         desc { |tcx| "looking up anon const kind of `{}`", tcx.def_path_str(def_id) }
-        cache_on_disk_if { def_id.is_local() }
         separate_provide_extern
     }
 }
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index f1ea2152f3b..455ac660412 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -262,8 +262,13 @@ impl<'tcx> Const<'tcx> {
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum AnonConstKind {
-    GCEConst,
-    MCGConst,
+    /// `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_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index c174de44558..d8e83dc72b0 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -542,6 +542,9 @@ 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.
             //
@@ -553,87 +556,84 @@ 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.def_kind(uv.def) == DefKind::AnonConst
-                && let ty::AnonConstKind::GCEConst = tcx.anon_const_kind(uv.def)
-            {
+            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.
-
-                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);
+                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)
                             }
                         }
-                        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)
                     }
-                } else {
-                    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
-                && let ty::AnonConstKind::RepeatExprCount = tcx.anon_const_kind(uv.def)
-            {
-                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(
-                        "Encountered anon const with inference variable args but no error reported",
-                    );
                 }
+                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);
+                    // 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)
-            } else {
-                // 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
-                if uv.args.has_non_region_param() || uv.args.has_non_region_infer() {
-                    return Err(EvaluateConstErr::HasGenericsOrInfers);
+                    (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
+                    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)
+                    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);
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
index 19cddb71b01..99318ef7598 100644
--- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs
+++ b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs
@@ -22,3 +22,5 @@ where
     //~^ ERROR type mismatch resolving
 {
 }
+
+fn main() {}