diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_resolve/messages.ftl | 29 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 47 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/ident.rs | 70 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 70 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 11 |
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 |
