Rollup merge of #119939 - clubby789:static-const-generic-note, r=compiler-errors

Improve 'generic param from outer item' error for `Self` and inside `static`/`const` items

Fixes #109596
Fixes #119936
This commit is contained in:
Matthias Krüger 2024-02-06 22:45:39 +01:00 committed by GitHub
commit 3c52832375
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 118 additions and 43 deletions

View File

@ -118,17 +118,27 @@ resolve_forward_declared_generic_param =
.label = defaulted generic parameters cannot be forward declared
resolve_generic_params_from_outer_item =
can't use generic parameters from outer item
.label = use of generic parameter from outer item
can't use {$is_self ->
[true] `Self`
*[false] generic parameters
} from outer item
.label = use of {$is_self ->
[true] `Self`
*[false] generic parameter
} 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

View File

@ -561,13 +561,21 @@ 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 is_self = matches!(outer_res, Res::SelfTyParam { .. } | Res::SelfTyAlias { .. });
let mut err = errs::GenericParamsFromOuterItem {
span,
label: None,
refer_to_type_directly: None,
sugg: None,
static_or_const,
is_self,
};
let sm = self.tcx.sess.source_map();

View File

@ -45,6 +45,17 @@ 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>,
pub(crate) is_self: bool,
}
#[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)]

View File

@ -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;

View File

@ -185,7 +185,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.
///
@ -225,7 +225,7 @@ impl RibKind<'_> {
| RibKind::MacroDefinition(_)
| RibKind::ConstParamTy
| RibKind::InlineAsmSym => false,
RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true,
RibKind::AssocItem | RibKind::Item(..) | RibKind::ForwardGenericParamBan => true,
}
}
@ -869,11 +869,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,
@ -885,7 +886,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,
@ -895,7 +896,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);
});
}
@ -2266,10 +2267,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,
@ -2343,11 +2345,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,
@ -2360,7 +2363,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,
@ -2399,7 +2402,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,
@ -2420,7 +2423,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,
@ -2454,7 +2457,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);
});
@ -2469,11 +2472,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,
@ -2558,7 +2564,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)));
};
@ -2693,8 +2699,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))
}
@ -2875,7 +2881,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,

View File

@ -184,7 +184,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),
@ -1217,6 +1217,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,

View File

@ -20,7 +20,7 @@ LL | fn baz<U,
LL | (y: T) {
| ^ use of generic parameter from outer item
error[E0401]: can't use generic parameters from outer item
error[E0401]: can't use `Self` from outer item
--> $DIR/E0401.rs:24:25
|
LL | impl<T> Iterator for A<T> {
@ -29,7 +29,7 @@ LL | impl<T> Iterator for A<T> {
LL | fn helper(sel: &Self) -> u8 {
| ^^^^
| |
| use of generic parameter from outer item
| use of `Self` from outer item
| refer to the type directly here instead
error[E0283]: type annotations needed

View File

@ -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]: type parameter `T` is never used
--> $DIR/inner-static-type-parameter.rs:3:10

View File

@ -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

View File

@ -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

View File

@ -1,7 +1,7 @@
trait Trait {
fn outer(&self) {
fn inner(_: &Self) {
//~^ ERROR can't use generic parameters from outer item
//~^ ERROR can't use `Self` from outer item
}
}
}

View File

@ -1,10 +1,10 @@
error[E0401]: can't use generic parameters from outer item
error[E0401]: can't use `Self` from outer item
--> $DIR/issue-12796.rs:3:22
|
LL | fn inner(_: &Self) {
| ^^^^
| |
| use of generic parameter from outer item
| use of `Self` from outer item
| can't use `Self` here
error: aborting due to 1 previous error

View File

@ -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

View File

@ -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

View File

@ -4,8 +4,8 @@ impl A {
//~^ NOTE `Self` type implicitly declared here, by this `impl`
fn banana(&mut self) {
fn peach(this: &Self) {
//~^ ERROR can't use generic parameters from outer item
//~| NOTE use of generic parameter from outer item
//~^ ERROR can't use `Self` from outer item
//~| NOTE use of `Self` from outer item
//~| NOTE refer to the type directly here instead
}
}

View File

@ -1,4 +1,4 @@
error[E0401]: can't use generic parameters from outer item
error[E0401]: can't use `Self` from outer item
--> $DIR/use-self-in-inner-fn.rs:6:25
|
LL | impl A {
@ -7,7 +7,7 @@ LL | impl A {
LL | fn peach(this: &Self) {
| ^^^^
| |
| use of generic parameter from outer item
| use of `Self` from outer item
| refer to the type directly here instead
error: aborting due to 1 previous error