Skip to content

Commit 84a4421

Browse files
committed
Suggest fixes for use foo::self
1 parent 672b272 commit 84a4421

File tree

7 files changed

+97
-19
lines changed

7 files changed

+97
-19
lines changed

src/librustc_resolve/build_reduced_graph.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,24 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
435435
} else {
436436
// Disallow `self`
437437
if source.ident.name == kw::SelfLower {
438+
let parent = module_path.last();
439+
440+
let span = match parent {
441+
// only `::self` from `use foo::self as bar`
442+
Some(seg) => seg.ident.span.shrink_to_hi().to(source.ident.span),
443+
None => source.ident.span,
444+
};
445+
let span_with_rename = match rename {
446+
// only `self as bar` from `use foo::self as bar`
447+
Some(rename) => source.ident.span.to(rename.span),
448+
None => source.ident.span,
449+
};
438450
self.r.report_error(
439-
use_tree.span,
440-
ResolutionError::SelfImportsOnlyAllowedWithin,
451+
span,
452+
ResolutionError::SelfImportsOnlyAllowedWithin {
453+
root: parent.is_none(),
454+
span_with_rename,
455+
},
441456
);
442457
}
443458

src/librustc_resolve/diagnostics.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,40 @@ impl<'a> Resolver<'a> {
301301
}
302302
err
303303
}
304-
ResolutionError::SelfImportsOnlyAllowedWithin => struct_span_err!(
305-
self.session,
306-
span,
307-
E0429,
308-
"{}",
309-
"`self` imports are only allowed within a { } list"
310-
),
304+
ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => {
305+
let mut err = struct_span_err!(
306+
self.session,
307+
span,
308+
E0429,
309+
"{}",
310+
"`self` imports are only allowed within a { } list"
311+
);
312+
313+
// None of the suggestions below would help with a case like `use self`.
314+
if !root {
315+
// use foo::bar::self -> foo::bar
316+
// use foo::bar::self as abc -> foo::bar as abc
317+
err.span_suggestion(
318+
span,
319+
"Remove `::self`..",
320+
"".to_string(),
321+
Applicability::MachineApplicable,
322+
);
323+
324+
// use foo::bar::self -> foo::bar::{self}
325+
// use foo::bar::self as abc -> foo::bar::{self as abc}
326+
let braces = vec![
327+
(span_with_rename.shrink_to_lo(), "{".to_string()),
328+
(span_with_rename.shrink_to_hi(), "}".to_string()),
329+
];
330+
err.multipart_suggestion(
331+
"..or add braces around `self`",
332+
braces,
333+
Applicability::MachineApplicable,
334+
);
335+
}
336+
err
337+
}
311338
ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
312339
let mut err = struct_span_err!(
313340
self.session,

src/librustc_resolve/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ enum ResolutionError<'a> {
194194
/// Error E0426: use of undeclared label.
195195
UndeclaredLabel(&'a str, Option<Symbol>),
196196
/// Error E0429: `self` imports are only allowed within a `{ }` list.
197-
SelfImportsOnlyAllowedWithin,
197+
SelfImportsOnlyAllowedWithin { root: bool, span_with_rename: Span },
198198
/// Error E0430: `self` import can only appear once in the list.
199199
SelfImportCanOnlyAppearOnceInTheList,
200200
/// Error E0431: `self` import can only appear in an import list with a non-empty prefix.

src/test/ui/error-codes/E0429.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
error[E0429]: `self` imports are only allowed within a { } list
2-
--> $DIR/E0429.rs:1:5
2+
--> $DIR/E0429.rs:1:13
33
|
44
LL | use std::fmt::self;
5-
| ^^^^^^^^^^^^^^
5+
| ^^^^^^
6+
|
7+
help: Remove `::self`..
8+
|
9+
LL | use std::fmt;
10+
| --
11+
help: ..or add braces around `self`
12+
|
13+
LL | use std::fmt::{self};
14+
| ^ ^
615

716
error: aborting due to previous error
817

src/test/ui/issues/issue-45829/import-self.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@ LL | use foo as self;
55
| ^^^^ expected identifier, found keyword
66

77
error[E0429]: `self` imports are only allowed within a { } list
8-
--> $DIR/import-self.rs:12:5
8+
--> $DIR/import-self.rs:12:8
99
|
1010
LL | use foo::self;
11-
| ^^^^^^^^^
11+
| ^^^^^^
12+
|
13+
help: Remove `::self`..
14+
|
15+
LL | use foo;
16+
| --
17+
help: ..or add braces around `self`
18+
|
19+
LL | use foo::{self};
20+
| ^ ^
1221

1322
error[E0255]: the name `foo` is defined multiple times
1423
--> $DIR/import-self.rs:6:11

src/test/ui/use/use-keyword.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0429]: `self` imports are only allowed within a { } list
22
--> $DIR/use-keyword.rs:6:13
33
|
44
LL | use self as A;
5-
| ^^^^^^^^^
5+
| ^^^^
66

77
error[E0432]: unresolved import `super`
88
--> $DIR/use-keyword.rs:8:13

src/test/ui/use/use-mod/use-mod-4.stderr

+22-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
11
error[E0429]: `self` imports are only allowed within a { } list
2-
--> $DIR/use-mod-4.rs:1:5
2+
--> $DIR/use-mod-4.rs:1:8
33
|
44
LL | use foo::self;
5-
| ^^^^^^^^^
5+
| ^^^^^^
6+
|
7+
help: Remove `::self`..
8+
|
9+
LL | use foo;
10+
| --
11+
help: ..or add braces around `self`
12+
|
13+
LL | use foo::{self};
14+
| ^ ^
615

716
error[E0429]: `self` imports are only allowed within a { } list
8-
--> $DIR/use-mod-4.rs:4:5
17+
--> $DIR/use-mod-4.rs:4:13
918
|
1019
LL | use std::mem::self;
11-
| ^^^^^^^^^^^^^^
20+
| ^^^^^^
21+
|
22+
help: Remove `::self`..
23+
|
24+
LL | use std::mem;
25+
| --
26+
help: ..or add braces around `self`
27+
|
28+
LL | use std::mem::{self};
29+
| ^ ^
1230

1331
error[E0432]: unresolved import `foo`
1432
--> $DIR/use-mod-4.rs:1:5

0 commit comments

Comments
 (0)