Skip to content

Commit 0240dca

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

11 files changed

+101
-32
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` creates a new item
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` creates a new item
131+
128132
resolve_generic_params_from_outer_item_ty_param = type parameter from outer item
129133
130134

compiler/rustc_resolve/src/diagnostics.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ use crate::late::{PatternSource, Rib};
3636
use crate::path_names_to_string;
3737
use crate::{errors as errs, BindingKey};
3838
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, Finalize};
39-
use crate::{HasGenericParams, MacroRulesScope, Module, ModuleKind, ModuleOrUniformRoot};
39+
use crate::{
40+
HasGenericParams, IsStaticOrConst, MacroRulesScope, Module, ModuleKind, ModuleOrUniformRoot,
41+
};
4042
use crate::{LexicalScopeBinding, NameBinding, NameBindingKind, PrivacyError, VisResolutionError};
4143
use crate::{ParentScope, PathResult, ResolutionError, Resolver, Scope, ScopeSet};
4244
use crate::{Segment, UseError};
@@ -561,15 +563,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
561563
resolution_error: ResolutionError<'a>,
562564
) -> DiagnosticBuilder<'_> {
563565
match resolution_error {
564-
ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => {
566+
ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params, is_static_or_const) => {
565567
use errs::GenericParamsFromOuterItemLabel as Label;
568+
let static_or_const = match is_static_or_const {
569+
IsStaticOrConst::Static => Some(errs::GenericParamsFromOuterItemStaticOrConst::Static),
570+
IsStaticOrConst::Const => Some(errs::GenericParamsFromOuterItemStaticOrConst::Const),
571+
IsStaticOrConst::No => None,
572+
};
566573
let mut err = errs::GenericParamsFromOuterItem {
567574
span,
568575
label: None,
569576
refer_to_type_directly: None,
570577
sugg: None,
578+
static_or_const,
571579
};
572-
573580
let sm = self.tcx.sess.source_map();
574581
let def_id = match outer_res {
575582
Res::SelfTyParam { .. } => {

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

+20-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, is_static_or_const) = match rib.kind {
11591157
RibKind::Normal
11601158
| RibKind::FnOrCoroutine
11611159
| RibKind::Module(..)
@@ -1213,7 +1211,9 @@ 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, is_static_or_const) => {
1215+
(has_generic_params, is_static_or_const)
1216+
}
12171217
RibKind::ConstParamTy => {
12181218
if let Some(span) = finalize {
12191219
self.report_error(
@@ -1231,15 +1231,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12311231
if let Some(span) = finalize {
12321232
self.report_error(
12331233
span,
1234-
ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
1234+
ResolutionError::GenericParamsFromOuterItem(
1235+
res,
1236+
has_generic_params,
1237+
is_static_or_const,
1238+
),
12351239
);
12361240
}
12371241
return Res::Err;
12381242
}
12391243
}
12401244
Res::Def(DefKind::ConstParam, _) => {
12411245
for rib in ribs {
1242-
let has_generic_params = match rib.kind {
1246+
let (has_generic_params, is_static_or_const) = match rib.kind {
12431247
RibKind::Normal
12441248
| RibKind::FnOrCoroutine
12451249
| RibKind::Module(..)
@@ -1276,7 +1280,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12761280
continue;
12771281
}
12781282

1279-
RibKind::Item(has_generic_params) => has_generic_params,
1283+
RibKind::Item(has_generic_params, is_static_or_const) => {
1284+
(has_generic_params, is_static_or_const)
1285+
}
12801286
RibKind::ConstParamTy => {
12811287
if let Some(span) = finalize {
12821288
self.report_error(
@@ -1295,7 +1301,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12951301
if let Some(span) = finalize {
12961302
self.report_error(
12971303
span,
1298-
ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
1304+
ResolutionError::GenericParamsFromOuterItem(
1305+
res,
1306+
has_generic_params,
1307+
is_static_or_const,
1308+
),
12991309
);
13001310
}
13011311
return Res::Err;

compiler/rustc_resolve/src/late.rs

+29-17
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ pub(crate) enum HasGenericParams {
109109
No,
110110
}
111111

112+
/// Is this a `static` or `const` item?
113+
#[derive(Copy, Clone, Debug)]
114+
pub(crate) enum IsStaticOrConst {
115+
No,
116+
Static,
117+
Const,
118+
}
119+
112120
/// May this constant have generics?
113121
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
114122
pub(crate) enum ConstantHasGenerics {
@@ -181,7 +189,8 @@ pub(crate) enum RibKind<'a> {
181189
FnOrCoroutine,
182190

183191
/// We passed through an item scope. Disallow upvars.
184-
Item(HasGenericParams),
192+
/// Note if this is a static/const to help with some confusing diagnostics
193+
Item(HasGenericParams, IsStaticOrConst),
185194

186195
/// We're in a constant item. Can't refer to dynamic stuff.
187196
///
@@ -221,7 +230,7 @@ impl RibKind<'_> {
221230
| RibKind::MacroDefinition(_)
222231
| RibKind::ConstParamTy
223232
| RibKind::InlineAsmSym => false,
224-
RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true,
233+
RibKind::AssocItem | RibKind::Item(..) | RibKind::ForwardGenericParamBan => true,
225234
}
226235
}
227236

@@ -870,7 +879,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
870879
ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
871880
self.with_generic_param_rib(
872881
&generics.params,
873-
RibKind::Item(HasGenericParams::Yes(generics.span)),
882+
RibKind::Item(HasGenericParams::Yes(generics.span), IsStaticOrConst::No),
874883
LifetimeRibKind::Generics {
875884
binder: foreign_item.id,
876885
kind: LifetimeBinderKind::Item,
@@ -882,7 +891,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
882891
ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
883892
self.with_generic_param_rib(
884893
&generics.params,
885-
RibKind::Item(HasGenericParams::Yes(generics.span)),
894+
RibKind::Item(HasGenericParams::Yes(generics.span), IsStaticOrConst::No),
886895
LifetimeRibKind::Generics {
887896
binder: foreign_item.id,
888897
kind: LifetimeBinderKind::Function,
@@ -2271,7 +2280,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
22712280
self.with_current_self_item(item, |this| {
22722281
this.with_generic_param_rib(
22732282
&generics.params,
2274-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2283+
RibKind::Item(HasGenericParams::Yes(generics.span), IsStaticOrConst::No),
22752284
LifetimeRibKind::Generics {
22762285
binder: item.id,
22772286
kind: LifetimeBinderKind::Item,
@@ -2349,7 +2358,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
23492358
ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
23502359
self.with_generic_param_rib(
23512360
&generics.params,
2352-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2361+
RibKind::Item(HasGenericParams::Yes(generics.span), IsStaticOrConst::No),
23532362
LifetimeRibKind::Generics {
23542363
binder: item.id,
23552364
kind: LifetimeBinderKind::Item,
@@ -2362,7 +2371,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
23622371
ItemKind::Fn(box Fn { ref generics, .. }) => {
23632372
self.with_generic_param_rib(
23642373
&generics.params,
2365-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2374+
RibKind::Item(HasGenericParams::Yes(generics.span), IsStaticOrConst::No),
23662375
LifetimeRibKind::Generics {
23672376
binder: item.id,
23682377
kind: LifetimeBinderKind::Function,
@@ -2401,7 +2410,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24012410
// Create a new rib for the trait-wide type parameters.
24022411
self.with_generic_param_rib(
24032412
&generics.params,
2404-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2413+
RibKind::Item(HasGenericParams::Yes(generics.span), IsStaticOrConst::No),
24052414
LifetimeRibKind::Generics {
24062415
binder: item.id,
24072416
kind: LifetimeBinderKind::Item,
@@ -2422,7 +2431,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24222431
// Create a new rib for the trait-wide type parameters.
24232432
self.with_generic_param_rib(
24242433
&generics.params,
2425-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2434+
RibKind::Item(HasGenericParams::Yes(generics.span), IsStaticOrConst::No),
24262435
LifetimeRibKind::Generics {
24272436
binder: item.id,
24282437
kind: LifetimeBinderKind::Item,
@@ -2471,11 +2480,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24712480
ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
24722481
self.with_generic_param_rib(
24732482
&generics.params,
2474-
RibKind::Item(if self.r.tcx.features().generic_const_items {
2475-
HasGenericParams::Yes(generics.span)
2476-
} else {
2477-
HasGenericParams::No
2478-
}),
2483+
RibKind::Item(
2484+
if self.r.tcx.features().generic_const_items {
2485+
HasGenericParams::Yes(generics.span)
2486+
} else {
2487+
HasGenericParams::No
2488+
},
2489+
IsStaticOrConst::Const,
2490+
),
24792491
LifetimeRibKind::Generics {
24802492
binder: item.id,
24812493
kind: LifetimeBinderKind::ConstItem,
@@ -2560,7 +2572,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
25602572
let mut add_bindings_for_ns = |ns| {
25612573
let parent_rib = self.ribs[ns]
25622574
.iter()
2563-
.rfind(|r| matches!(r.kind, RibKind::Item(_)))
2575+
.rfind(|r| matches!(r.kind, RibKind::Item(..)))
25642576
.expect("associated item outside of an item");
25652577
seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
25662578
};
@@ -2696,7 +2708,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
26962708
}
26972709

26982710
fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) {
2699-
let kind = RibKind::Item(HasGenericParams::No);
2711+
let kind = RibKind::Item(HasGenericParams::No, IsStaticOrConst::Static);
27002712
self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
27012713
}
27022714

@@ -2877,7 +2889,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
28772889
// If applicable, create a rib for the type parameters.
28782890
self.with_generic_param_rib(
28792891
&generics.params,
2880-
RibKind::Item(HasGenericParams::Yes(generics.span)),
2892+
RibKind::Item(HasGenericParams::Yes(generics.span), IsStaticOrConst::No),
28812893
LifetimeRibKind::Generics {
28822894
span: generics.span,
28832895
binder: item_id,

compiler/rustc_resolve/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ use std::fmt;
6767

6868
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
6969
use imports::{Import, ImportData, ImportKind, NameResolution};
70-
use late::{HasGenericParams, PathSource, PatternSource};
70+
use late::{HasGenericParams, IsStaticOrConst, PathSource, PatternSource};
7171
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
7272

7373
use crate::effective_visibilities::EffectiveVisibilitiesVisitor;
@@ -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, IsStaticOrConst),
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` creates a new item
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` creates a new item
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` creates a new item
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` creates a new item
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` creates a new item
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` creates a new item
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` creates a new item
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` creates a new item
911

1012
error: aborting due to 1 previous error
1113

0 commit comments

Comments
 (0)