Skip to content

Commit 7493828

Browse files
committed
Emit a single error when importing a path with _
When encountering `use _;`, `use _::*'` or similar, do not emit two errors for that single mistake. This also side-steps the issue of resolve errors suggesting adding a crate named `_` to `Cargo.toml`.
1 parent a56bf51 commit 7493828

File tree

6 files changed

+42
-95
lines changed

6 files changed

+42
-95
lines changed

compiler/rustc_resolve/src/imports.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
608608
}
609609
}
610610

611-
self.throw_unresolved_import_error(errors, glob_error);
611+
if !errors.is_empty() {
612+
self.throw_unresolved_import_error(errors, glob_error);
613+
}
612614
}
613615

614616
pub(crate) fn check_hidden_glob_reexports(
@@ -683,38 +685,50 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
683685
mut errors: Vec<(Import<'_>, UnresolvedImportError)>,
684686
glob_error: bool,
685687
) {
688+
let span_and_message = |errors: &[(Import<'_>, UnresolvedImportError)]| {
689+
let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
690+
691+
let paths = errors
692+
.iter()
693+
.map(|(import, err)| {
694+
let path = import_path_to_string(
695+
&import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
696+
&import.kind,
697+
err.span,
698+
);
699+
format!("`{path}`")
700+
})
701+
.collect::<Vec<_>>();
702+
let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
703+
(span, msg)
704+
};
705+
706+
let (span, msg) = span_and_message(&errors);
707+
686708
errors.retain(|(_import, err)| match err.module {
687709
// Skip `use` errors for `use foo::Bar;` if `foo.rs` has unrecovered parse errors.
688710
Some(def_id) if self.mods_with_parse_errors.contains(&def_id) => false,
689-
_ => true,
711+
// If we've encountered something like `use _;`, we've already emitted an error stating
712+
// that `_` is not a valid identifier, so we silence the resolve error.
713+
_ => err.segment != Some(kw::Underscore),
690714
});
715+
691716
if errors.is_empty() {
717+
struct_span_code_err!(self.dcx(), span, E0432, "{msg}").delay_as_bug();
692718
return;
693719
}
694720

695-
/// Upper limit on the number of `span_label` messages.
696-
const MAX_LABEL_COUNT: usize = 10;
697-
698-
let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
699-
let paths = errors
700-
.iter()
701-
.map(|(import, err)| {
702-
let path = import_path_to_string(
703-
&import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
704-
&import.kind,
705-
err.span,
706-
);
707-
format!("`{path}`")
708-
})
709-
.collect::<Vec<_>>();
710-
let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
721+
let (span, msg) = span_and_message(&errors);
711722

712723
let mut diag = struct_span_code_err!(self.dcx(), span, E0432, "{msg}");
713724

714725
if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
715726
diag.note(note.clone());
716727
}
717728

729+
/// Upper limit on the number of `span_label` messages.
730+
const MAX_LABEL_COUNT: usize = 10;
731+
718732
for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
719733
if let Some(label) = err.label {
720734
diag.span_label(err.span, label);

tests/ui/imports/multiple-extern-by-macro-for-underscore.ed2015.stderr

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,5 @@ error: expected identifier, found reserved identifier `_`
44
LL | use ::_;
55
| ^ expected identifier, found reserved identifier
66

7-
error[E0432]: unresolved import `_`
8-
--> $DIR/multiple-extern-by-macro-for-underscore.rs:18:9
9-
|
10-
LL | use ::_;
11-
| ^^^ no `_` in the root
12-
13-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
148

15-
For more information about this error, try `rustc --explain E0432`.

tests/ui/imports/multiple-extern-by-macro-for-underscore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ macro_rules! m {
1515
m!();
1616

1717
fn main() {
18-
use ::_; //[ed2015]~ ERROR: unresolved import `_`
18+
use ::_;
1919
//~^ ERROR: expected identifier, found reserved identifier `_`
2020
}

tests/ui/underscore-imports/issue-110164.ed2015.stderr

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ LL | use _::a;
55
| ^ expected identifier, found reserved identifier
66

77
error: expected identifier, found reserved identifier `_`
8-
--> $DIR/issue-110164.rs:11:5
8+
--> $DIR/issue-110164.rs:10:5
99
|
1010
LL | use _::*;
1111
| ^ expected identifier, found reserved identifier
1212

1313
error: expected identifier, found reserved identifier `_`
14-
--> $DIR/issue-110164.rs:16:9
14+
--> $DIR/issue-110164.rs:14:9
1515
|
1616
LL | use _::a;
1717
| ^ expected identifier, found reserved identifier
1818

1919
error: expected identifier, found reserved identifier `_`
20-
--> $DIR/issue-110164.rs:19:9
20+
--> $DIR/issue-110164.rs:16:9
2121
|
2222
LL | use _::*;
2323
| ^ expected identifier, found reserved identifier
@@ -34,30 +34,6 @@ error[E0432]: unresolved import `crate::*`
3434
LL | use crate::*;
3535
| ^^^^^^^^ cannot glob-import a module into itself
3636

37-
error[E0432]: unresolved import `_`
38-
--> $DIR/issue-110164.rs:11:5
39-
|
40-
LL | use _::*;
41-
| ^ `_` is not a valid crate or module name
42-
43-
error[E0432]: unresolved import `_`
44-
--> $DIR/issue-110164.rs:8:5
45-
|
46-
LL | use _::a;
47-
| ^ `_` is not a valid crate or module name
48-
49-
error[E0432]: unresolved import `_`
50-
--> $DIR/issue-110164.rs:16:9
51-
|
52-
LL | use _::a;
53-
| ^ `_` is not a valid crate or module name
54-
55-
error[E0432]: unresolved import `_`
56-
--> $DIR/issue-110164.rs:19:9
57-
|
58-
LL | use _::*;
59-
| ^ `_` is not a valid crate or module name
60-
61-
error: aborting due to 10 previous errors
37+
error: aborting due to 6 previous errors
6238

6339
For more information about this error, try `rustc --explain E0432`.

tests/ui/underscore-imports/issue-110164.ed2021.stderr

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ LL | use _::a;
55
| ^ expected identifier, found reserved identifier
66

77
error: expected identifier, found reserved identifier `_`
8-
--> $DIR/issue-110164.rs:11:5
8+
--> $DIR/issue-110164.rs:10:5
99
|
1010
LL | use _::*;
1111
| ^ expected identifier, found reserved identifier
1212

1313
error: expected identifier, found reserved identifier `_`
14-
--> $DIR/issue-110164.rs:16:9
14+
--> $DIR/issue-110164.rs:14:9
1515
|
1616
LL | use _::a;
1717
| ^ expected identifier, found reserved identifier
1818

1919
error: expected identifier, found reserved identifier `_`
20-
--> $DIR/issue-110164.rs:19:9
20+
--> $DIR/issue-110164.rs:16:9
2121
|
2222
LL | use _::*;
2323
| ^ expected identifier, found reserved identifier
@@ -34,38 +34,6 @@ error[E0432]: unresolved import `crate::*`
3434
LL | use crate::*;
3535
| ^^^^^^^^ cannot glob-import a module into itself
3636

37-
error[E0432]: unresolved import `_`
38-
--> $DIR/issue-110164.rs:11:5
39-
|
40-
LL | use _::*;
41-
| ^ use of unresolved module or unlinked crate `_`
42-
|
43-
= help: you might be missing a crate named `_`
44-
45-
error[E0432]: unresolved import `_`
46-
--> $DIR/issue-110164.rs:8:5
47-
|
48-
LL | use _::a;
49-
| ^ use of unresolved module or unlinked crate `_`
50-
|
51-
= help: you might be missing a crate named `_`
52-
53-
error[E0432]: unresolved import `_`
54-
--> $DIR/issue-110164.rs:16:9
55-
|
56-
LL | use _::a;
57-
| ^ use of unresolved module or unlinked crate `_`
58-
|
59-
= help: you might be missing a crate named `_`
60-
61-
error[E0432]: unresolved import `_`
62-
--> $DIR/issue-110164.rs:19:9
63-
|
64-
LL | use _::*;
65-
| ^ use of unresolved module or unlinked crate `_`
66-
|
67-
= help: you might be missing a crate named `_`
68-
69-
error: aborting due to 10 previous errors
37+
error: aborting due to 6 previous errors
7038

7139
For more information about this error, try `rustc --explain E0432`.

tests/ui/underscore-imports/issue-110164.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,12 @@ use crate::*;
77
//~^ ERROR unresolved import `crate::*`
88
use _::a;
99
//~^ ERROR expected identifier, found reserved identifier `_`
10-
//~| ERROR unresolved import `_`
1110
use _::*;
1211
//~^ ERROR expected identifier, found reserved identifier `_`
13-
//~| ERROR unresolved import `_`
1412

1513
fn main() {
1614
use _::a;
1715
//~^ ERROR expected identifier, found reserved identifier `_`
18-
//~| ERROR unresolved import `_`
1916
use _::*;
2017
//~^ ERROR expected identifier, found reserved identifier `_`
21-
//~| ERROR unresolved import `_`
2218
}

0 commit comments

Comments
 (0)