Add note to resolve error about generics from inside static/const
This commit is contained in:
parent
1d8d7b16cb
commit
511bf6e1c7
@ -119,12 +119,16 @@ resolve_generic_params_from_outer_item =
|
||||
.refer_to_type_directly = refer to the type directly here instead
|
||||
.suggestion = try introducing a local generic parameter here
|
||||
|
||||
resolve_generic_params_from_outer_item_const = a `const` is a separate item from the item that contains it
|
||||
|
||||
resolve_generic_params_from_outer_item_const_param = const parameter from outer item
|
||||
|
||||
resolve_generic_params_from_outer_item_self_ty_alias = `Self` type implicitly declared here, by this `impl`
|
||||
|
||||
resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here
|
||||
|
||||
resolve_generic_params_from_outer_item_static = a `static` is a separate item from the item that contains it
|
||||
|
||||
resolve_generic_params_from_outer_item_ty_param = type parameter from outer item
|
||||
|
||||
|
||||
|
@ -561,13 +561,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
resolution_error: ResolutionError<'a>,
|
||||
) -> DiagnosticBuilder<'_> {
|
||||
match resolution_error {
|
||||
ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => {
|
||||
ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params, def_kind) => {
|
||||
use errs::GenericParamsFromOuterItemLabel as Label;
|
||||
let static_or_const = match def_kind {
|
||||
DefKind::Static(_) => Some(errs::GenericParamsFromOuterItemStaticOrConst::Static),
|
||||
DefKind::Const => Some(errs::GenericParamsFromOuterItemStaticOrConst::Const),
|
||||
_ => None,
|
||||
};
|
||||
let mut err = errs::GenericParamsFromOuterItem {
|
||||
span,
|
||||
label: None,
|
||||
refer_to_type_directly: None,
|
||||
sugg: None,
|
||||
static_or_const,
|
||||
};
|
||||
|
||||
let sm = self.tcx.sess.source_map();
|
||||
|
@ -44,6 +44,16 @@ pub(crate) struct GenericParamsFromOuterItem {
|
||||
pub(crate) refer_to_type_directly: Option<Span>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sugg: Option<GenericParamsFromOuterItemSugg>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) static_or_const: Option<GenericParamsFromOuterItemStaticOrConst>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum GenericParamsFromOuterItemStaticOrConst {
|
||||
#[note(resolve_generic_params_from_outer_item_static)]
|
||||
Static,
|
||||
#[note(resolve_generic_params_from_outer_item_const)]
|
||||
Const,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
@ -10,9 +10,7 @@ use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
|
||||
use crate::late::{
|
||||
ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind,
|
||||
};
|
||||
use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
|
||||
use crate::macros::{sub_namespace_match, MacroRulesScope};
|
||||
use crate::BindingKey;
|
||||
use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
|
||||
@ -1090,7 +1088,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
| RibKind::ForwardGenericParamBan => {
|
||||
// Nothing to do. Continue.
|
||||
}
|
||||
RibKind::Item(_) | RibKind::AssocItem => {
|
||||
RibKind::Item(..) | RibKind::AssocItem => {
|
||||
// This was an attempt to access an upvar inside a
|
||||
// named function item. This is not allowed, so we
|
||||
// report an error.
|
||||
@ -1155,7 +1153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
|
||||
for rib in ribs {
|
||||
let has_generic_params: HasGenericParams = match rib.kind {
|
||||
let (has_generic_params, def_kind) = match rib.kind {
|
||||
RibKind::Normal
|
||||
| RibKind::FnOrCoroutine
|
||||
| RibKind::Module(..)
|
||||
@ -1213,7 +1211,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// This was an attempt to use a type parameter outside its scope.
|
||||
RibKind::Item(has_generic_params) => has_generic_params,
|
||||
RibKind::Item(has_generic_params, def_kind) => {
|
||||
(has_generic_params, def_kind)
|
||||
}
|
||||
RibKind::ConstParamTy => {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(
|
||||
@ -1231,7 +1231,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
|
||||
ResolutionError::GenericParamsFromOuterItem(
|
||||
res,
|
||||
has_generic_params,
|
||||
def_kind,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
@ -1239,7 +1243,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
Res::Def(DefKind::ConstParam, _) => {
|
||||
for rib in ribs {
|
||||
let has_generic_params = match rib.kind {
|
||||
let (has_generic_params, def_kind) = match rib.kind {
|
||||
RibKind::Normal
|
||||
| RibKind::FnOrCoroutine
|
||||
| RibKind::Module(..)
|
||||
@ -1276,7 +1280,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
continue;
|
||||
}
|
||||
|
||||
RibKind::Item(has_generic_params) => has_generic_params,
|
||||
RibKind::Item(has_generic_params, def_kind) => {
|
||||
(has_generic_params, def_kind)
|
||||
}
|
||||
RibKind::ConstParamTy => {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(
|
||||
@ -1295,7 +1301,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
|
||||
ResolutionError::GenericParamsFromOuterItem(
|
||||
res,
|
||||
has_generic_params,
|
||||
def_kind,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
|
@ -181,7 +181,7 @@ pub(crate) enum RibKind<'a> {
|
||||
FnOrCoroutine,
|
||||
|
||||
/// We passed through an item scope. Disallow upvars.
|
||||
Item(HasGenericParams),
|
||||
Item(HasGenericParams, DefKind),
|
||||
|
||||
/// We're in a constant item. Can't refer to dynamic stuff.
|
||||
///
|
||||
@ -221,7 +221,7 @@ impl RibKind<'_> {
|
||||
| RibKind::MacroDefinition(_)
|
||||
| RibKind::ConstParamTy
|
||||
| RibKind::InlineAsmSym => false,
|
||||
RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true,
|
||||
RibKind::AssocItem | RibKind::Item(..) | RibKind::ForwardGenericParamBan => true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -866,11 +866,12 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
}
|
||||
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
|
||||
self.resolve_doc_links(&foreign_item.attrs, MaybeExported::Ok(foreign_item.id));
|
||||
let def_kind = self.r.local_def_kind(foreign_item.id);
|
||||
match foreign_item.kind {
|
||||
ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span)),
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
|
||||
LifetimeRibKind::Generics {
|
||||
binder: foreign_item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
@ -882,7 +883,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span)),
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
|
||||
LifetimeRibKind::Generics {
|
||||
binder: foreign_item.id,
|
||||
kind: LifetimeBinderKind::Function,
|
||||
@ -892,7 +893,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
);
|
||||
}
|
||||
ForeignItemKind::Static(..) => {
|
||||
self.with_static_rib(|this| {
|
||||
self.with_static_rib(def_kind, |this| {
|
||||
visit::walk_foreign_item(this, foreign_item);
|
||||
});
|
||||
}
|
||||
@ -2268,10 +2269,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
|
||||
fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) {
|
||||
debug!("resolve_adt");
|
||||
let kind = self.r.local_def_kind(item.id);
|
||||
self.with_current_self_item(item, |this| {
|
||||
this.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span)),
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span), kind),
|
||||
LifetimeRibKind::Generics {
|
||||
binder: item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
@ -2345,11 +2347,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
let name = item.ident.name;
|
||||
debug!("(resolving item) resolving {} ({:?})", name, item.kind);
|
||||
|
||||
let def_kind = self.r.local_def_kind(item.id);
|
||||
match item.kind {
|
||||
ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span)),
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
|
||||
LifetimeRibKind::Generics {
|
||||
binder: item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
@ -2362,7 +2365,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
ItemKind::Fn(box Fn { ref generics, .. }) => {
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span)),
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
|
||||
LifetimeRibKind::Generics {
|
||||
binder: item.id,
|
||||
kind: LifetimeBinderKind::Function,
|
||||
@ -2401,7 +2404,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
// Create a new rib for the trait-wide type parameters.
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span)),
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
|
||||
LifetimeRibKind::Generics {
|
||||
binder: item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
@ -2422,7 +2425,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
// Create a new rib for the trait-wide type parameters.
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span)),
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
|
||||
LifetimeRibKind::Generics {
|
||||
binder: item.id,
|
||||
kind: LifetimeBinderKind::Item,
|
||||
@ -2456,7 +2459,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
}
|
||||
|
||||
ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) => {
|
||||
self.with_static_rib(|this| {
|
||||
self.with_static_rib(def_kind, |this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
|
||||
this.visit_ty(ty);
|
||||
});
|
||||
@ -2471,11 +2474,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(if self.r.tcx.features().generic_const_items {
|
||||
HasGenericParams::Yes(generics.span)
|
||||
} else {
|
||||
HasGenericParams::No
|
||||
}),
|
||||
RibKind::Item(
|
||||
if self.r.tcx.features().generic_const_items {
|
||||
HasGenericParams::Yes(generics.span)
|
||||
} else {
|
||||
HasGenericParams::No
|
||||
},
|
||||
def_kind,
|
||||
),
|
||||
LifetimeRibKind::Generics {
|
||||
binder: item.id,
|
||||
kind: LifetimeBinderKind::ConstItem,
|
||||
@ -2560,7 +2566,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
let mut add_bindings_for_ns = |ns| {
|
||||
let parent_rib = self.ribs[ns]
|
||||
.iter()
|
||||
.rfind(|r| matches!(r.kind, RibKind::Item(_)))
|
||||
.rfind(|r| matches!(r.kind, RibKind::Item(..)))
|
||||
.expect("associated item outside of an item");
|
||||
seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
|
||||
};
|
||||
@ -2695,8 +2701,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
self.label_ribs.pop();
|
||||
}
|
||||
|
||||
fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
let kind = RibKind::Item(HasGenericParams::No);
|
||||
fn with_static_rib(&mut self, def_kind: DefKind, f: impl FnOnce(&mut Self)) {
|
||||
let kind = RibKind::Item(HasGenericParams::No, def_kind);
|
||||
self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
|
||||
}
|
||||
|
||||
@ -2877,7 +2883,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
// If applicable, create a rib for the type parameters.
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span)),
|
||||
RibKind::Item(HasGenericParams::Yes(generics.span), self.r.local_def_kind(item_id)),
|
||||
LifetimeRibKind::Generics {
|
||||
span: generics.span,
|
||||
binder: item_id,
|
||||
|
@ -185,7 +185,7 @@ struct BindingError {
|
||||
#[derive(Debug)]
|
||||
enum ResolutionError<'a> {
|
||||
/// Error E0401: can't use type or const parameters from outer item.
|
||||
GenericParamsFromOuterItem(Res, HasGenericParams),
|
||||
GenericParamsFromOuterItem(Res, HasGenericParams, DefKind),
|
||||
/// Error E0403: the name is already used for a type or const parameter in this generic
|
||||
/// parameter list.
|
||||
NameAlreadyUsedInParameterList(Symbol, Span),
|
||||
@ -1207,6 +1207,10 @@ impl<'tcx> Resolver<'_, 'tcx> {
|
||||
self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
|
||||
}
|
||||
|
||||
fn local_def_kind(&self, node: NodeId) -> DefKind {
|
||||
self.tcx.def_kind(self.local_def_id(node))
|
||||
}
|
||||
|
||||
/// Adds a definition with a parent definition.
|
||||
fn create_def(
|
||||
&mut self,
|
||||
|
@ -5,6 +5,8 @@ LL | fn foo<T>() {
|
||||
| - type parameter from outer item
|
||||
LL | static a: Bar<T> = Bar::What;
|
||||
| ^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `static` is a separate item from the item that contains it
|
||||
|
||||
error[E0392]: parameter `T` is never used
|
||||
--> $DIR/inner-static-type-parameter.rs:3:10
|
||||
|
@ -5,6 +5,8 @@ LL | fn outer<T: Tr>() { // outer function
|
||||
| - type parameter from outer item
|
||||
LL | const K: u32 = T::C;
|
||||
| ^^^^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `const` is a separate item from the item that contains it
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24
|
||||
@ -14,6 +16,8 @@ LL | impl<T> Tr for T { // outer impl block
|
||||
LL | const C: u32 = {
|
||||
LL | const I: u32 = T::C;
|
||||
| ^^^^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `const` is a separate item from the item that contains it
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20
|
||||
@ -22,6 +26,8 @@ LL | struct S<T: Tr>(U32<{ // outer struct
|
||||
| - type parameter from outer item
|
||||
LL | const _: u32 = T::C;
|
||||
| ^^^^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `const` is a separate item from the item that contains it
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -7,6 +7,8 @@ LL | const K: u32 = T::C;
|
||||
| - ^^^^ use of generic parameter from outer item
|
||||
| |
|
||||
| help: try introducing a local generic parameter here: `<T>`
|
||||
|
|
||||
= note: a `const` is a separate item from the item that contains it
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24
|
||||
@ -18,6 +20,8 @@ LL | const I: u32 = T::C;
|
||||
| - ^^^^ use of generic parameter from outer item
|
||||
| |
|
||||
| help: try introducing a local generic parameter here: `<T>`
|
||||
|
|
||||
= note: a `const` is a separate item from the item that contains it
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20
|
||||
@ -28,6 +32,8 @@ LL | const _: u32 = T::C;
|
||||
| - ^^^^ use of generic parameter from outer item
|
||||
| |
|
||||
| help: try introducing a local generic parameter here: `<T>`
|
||||
|
|
||||
= note: a `const` is a separate item from the item that contains it
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -6,6 +6,8 @@ LL | unsafe fn foo<A>() {
|
||||
LL | extern "C" {
|
||||
LL | static baz: *const A;
|
||||
| ^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `static` is a separate item from the item that contains it
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -6,6 +6,8 @@ LL | fn f<T>() {
|
||||
LL | extern "C" {
|
||||
LL | static a: *const T;
|
||||
| ^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `static` is a separate item from the item that contains it
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/issue-65035-static-with-parent-generics.rs:9:22
|
||||
@ -14,6 +16,8 @@ LL | fn g<T: Default>() {
|
||||
| - type parameter from outer item
|
||||
LL | static a: *const T = Default::default();
|
||||
| ^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `static` is a separate item from the item that contains it
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/issue-65035-static-with-parent-generics.rs:15:24
|
||||
@ -23,6 +27,8 @@ LL | fn h<const N: usize>() {
|
||||
LL | extern "C" {
|
||||
LL | static a: [u8; N];
|
||||
| ^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `static` is a separate item from the item that contains it
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/issue-65035-static-with-parent-generics.rs:21:20
|
||||
@ -31,6 +37,8 @@ LL | fn i<const N: usize>() {
|
||||
| - const parameter from outer item
|
||||
LL | static a: [u8; N] = [0; N];
|
||||
| ^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `static` is a separate item from the item that contains it
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/issue-65035-static-with-parent-generics.rs:21:29
|
||||
@ -39,6 +47,8 @@ LL | fn i<const N: usize>() {
|
||||
| - const parameter from outer item
|
||||
LL | static a: [u8; N] = [0; N];
|
||||
| ^ use of generic parameter from outer item
|
||||
|
|
||||
= note: a `static` is a separate item from the item that contains it
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user