Skip to content

Commit 01896c0

Browse files
committed
Add note to resolve error about generics from inside static/const
1 parent 1d8d7b1 commit 01896c0

11 files changed

+97
-34
lines changed

compiler/rustc_resolve/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,16 @@ resolve_generic_params_from_outer_item =
119119
.refer_to_type_directly = refer to the type directly here instead
120120
.suggestion = try introducing a local generic parameter here
121121
122+
resolve_generic_params_from_outer_item_const = a `const` is a separate item from the item that contains it
123+
122124
resolve_generic_params_from_outer_item_const_param = const parameter from outer item
123125
124126
resolve_generic_params_from_outer_item_self_ty_alias = `Self` type implicitly declared here, by this `impl`
125127
126128
resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here
127129
130+
resolve_generic_params_from_outer_item_static = a `static` is a separate item from the item that contains it
131+
128132
resolve_generic_params_from_outer_item_ty_param = type parameter from outer item
129133
130134

compiler/rustc_resolve/src/diagnostics.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -561,13 +561,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
561561
resolution_error: ResolutionError<'a>,
562562
) -> DiagnosticBuilder<'_> {
563563
match resolution_error {
564-
ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => {
564+
ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params, defkind) => {
565565
use errs::GenericParamsFromOuterItemLabel as Label;
566+
let static_or_const = match defkind {
567+
DefKind::Static(_) => Some(errs::GenericParamsFromOuterItemStaticOrConst::Static),
568+
DefKind::Const => Some(errs::GenericParamsFromOuterItemStaticOrConst::Const),
569+
_ => None,
570+
};
566571
let mut err = errs::GenericParamsFromOuterItem {
567572
span,
568573
label: None,
569574
refer_to_type_directly: None,
570575
sugg: None,
576+
static_or_const,
571577
};
572578

573579
let sm = self.tcx.sess.source_map();

compiler/rustc_resolve/src/errors.rs

+10
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ pub(crate) struct GenericParamsFromOuterItem {
4444
pub(crate) refer_to_type_directly: Option<Span>,
4545
#[subdiagnostic]
4646
pub(crate) sugg: Option<GenericParamsFromOuterItemSugg>,
47+
#[subdiagnostic]
48+
pub(crate) static_or_const: Option<GenericParamsFromOuterItemStaticOrConst>,
49+
}
50+
51+
#[derive(Subdiagnostic)]
52+
pub(crate) enum GenericParamsFromOuterItemStaticOrConst {
53+
#[note(resolve_generic_params_from_outer_item_static)]
54+
Static,
55+
#[note(resolve_generic_params_from_outer_item_const)]
56+
Const,
4757
}
4858

4959
#[derive(Subdiagnostic)]

compiler/rustc_resolve/src/ident.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ use rustc_span::symbol::{kw, Ident};
1010
use rustc_span::Span;
1111

1212
use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
13-
use crate::late::{
14-
ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind,
15-
};
13+
use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
1614
use crate::macros::{sub_namespace_match, MacroRulesScope};
1715
use crate::BindingKey;
1816
use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
@@ -1090,7 +1088,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
10901088
| RibKind::ForwardGenericParamBan => {
10911089
// Nothing to do. Continue.
10921090
}
1093-
RibKind::Item(_) | RibKind::AssocItem => {
1091+
RibKind::Item(..) | RibKind::AssocItem => {
10941092
// This was an attempt to access an upvar inside a
10951093
// named function item. This is not allowed, so we
10961094
// report an error.
@@ -1155,7 +1153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11551153
}
11561154
Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
11571155
for rib in ribs {
1158-
let has_generic_params: HasGenericParams = match rib.kind {
1156+
let (has_generic_params, defkind) = match rib.kind {
11591157
RibKind::Normal
11601158
| RibKind::FnOrCoroutine
11611159
| RibKind::Module(..)
@@ -1213,7 +1211,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12131211
}
12141212

12151213
// This was an attempt to use a type parameter outside its scope.
1216-
RibKind::Item(has_generic_params) => has_generic_params,
1214+
RibKind::Item(has_generic_params, defkind) => (has_generic_params, defkind),
12171215
RibKind::ConstParamTy => {
12181216
if let Some(span) = finalize {
12191217
self.report_error(
@@ -1231,15 +1229,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12311229
if let Some(span) = finalize {
12321230
self.report_error(
12331231
span,
1234-
ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
1232+
ResolutionError::GenericParamsFromOuterItem(
1233+
res,
1234+
has_generic_params,
1235+
defkind,
1236+
),
12351237
);
12361238
}
12371239
return Res::Err;
12381240
}
12391241
}
12401242
Res::Def(DefKind::ConstParam, _) => {
12411243
for rib in ribs {
1242-
let has_generic_params = match rib.kind {
1244+
let (has_generic_params, defkind) = match rib.kind {
12431245
RibKind::Normal
12441246
| RibKind::FnOrCoroutine
12451247
| RibKind::Module(..)
@@ -1276,7 +1278,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12761278
continue;
12771279
}
12781280

1279-
RibKind::Item(has_generic_params) => has_generic_params,
1281+
RibKind::Item(has_generic_params, defkind) => (has_generic_params, defkind),
12801282
RibKind::ConstParamTy => {
12811283
if let Some(span) = finalize {
12821284
self.report_error(
@@ -1295,7 +1297,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12951297
if let Some(span) = finalize {
12961298
self.report_error(
12971299
span,
1298-
ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
1300+
ResolutionError::GenericParamsFromOuterItem(
1301+
res,
1302+
has_generic_params,
1303+
defkind,
1304+
),
12991305
);
13001306
}
13011307
return Res::Err;

compiler/rustc_resolve/src/late.rs

+33-22
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ pub(crate) enum RibKind<'a> {
181181
FnOrCoroutine,
182182

183183
/// We passed through an item scope. Disallow upvars.
184-
Item(HasGenericParams),
184+
/// Note if this is a static/const to help with some confusing diagnostics
185+
Item(HasGenericParams, DefKind),
185186

186187
/// We're in a constant item. Can't refer to dynamic stuff.
187188
///
@@ -221,7 +222,7 @@ impl RibKind<'_> {
221222
| RibKind::MacroDefinition(_)
222223
| RibKind::ConstParamTy
223224
| RibKind::InlineAsmSym => false,
224-
RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true,
225+
RibKind::AssocItem | RibKind::Item(..) | RibKind::ForwardGenericParamBan => true,
225226
}
226227
}
227228

@@ -870,7 +871,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
870871
ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
871872
self.with_generic_param_rib(
872873
&generics.params,
873-
RibKind::Item(HasGenericParams::Yes(generics.span)),
874+
RibKind::Item(HasGenericParams::Yes(generics.span), DefKind::ForeignTy),
874875
LifetimeRibKind::Generics {
875876
binder: foreign_item.id,
876877
kind: LifetimeBinderKind::Item,
@@ -882,7 +883,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
882883
ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
883884
self.with_generic_param_rib(
884885
&generics.params,
885-
RibKind::Item(HasGenericParams::Yes(generics.span)),
886+
RibKind::Item(HasGenericParams::Yes(generics.span), DefKind::Fn),
886887
LifetimeRibKind::Generics {
887888
binder: foreign_item.id,
888889
kind: LifetimeBinderKind::Function,
@@ -891,8 +892,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
891892
|this| visit::walk_foreign_item(this, foreign_item),
892893
);
893894
}
894-
ForeignItemKind::Static(..) => {
895-
self.with_static_rib(|this| {
895+
ForeignItemKind::Static(_, mutability, _) => {
896+
self.with_static_rib(mutability, |this| {
896897
visit::walk_foreign_item(this, foreign_item);
897898
});
898899
}
@@ -2268,10 +2269,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
22682269

22692270
fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) {
22702271
debug!("resolve_adt");
2272+
let kind = match item.kind {
2273+
ItemKind::Enum(_, _) => DefKind::Enum,
2274+
ItemKind::Struct(_, _) => DefKind::Struct,
2275+
ItemKind::Union(_, _) => DefKind::Union,
2276+
// only called if `item` is one of the above
2277+
_ => unreachable!(),
2278+
};
22712279
self.with_current_self_item(item, |this| {
22722280
this.with_generic_param_rib(
22732281
&generics.params,
2274-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2282+
RibKind::Item(HasGenericParams::Yes(generics.span), kind),
22752283
LifetimeRibKind::Generics {
22762284
binder: item.id,
22772285
kind: LifetimeBinderKind::Item,
@@ -2349,7 +2357,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
23492357
ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
23502358
self.with_generic_param_rib(
23512359
&generics.params,
2352-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2360+
RibKind::Item(HasGenericParams::Yes(generics.span), DefKind::TyAlias),
23532361
LifetimeRibKind::Generics {
23542362
binder: item.id,
23552363
kind: LifetimeBinderKind::Item,
@@ -2362,7 +2370,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
23622370
ItemKind::Fn(box Fn { ref generics, .. }) => {
23632371
self.with_generic_param_rib(
23642372
&generics.params,
2365-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2373+
RibKind::Item(HasGenericParams::Yes(generics.span), DefKind::Fn),
23662374
LifetimeRibKind::Generics {
23672375
binder: item.id,
23682376
kind: LifetimeBinderKind::Function,
@@ -2401,7 +2409,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24012409
// Create a new rib for the trait-wide type parameters.
24022410
self.with_generic_param_rib(
24032411
&generics.params,
2404-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2412+
RibKind::Item(HasGenericParams::Yes(generics.span), DefKind::Trait),
24052413
LifetimeRibKind::Generics {
24062414
binder: item.id,
24072415
kind: LifetimeBinderKind::Item,
@@ -2422,7 +2430,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24222430
// Create a new rib for the trait-wide type parameters.
24232431
self.with_generic_param_rib(
24242432
&generics.params,
2425-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2433+
RibKind::Item(HasGenericParams::Yes(generics.span), DefKind::TraitAlias),
24262434
LifetimeRibKind::Generics {
24272435
binder: item.id,
24282436
kind: LifetimeBinderKind::Item,
@@ -2455,8 +2463,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24552463
});
24562464
}
24572465

2458-
ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) => {
2459-
self.with_static_rib(|this| {
2466+
ItemKind::Static(box ast::StaticItem { ref ty, ref expr, mutability }) => {
2467+
self.with_static_rib(mutability, |this| {
24602468
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
24612469
this.visit_ty(ty);
24622470
});
@@ -2471,11 +2479,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24712479
ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
24722480
self.with_generic_param_rib(
24732481
&generics.params,
2474-
RibKind::Item(if self.r.tcx.features().generic_const_items {
2475-
HasGenericParams::Yes(generics.span)
2476-
} else {
2477-
HasGenericParams::No
2478-
}),
2482+
RibKind::Item(
2483+
if self.r.tcx.features().generic_const_items {
2484+
HasGenericParams::Yes(generics.span)
2485+
} else {
2486+
HasGenericParams::No
2487+
},
2488+
DefKind::Const,
2489+
),
24792490
LifetimeRibKind::Generics {
24802491
binder: item.id,
24812492
kind: LifetimeBinderKind::ConstItem,
@@ -2560,7 +2571,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
25602571
let mut add_bindings_for_ns = |ns| {
25612572
let parent_rib = self.ribs[ns]
25622573
.iter()
2563-
.rfind(|r| matches!(r.kind, RibKind::Item(_)))
2574+
.rfind(|r| matches!(r.kind, RibKind::Item(..)))
25642575
.expect("associated item outside of an item");
25652576
seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
25662577
};
@@ -2695,8 +2706,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
26952706
self.label_ribs.pop();
26962707
}
26972708

2698-
fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) {
2699-
let kind = RibKind::Item(HasGenericParams::No);
2709+
fn with_static_rib(&mut self, mutability: Mutability, f: impl FnOnce(&mut Self)) {
2710+
let kind = RibKind::Item(HasGenericParams::No, DefKind::Static(mutability));
27002711
self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
27012712
}
27022713

@@ -2877,7 +2888,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
28772888
// If applicable, create a rib for the type parameters.
28782889
self.with_generic_param_rib(
28792890
&generics.params,
2880-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2891+
RibKind::Item(HasGenericParams::Yes(generics.span), DefKind::Impl { of_trait: opt_trait_reference.is_some() }),
28812892
LifetimeRibKind::Generics {
28822893
span: generics.span,
28832894
binder: item_id,

compiler/rustc_resolve/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ struct BindingError {
185185
#[derive(Debug)]
186186
enum ResolutionError<'a> {
187187
/// Error E0401: can't use type or const parameters from outer item.
188-
GenericParamsFromOuterItem(Res, HasGenericParams),
188+
GenericParamsFromOuterItem(Res, HasGenericParams, DefKind),
189189
/// Error E0403: the name is already used for a type or const parameter in this generic
190190
/// parameter list.
191191
NameAlreadyUsedInParameterList(Symbol, Span),

tests/ui/inner-static-type-parameter.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | fn foo<T>() {
55
| - type parameter from outer item
66
LL | static a: Bar<T> = Bar::What;
77
| ^ use of generic parameter from outer item
8+
|
9+
= note: a `static` is a separate item from the item that contains it
810

911
error[E0392]: parameter `T` is never used
1012
--> $DIR/inner-static-type-parameter.rs:3:10

tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | fn outer<T: Tr>() { // outer function
55
| - type parameter from outer item
66
LL | const K: u32 = T::C;
77
| ^^^^ use of generic parameter from outer item
8+
|
9+
= note: a `const` is a separate item from the item that contains it
810

911
error[E0401]: can't use generic parameters from outer item
1012
--> $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
1416
LL | const C: u32 = {
1517
LL | const I: u32 = T::C;
1618
| ^^^^ use of generic parameter from outer item
19+
|
20+
= note: a `const` is a separate item from the item that contains it
1721

1822
error[E0401]: can't use generic parameters from outer item
1923
--> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20
@@ -22,6 +26,8 @@ LL | struct S<T: Tr>(U32<{ // outer struct
2226
| - type parameter from outer item
2327
LL | const _: u32 = T::C;
2428
| ^^^^ use of generic parameter from outer item
29+
|
30+
= note: a `const` is a separate item from the item that contains it
2531

2632
error: aborting due to 3 previous errors
2733

tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ LL | const K: u32 = T::C;
77
| - ^^^^ use of generic parameter from outer item
88
| |
99
| help: try introducing a local generic parameter here: `<T>`
10+
|
11+
= note: a `const` is a separate item from the item that contains it
1012

1113
error[E0401]: can't use generic parameters from outer item
1214
--> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24
@@ -18,6 +20,8 @@ LL | const I: u32 = T::C;
1820
| - ^^^^ use of generic parameter from outer item
1921
| |
2022
| help: try introducing a local generic parameter here: `<T>`
23+
|
24+
= note: a `const` is a separate item from the item that contains it
2125

2226
error[E0401]: can't use generic parameters from outer item
2327
--> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20
@@ -28,6 +32,8 @@ LL | const _: u32 = T::C;
2832
| - ^^^^ use of generic parameter from outer item
2933
| |
3034
| help: try introducing a local generic parameter here: `<T>`
35+
|
36+
= note: a `const` is a separate item from the item that contains it
3137

3238
error: aborting due to 3 previous errors
3339

tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | unsafe fn foo<A>() {
66
LL | extern "C" {
77
LL | static baz: *const A;
88
| ^ use of generic parameter from outer item
9+
|
10+
= note: a `static` is a separate item from the item that contains it
911

1012
error: aborting due to 1 previous error
1113

0 commit comments

Comments
 (0)