about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_resolve/messages.ftl29
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs19
-rw-r--r--compiler/rustc_resolve/src/errors.rs47
-rw-r--r--compiler/rustc_resolve/src/ident.rs70
-rw-r--r--compiler/rustc_resolve/src/late.rs4
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs70
-rw-r--r--compiler/rustc_resolve/src/lib.rs11
7 files changed, 185 insertions, 65 deletions
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 32409499047..ff8bd462dd8 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -145,6 +145,15 @@ resolve_param_in_ty_of_const_param =
     the type of const parameters must not depend on other generic parameters
     .label = the type must not depend on the parameter `{$name}`
 
+resolve_type_param_in_ty_of_const_param =
+    type parameters may not be used in the type of const parameters
+
+resolve_const_param_in_ty_of_const_param =
+    const parameters may not be used in the type of const parameters
+
+resolve_lifetime_param_in_ty_of_const_param =
+    lifetime parameters may not be used in the type of const parameters
+
 resolve_self_in_generic_param_default =
     generic parameters cannot use `Self` in their defaults
     .label = `Self` in generic parameter default
@@ -156,12 +165,15 @@ resolve_param_in_non_trivial_anon_const =
 resolve_param_in_non_trivial_anon_const_help =
     use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
-resolve_param_in_non_trivial_anon_const_sub_type =
+resolve_type_param_in_non_trivial_anon_const =
     type parameters may not be used in const expressions
 
-resolve_param_in_non_trivial_anon_const_sub_non_type =
+resolve_const_param_in_non_trivial_anon_const =
     const parameters may only be used as standalone arguments, i.e. `{$name}`
 
+resolve_lifetime_param_in_non_trivial_anon_const =
+    lifetime parameters may not be used in const expressions
+
 resolve_unreachable_label =
     use of unreachable label `{$name}`
     .label = unreachable label `{$name}`
@@ -233,3 +245,16 @@ resolve_macro_use_extern_crate_self = `#[macro_use]` is not supported on `extern
 
 resolve_accessible_unsure = not sure whether the path is accessible or not
     .note = the type may have associated items, but we are currently not checking them
+
+resolve_param_in_enum_discriminant =
+    generic parameters may not be used in enum discriminant values
+    .label = cannot perform const operation using `{$name}`
+
+resolve_type_param_in_enum_discriminant =
+    type parameters may not be used in enum discriminant values
+
+resolve_const_param_in_enum_discriminant =
+    const parameters may not be used in enum discriminant values
+
+resolve_lifetime_param_in_enum_discriminant =
+    lifetime parameters may not be used in enum discriminant values
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index fae7d549592..72cdce5c8f0 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -864,18 +864,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             ResolutionError::ForwardDeclaredGenericParam => {
                 self.tcx.sess.create_err(errs::ForwardDeclaredGenericParam { span })
             }
-            ResolutionError::ParamInTyOfConstParam(name) => {
-                self.tcx.sess.create_err(errs::ParamInTyOfConstParam { span, name })
-            }
-            ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
+            ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self
+                .tcx
+                .sess
+                .create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }),
+            ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => {
                 self.tcx.sess.create_err(errs::ParamInNonTrivialAnonConst {
                     span,
                     name,
-                    sub_is_type: if is_type {
-                        errs::ParamInNonTrivialAnonConstIsType::AType
-                    } else {
-                        errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
-                    },
+                    param_kind: is_type,
                     help: self
                         .tcx
                         .sess
@@ -883,6 +880,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         .then_some(errs::ParamInNonTrivialAnonConstHelp),
                 })
             }
+            ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
+                .tcx
+                .sess
+                .create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
             ResolutionError::SelfInGenericParamDefault => {
                 self.tcx.sess.create_err(errs::SelfInGenericParamDefault { span })
             }
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 4f9f1c7e856..f6d7e8b4c87 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -326,6 +326,18 @@ pub(crate) struct ParamInTyOfConstParam {
     #[label]
     pub(crate) span: Span,
     pub(crate) name: Symbol,
+    #[subdiagnostic]
+    pub(crate) param_kind: Option<ParamKindInTyOfConstParam>,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamKindInTyOfConstParam {
+    #[note(resolve_type_param_in_ty_of_const_param)]
+    Type,
+    #[note(resolve_const_param_in_ty_of_const_param)]
+    Const,
+    #[note(resolve_lifetime_param_in_ty_of_const_param)]
+    Lifetime,
 }
 
 #[derive(Diagnostic)]
@@ -344,7 +356,7 @@ pub(crate) struct ParamInNonTrivialAnonConst {
     pub(crate) span: Span,
     pub(crate) name: Symbol,
     #[subdiagnostic]
-    pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
+    pub(crate) param_kind: ParamKindInNonTrivialAnonConst,
     #[subdiagnostic]
     pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
 }
@@ -354,11 +366,13 @@ pub(crate) struct ParamInNonTrivialAnonConst {
 pub(crate) struct ParamInNonTrivialAnonConstHelp;
 
 #[derive(Subdiagnostic)]
-pub(crate) enum ParamInNonTrivialAnonConstIsType {
-    #[note(resolve_param_in_non_trivial_anon_const_sub_type)]
-    AType,
-    #[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
-    NotAType { name: Symbol },
+pub(crate) enum ParamKindInNonTrivialAnonConst {
+    #[note(resolve_type_param_in_non_trivial_anon_const)]
+    Type,
+    #[help(resolve_const_param_in_non_trivial_anon_const)]
+    Const { name: Symbol },
+    #[note(resolve_lifetime_param_in_non_trivial_anon_const)]
+    Lifetime,
 }
 
 #[derive(Diagnostic)]
@@ -539,3 +553,24 @@ pub(crate) struct CfgAccessibleUnsure {
     #[primary_span]
     pub(crate) span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(resolve_param_in_enum_discriminant)]
+pub(crate) struct ParamInEnumDiscriminant {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) name: Symbol,
+    #[subdiagnostic]
+    pub(crate) param_kind: ParamKindInEnumDiscriminant,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamKindInEnumDiscriminant {
+    #[note(resolve_type_param_in_enum_discriminant)]
+    Type,
+    #[note(resolve_const_param_in_enum_discriminant)]
+    Const,
+    #[note(resolve_lifetime_param_in_enum_discriminant)]
+    Lifetime,
+}
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 4e1d49c12a7..5a3ae656ad4 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -13,8 +13,10 @@ use rustc_span::{Span, DUMMY_SP};
 
 use std::ptr;
 
+use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
 use crate::late::{
-    ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind,
+    ConstantHasGenerics, ConstantItemKind, HasGenericParams, NoConstantGenericsReason, PathSource,
+    Rib, RibKind,
 };
 use crate::macros::{sub_namespace_match, MacroRulesScope};
 use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
@@ -1153,7 +1155,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         }
                         RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
-                                self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
+                                self.report_error(
+                                    span,
+                                    ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: None,
+                                    },
+                                );
                             }
                             return Res::Err;
                         }
@@ -1206,13 +1214,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     }
                                 } else {
                                     if let Some(span) = finalize {
-                                        self.report_error(
-                                            span,
-                                            ResolutionError::ParamInNonTrivialAnonConst {
-                                                name: rib_ident.name,
-                                                is_type: true,
-                                            },
-                                        );
+                                        let error = match cause {
+                                            NoConstantGenericsReason::IsEnumDiscriminant => {
+                                                ResolutionError::ParamInEnumDiscriminant {
+                                                    name: rib_ident.name,
+                                                    param_kind: ParamKindInEnumDiscriminant::Type,
+                                                }
+                                            }
+                                            NoConstantGenericsReason::NonTrivialConstArg => {
+                                                ResolutionError::ParamInNonTrivialAnonConst {
+                                                    name: rib_ident.name,
+                                                    param_kind:
+                                                        ParamKindInNonTrivialAnonConst::Type,
+                                                }
+                                            }
+                                        };
+                                        self.report_error(span, error);
                                         self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
                                     }
 
@@ -1229,7 +1246,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             if let Some(span) = finalize {
                                 self.report_error(
                                     span,
-                                    ResolutionError::ParamInTyOfConstParam(rib_ident.name),
+                                    ResolutionError::ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
+                                    },
                                 );
                             }
                             return Res::Err;
@@ -1262,14 +1282,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         RibKind::ConstantItem(trivial, _) => {
                             if let ConstantHasGenerics::No(cause) = trivial {
                                 if let Some(span) = finalize {
-                                    self.report_error(
-                                        span,
-                                        ResolutionError::ParamInNonTrivialAnonConst {
-                                            name: rib_ident.name,
-                                            is_type: false,
-                                        },
-                                    );
-                                    self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
+                                    let error = match cause {
+                                        NoConstantGenericsReason::IsEnumDiscriminant => {
+                                            ResolutionError::ParamInEnumDiscriminant {
+                                                name: rib_ident.name,
+                                                param_kind: ParamKindInEnumDiscriminant::Const,
+                                            }
+                                        }
+                                        NoConstantGenericsReason::NonTrivialConstArg => {
+                                            ResolutionError::ParamInNonTrivialAnonConst {
+                                                name: rib_ident.name,
+                                                param_kind: ParamKindInNonTrivialAnonConst::Const {
+                                                    name: rib_ident.name,
+                                                },
+                                            }
+                                        }
+                                    };
+                                    self.report_error(span, error);
                                 }
 
                                 return Res::Err;
@@ -1283,7 +1312,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             if let Some(span) = finalize {
                                 self.report_error(
                                     span,
-                                    ResolutionError::ParamInTyOfConstParam(rib_ident.name),
+                                    ResolutionError::ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
+                                    },
                                 );
                             }
                             return Res::Err;
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index c6b193710e0..2a8287d5554 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1529,7 +1529,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             match rib.kind {
                 LifetimeRibKind::Item => break,
                 LifetimeRibKind::ConstParamTy => {
-                    self.emit_non_static_lt_in_const_generic_error(lifetime);
+                    self.emit_non_static_lt_in_const_param_ty_error(lifetime);
                     self.record_lifetime_res(
                         lifetime.id,
                         LifetimeRes::Error,
@@ -1538,7 +1538,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     return;
                 }
                 LifetimeRibKind::ConcreteAnonConst(cause) => {
-                    self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
+                    self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
                     self.record_lifetime_res(
                         lifetime.id,
                         LifetimeRes::Error,
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 42d498c7ee0..c9131d8c8a9 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1,7 +1,7 @@
 use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
 use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
 use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet};
-use crate::path_names_to_string;
+use crate::{errors, path_names_to_string};
 use crate::{Module, ModuleKind, ModuleOrUniformRoot};
 use crate::{PathResult, PathSource, Segment};
 
@@ -22,7 +22,6 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
 use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
 use rustc_hir::PrimTy;
 use rustc_session::lint;
-use rustc_session::parse::feature_err;
 use rustc_session::Session;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::edition::Edition;
@@ -35,6 +34,8 @@ use std::ops::Deref;
 
 use thin_vec::ThinVec;
 
+use super::NoConstantGenericsReason;
+
 type Res = def::Res<ast::NodeId>;
 
 /// A field or associated item from self type suggested in case of resolution failure.
@@ -2316,37 +2317,56 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         }
     }
 
-    pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
-        struct_span_err!(
-            self.r.tcx.sess,
-            lifetime_ref.ident.span,
-            E0771,
-            "use of non-static lifetime `{}` in const generic",
-            lifetime_ref.ident
-        )
-        .note(
-            "for more information, see issue #74052 \
-            <https://github.com/rust-lang/rust/issues/74052>",
-        )
-        .emit();
+    pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) {
+        self.r
+            .tcx
+            .sess
+            .create_err(errors::ParamInTyOfConstParam {
+                span: lifetime_ref.ident.span,
+                name: lifetime_ref.ident.name,
+                param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
+            })
+            .emit();
     }
 
     /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
     /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
     /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
-    pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error(
+    pub(crate) fn emit_forbidden_non_static_lifetime_error(
         &self,
+        cause: NoConstantGenericsReason,
         lifetime_ref: &ast::Lifetime,
     ) {
-        let feature_active = self.r.tcx.sess.features_untracked().generic_const_exprs;
-        if !feature_active {
-            feature_err(
-                &self.r.tcx.sess.parse_sess,
-                sym::generic_const_exprs,
-                lifetime_ref.ident.span,
-                "a non-static lifetime is not allowed in a `const`",
-            )
-            .emit();
+        match cause {
+            NoConstantGenericsReason::IsEnumDiscriminant => {
+                self.r
+                    .tcx
+                    .sess
+                    .create_err(errors::ParamInEnumDiscriminant {
+                        span: lifetime_ref.ident.span,
+                        name: lifetime_ref.ident.name,
+                        param_kind: errors::ParamKindInEnumDiscriminant::Lifetime,
+                    })
+                    .emit();
+            }
+            NoConstantGenericsReason::NonTrivialConstArg => {
+                assert!(!self.r.tcx.features().generic_const_exprs);
+                self.r
+                    .tcx
+                    .sess
+                    .create_err(errors::ParamInNonTrivialAnonConst {
+                        span: lifetime_ref.ident.span,
+                        name: lifetime_ref.ident.name,
+                        param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime,
+                        help: self
+                            .r
+                            .tcx
+                            .sess
+                            .is_nightly_build()
+                            .then_some(errors::ParamInNonTrivialAnonConstHelp),
+                    })
+                    .emit();
+            }
         }
     }
 
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index e46463579fe..590609f9ed3 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -21,6 +21,9 @@
 #[macro_use]
 extern crate tracing;
 
+use errors::{
+    ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam,
+};
 use rustc_arena::{DroplessArena, TypedArena};
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::{self as ast, attr, NodeId, CRATE_NODE_ID};
@@ -223,11 +226,15 @@ enum ResolutionError<'a> {
     /// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
     ForwardDeclaredGenericParam,
     /// ERROR E0770: the type of const parameters must not depend on other generic parameters.
-    ParamInTyOfConstParam(Symbol),
+    ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> },
     /// generic parameters must not be used inside const evaluations.
     ///
     /// This error is only emitted when using `min_const_generics`.
-    ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
+    ParamInNonTrivialAnonConst { name: Symbol, param_kind: ParamKindInNonTrivialAnonConst },
+    /// generic parameters must not be used inside enum discriminants.
+    ///
+    /// This error is emitted even with `generic_const_exprs`.
+    ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
     /// Error E0735: generic parameters with a default cannot use `Self`
     SelfInGenericParamDefault,
     /// Error E0767: use of unreachable label