Skip to content

Commit ba2600e

Browse files
committed
Suggest appropriate type instead of Self in E0401
``` error[E0401]: can't use `Self` from outer item --> $DIR/E0401.rs:22:25 | LL | impl<T> Iterator for A<T> { | ---- `Self` type implicitly declared here, by this `impl` ... LL | fn helper(sel: &Self) -> u8 { | ------ ^^^^ use of `Self` from outer item | | | `Self` used in this inner function | help: refer to the type directly here instead | LL - fn helper(sel: &Self) -> u8 { LL + fn helper(sel: &A<T>) -> u8 { | ```
1 parent 35ebdf9 commit ba2600e

File tree

7 files changed

+45
-12
lines changed

7 files changed

+45
-12
lines changed

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: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ pub(crate) struct GenericParamsFromOuterItem {
1717
pub(crate) span: Span,
1818
#[subdiagnostic]
1919
pub(crate) label: Option<GenericParamsFromOuterItemLabel>,
20-
#[label(resolve_refer_to_type_directly)]
21-
pub(crate) refer_to_type_directly: Option<Span>,
20+
#[subdiagnostic]
21+
pub(crate) refer_to_type_directly: Option<UseTypeDirectly>,
2222
#[subdiagnostic]
2323
pub(crate) sugg: Option<GenericParamsFromOuterItemSugg>,
2424
#[subdiagnostic]
@@ -68,6 +68,18 @@ pub(crate) struct GenericParamsFromOuterItemSugg {
6868
pub(crate) span: Span,
6969
pub(crate) snippet: String,
7070
}
71+
#[derive(Subdiagnostic)]
72+
#[suggestion(
73+
resolve_refer_to_type_directly,
74+
code = "{snippet}",
75+
applicability = "maybe-incorrect",
76+
style = "verbose"
77+
)]
78+
pub(crate) struct UseTypeDirectly {
79+
#[primary_span]
80+
pub(crate) span: Span,
81+
pub(crate) snippet: String,
82+
}
7183

7284
#[derive(Diagnostic)]
7385
#[diag(resolve_name_is_already_used_as_generic_parameter, code = E0403)]

compiler/rustc_resolve/src/ident.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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/error-codes/E0401.stderr

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,15 @@ LL | impl<T> Iterator for A<T> {
3737
| ---- `Self` type implicitly declared here, by this `impl`
3838
...
3939
LL | fn helper(sel: &Self) -> u8 {
40-
| ------ ^^^^
41-
| | |
42-
| | use of `Self` from outer item
43-
| | refer to the type directly here instead
40+
| ------ ^^^^ use of `Self` from outer item
41+
| |
4442
| `Self` used in this inner function
43+
|
44+
help: refer to the type directly here instead
45+
|
46+
LL - fn helper(sel: &Self) -> u8 {
47+
LL + fn helper(sel: &A<T>) -> u8 {
48+
|
4549

4650
error: aborting due to 3 previous errors
4751

tests/ui/resolve/use-self-in-inner-fn.stderr

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@ LL | impl A {
55
| ---- `Self` type implicitly declared here, by this `impl`
66
...
77
LL | fn peach(this: &Self) {
8-
| ----- ^^^^
9-
| | |
10-
| | use of `Self` from outer item
11-
| | refer to the type directly here instead
8+
| ----- ^^^^ use of `Self` from outer item
9+
| |
1210
| `Self` used in this inner function
11+
|
12+
help: refer to the type directly here instead
13+
|
14+
LL - fn peach(this: &Self) {
15+
LL + fn peach(this: &A) {
16+
|
1317

1418
error: aborting due to 1 previous error
1519

0 commit comments

Comments
 (0)