Skip to content

Commit bcf227a

Browse files
authored
Rollup merge of rust-lang#148447 - estebank:outer-param-2, r=jackh726
Tweak E0401 More accurate span pointing at use place of outer param (at ident instead of full path). Add note explaining why outer item params can't be used in inner item. Use structured suggestion for what `Self` should have been. Follow up to rust-lang#148370. Fix rust-lang#37892.
2 parents b93b0d2 + 14646ec commit bcf227a

29 files changed

+140
-27
lines changed

compiler/rustc_resolve/messages.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ resolve_generic_params_from_outer_item =
175175
} from outer item
176176
.refer_to_type_directly = refer to the type directly here instead
177177
.suggestion = try introducing a local generic parameter here
178+
.note = nested items are independent from their parent item for everything except for privacy and name resolution
178179
179180
resolve_generic_params_from_outer_item_const = a `const` is a separate item from the item that contains it
180181

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
558558
has_generic_params,
559559
def_kind,
560560
inner_item,
561+
current_self_ty,
561562
} => {
562563
use errs::GenericParamsFromOuterItemLabel as Label;
563564
let static_or_const = match def_kind {
@@ -595,7 +596,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
595596
sm,
596597
self.def_span(def_id),
597598
)));
598-
err.refer_to_type_directly = Some(span);
599+
err.refer_to_type_directly =
600+
current_self_ty.map(|snippet| errs::UseTypeDirectly { span, snippet });
599601
return self.dcx().create_err(err);
600602
}
601603
Res::Def(DefKind::TyParam, def_id) => {

compiler/rustc_resolve/src/errors.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ use crate::{Res, fluent_generated as fluent};
1111

1212
#[derive(Diagnostic)]
1313
#[diag(resolve_generic_params_from_outer_item, code = E0401)]
14+
#[note]
1415
pub(crate) struct GenericParamsFromOuterItem {
1516
#[primary_span]
1617
#[label]
1718
pub(crate) span: Span,
1819
#[subdiagnostic]
1920
pub(crate) label: Option<GenericParamsFromOuterItemLabel>,
20-
#[label(resolve_refer_to_type_directly)]
21-
pub(crate) refer_to_type_directly: Option<Span>,
21+
#[subdiagnostic]
22+
pub(crate) refer_to_type_directly: Option<UseTypeDirectly>,
2223
#[subdiagnostic]
2324
pub(crate) sugg: Option<GenericParamsFromOuterItemSugg>,
2425
#[subdiagnostic]
@@ -68,6 +69,18 @@ pub(crate) struct GenericParamsFromOuterItemSugg {
6869
pub(crate) span: Span,
6970
pub(crate) snippet: String,
7071
}
72+
#[derive(Subdiagnostic)]
73+
#[suggestion(
74+
resolve_refer_to_type_directly,
75+
code = "{snippet}",
76+
applicability = "maybe-incorrect",
77+
style = "verbose"
78+
)]
79+
pub(crate) struct UseTypeDirectly {
80+
#[primary_span]
81+
pub(crate) span: Span,
82+
pub(crate) snippet: String,
83+
}
7184

7285
#[derive(Diagnostic)]
7386
#[diag(resolve_name_is_already_used_as_generic_parameter, code = E0403)]

compiler/rustc_resolve/src/ident.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
326326
i,
327327
rib_ident,
328328
*res,
329-
finalize.map(|finalize| finalize.path_span),
329+
finalize.map(|_| general_span),
330330
*original_rib_ident_def,
331331
ribs,
332332
diag_metadata,
@@ -1415,6 +1415,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14151415
has_generic_params,
14161416
def_kind,
14171417
inner_item: item,
1418+
current_self_ty: diag_metadata
1419+
.and_then(|m| m.current_self_type.as_ref())
1420+
.and_then(|ty| {
1421+
self.tcx.sess.source_map().span_to_snippet(ty.span).ok()
1422+
}),
14181423
},
14191424
);
14201425
}
@@ -1503,6 +1508,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15031508
has_generic_params,
15041509
def_kind,
15051510
inner_item: item,
1511+
current_self_ty: diag_metadata
1512+
.and_then(|m| m.current_self_type.as_ref())
1513+
.and_then(|ty| {
1514+
self.tcx.sess.source_map().span_to_snippet(ty.span).ok()
1515+
}),
15061516
},
15071517
);
15081518
}

compiler/rustc_resolve/src/late.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ pub(crate) struct DiagMetadata<'ast> {
675675
current_trait_assoc_items: Option<&'ast [Box<AssocItem>]>,
676676

677677
/// The current self type if inside an impl (used for better errors).
678-
current_self_type: Option<Ty>,
678+
pub(crate) current_self_type: Option<Ty>,
679679

680680
/// The current self item if inside an ADT (used for better errors).
681681
current_self_item: Option<NodeId>,

compiler/rustc_resolve/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ enum ResolutionError<'ra> {
246246
has_generic_params: HasGenericParams,
247247
def_kind: DefKind,
248248
inner_item: Option<(Span, ast::ItemKind)>,
249+
current_self_ty: Option<String>,
249250
},
250251
/// Error E0403: the name is already used for a type or const parameter in this generic
251252
/// parameter list.

tests/ui/associated-item/associated-item-duplicate-bounds.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: generic parameters may not be used in const operations
22
--> $DIR/associated-item-duplicate-bounds.rs:7:18
33
|
44
LL | links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
5-
| ^^^^^^^^ cannot perform const operation using `A`
5+
| ^ cannot perform const operation using `A`
66
|
77
= note: type parameters may not be used in const expressions
88
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

tests/ui/const-generics/early/const-param-from-outer-fn.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | fn bar() -> u32 {
88
LL | X
99
| ^ use of generic parameter from outer item
1010
|
11+
= note: nested items are independent from their parent item for everything except for privacy and name resolution
1112
help: try introducing a local generic parameter here
1213
|
1314
LL | fn bar<X>() -> u32 {

tests/ui/delegation/target-expr.stderr

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ LL | reuse Trait::static_method {
77
| ------------- generic parameter used in this inner delegated function
88
LL |
99
LL | let _ = T::Default();
10-
| ^^^^^^^^^^ use of generic parameter from outer item
10+
| ^ use of generic parameter from outer item
11+
|
12+
= note: nested items are independent from their parent item for everything except for privacy and name resolution
1113

1214
error[E0434]: can't capture dynamic environment in a fn item
1315
--> $DIR/target-expr.rs:26:17

tests/ui/error-codes/E0401.stderr

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
88
| |
99
| generic parameter used in this inner function
1010
|
11+
= note: nested items are independent from their parent item for everything except for privacy and name resolution
1112
help: try introducing a local generic parameter here
1213
|
1314
LL | fn bfnr<T, U, V: Baz<U>, W: Fn()>(y: T) {
@@ -25,6 +26,7 @@ LL | fn baz<U,
2526
LL | (y: T) {
2627
| ^ use of generic parameter from outer item
2728
|
29+
= note: nested items are independent from their parent item for everything except for privacy and name resolution
2830
help: try introducing a local generic parameter here
2931
|
3032
LL | fn baz<T, U,
@@ -37,11 +39,16 @@ LL | impl<T> Iterator for A<T> {
3739
| ---- `Self` type implicitly declared here, by this `impl`
3840
...
3941
LL | fn helper(sel: &Self) -> u8 {
40-
| ------ ^^^^
41-
| | |
42-
| | use of `Self` from outer item
43-
| | refer to the type directly here instead
42+
| ------ ^^^^ use of `Self` from outer item
43+
| |
4444
| `Self` used in this inner function
45+
|
46+
= note: nested items are independent from their parent item for everything except for privacy and name resolution
47+
help: refer to the type directly here instead
48+
|
49+
LL - fn helper(sel: &Self) -> u8 {
50+
LL + fn helper(sel: &A<T>) -> u8 {
51+
|
4552

4653
error: aborting due to 3 previous errors
4754

0 commit comments

Comments
 (0)