Skip to content

Commit bd9c135

Browse files
committed
Structured suggestion for extern crate foo when foo isn't resolved in import
When encountering a name in an import that could have come from a crate that wasn't imported, use a structured suggestion to suggest `extern crate foo;` pointing at the right place in the crate. When encountering `_` in an import, do not suggest `extern crate _;`. ``` error[E0432]: unresolved import `spam` --> $DIR/import-from-missing-star-3.rs:2:9 | LL | use spam::*; | ^^^^ maybe a missing crate `spam`? | help: consider importing the `spam` crate | LL + extern crate spam; | ```
1 parent 2a1c384 commit bd9c135

29 files changed

+174
-62
lines changed

compiler/rustc_resolve/src/def_collector.rs

+1
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
423423
}
424424

425425
fn visit_crate(&mut self, krate: &'a Crate) {
426+
self.resolver.current_crate_outer_attr_insert_span = Some(krate.spans.inject_use_span);
426427
if krate.is_placeholder {
427428
self.visit_macro_invoc(krate.id)
428429
} else {

compiler/rustc_resolve/src/diagnostics.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -2019,16 +2019,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
20192019
Applicability::MaybeIncorrect,
20202020
)),
20212021
)
2022+
} else if ident.name == kw::Underscore {
2023+
(format!("`_` is not a valid crate or module name"), None)
20222024
} else if self.tcx.sess.is_rust_2015() {
20232025
(
20242026
format!("maybe a missing crate `{ident}`?"),
2025-
Some((
2026-
vec![],
2027-
format!(
2028-
"consider adding `extern crate {ident}` to use the `{ident}` crate"
2029-
),
2030-
Applicability::MaybeIncorrect,
2031-
)),
2027+
self.current_crate_outer_attr_insert_span.map(|sp| {
2028+
(
2029+
vec![(sp, format!("extern crate {ident};\n"))],
2030+
format!("consider importing the `{ident}` crate"),
2031+
Applicability::MaybeIncorrect,
2032+
)
2033+
}),
20322034
)
20332035
} else {
20342036
(format!("could not find `{ident}` in the crate root"), None)

compiler/rustc_resolve/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,10 @@ pub struct Resolver<'a, 'tcx> {
11761176
/// Simplified analogue of module `resolutions` but in trait impls, excluding glob delegations.
11771177
/// Needed because glob delegations exclude explicitly defined names.
11781178
impl_binding_keys: FxHashMap<LocalDefId, FxHashSet<BindingKey>>,
1179+
1180+
/// This is the `Span` where an `extern crate foo;` suggestion would be inserted, if `foo`
1181+
/// could be a crate that wasn't imported. For diagnostics use only.
1182+
current_crate_outer_attr_insert_span: Option<Span>,
11791183
}
11801184

11811185
/// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1521,6 +1525,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15211525
glob_delegation_invoc_ids: Default::default(),
15221526
impl_unexpanded_invocations: Default::default(),
15231527
impl_binding_keys: Default::default(),
1528+
current_crate_outer_attr_insert_span: Default::default(),
15241529
};
15251530

15261531
let root_parent_scope = ParentScope::module(graph_root, &resolver);

tests/ui/attributes/field-attributes-vis-unresolved.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
44
LL | pub(in nonexistent) field: u8
55
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
66
|
7-
= help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
7+
help: consider importing the `nonexistent` crate
8+
|
9+
LL + extern crate nonexistent;
10+
|
811

912
error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
1013
--> $DIR/field-attributes-vis-unresolved.rs:22:12
1114
|
1215
LL | pub(in nonexistent) u8
1316
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
1417
|
15-
= help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
18+
help: consider importing the `nonexistent` crate
19+
|
20+
LL + extern crate nonexistent;
21+
|
1622

1723
error: aborting due to 2 previous errors
1824

tests/ui/error-codes/E0432.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `something`
44
LL | use something::Foo;
55
| ^^^^^^^^^ maybe a missing crate `something`?
66
|
7-
= help: consider adding `extern crate something` to use the `something` crate
7+
help: consider importing the `something` crate
8+
|
9+
LL + extern crate something;
10+
|
811

912
error: aborting due to 1 previous error
1013

tests/ui/imports/import-from-missing-star-2.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `spam`
44
LL | use spam::*;
55
| ^^^^ maybe a missing crate `spam`?
66
|
7-
= help: consider adding `extern crate spam` to use the `spam` crate
7+
help: consider importing the `spam` crate
8+
|
9+
LL + extern crate spam;
10+
|
811

912
error: aborting due to 1 previous error
1013

tests/ui/imports/import-from-missing-star-3.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ error[E0432]: unresolved import `spam`
44
LL | use spam::*;
55
| ^^^^ maybe a missing crate `spam`?
66
|
7-
= help: consider adding `extern crate spam` to use the `spam` crate
7+
help: consider importing the `spam` crate
8+
|
9+
LL + extern crate spam;
10+
|
811

912
error[E0432]: unresolved import `spam`
1013
--> $DIR/import-from-missing-star-3.rs:27:13
1114
|
1215
LL | use spam::*;
1316
| ^^^^ maybe a missing crate `spam`?
1417
|
15-
= help: consider adding `extern crate spam` to use the `spam` crate
18+
help: consider importing the `spam` crate
19+
|
20+
LL + extern crate spam;
21+
|
1622

1723
error: aborting due to 2 previous errors
1824

tests/ui/imports/import-from-missing-star.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `spam`
44
LL | use spam::*;
55
| ^^^^ maybe a missing crate `spam`?
66
|
7-
= help: consider adding `extern crate spam` to use the `spam` crate
7+
help: consider importing the `spam` crate
8+
|
9+
LL + extern crate spam;
10+
|
811

912
error: aborting due to 1 previous error
1013

tests/ui/imports/import3.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `main`
44
LL | use main::bar;
55
| ^^^^ maybe a missing crate `main`?
66
|
7-
= help: consider adding `extern crate main` to use the `main` crate
7+
help: consider importing the `main` crate
8+
|
9+
LL + extern crate main;
10+
|
811

912
error: aborting due to 1 previous error
1013

tests/ui/imports/issue-109343.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `unresolved`
44
LL | pub use unresolved::f;
55
| ^^^^^^^^^^ maybe a missing crate `unresolved`?
66
|
7-
= help: consider adding `extern crate unresolved` to use the `unresolved` crate
7+
help: consider importing the `unresolved` crate
8+
|
9+
LL + extern crate unresolved;
10+
|
811

912
error: aborting due to 1 previous error
1013

tests/ui/imports/issue-1697.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `unresolved`
44
LL | use unresolved::*;
55
| ^^^^^^^^^^ maybe a missing crate `unresolved`?
66
|
7-
= help: consider adding `extern crate unresolved` to use the `unresolved` crate
7+
help: consider importing the `unresolved` crate
8+
|
9+
LL + extern crate unresolved;
10+
|
811

912
error: aborting due to 1 previous error
1013

tests/ui/imports/issue-33464.stderr

+12-3
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,32 @@ error[E0432]: unresolved import `abc`
44
LL | use abc::one_el;
55
| ^^^ maybe a missing crate `abc`?
66
|
7-
= help: consider adding `extern crate abc` to use the `abc` crate
7+
help: consider importing the `abc` crate
8+
|
9+
LL + extern crate abc;
10+
|
811

912
error[E0432]: unresolved import `abc`
1013
--> $DIR/issue-33464.rs:5:5
1114
|
1215
LL | use abc::{a, bbb, cccccc};
1316
| ^^^ maybe a missing crate `abc`?
1417
|
15-
= help: consider adding `extern crate abc` to use the `abc` crate
18+
help: consider importing the `abc` crate
19+
|
20+
LL + extern crate abc;
21+
|
1622

1723
error[E0432]: unresolved import `a_very_long_name`
1824
--> $DIR/issue-33464.rs:7:5
1925
|
2026
LL | use a_very_long_name::{el, el2};
2127
| ^^^^^^^^^^^^^^^^ maybe a missing crate `a_very_long_name`?
2228
|
23-
= help: consider adding `extern crate a_very_long_name` to use the `a_very_long_name` crate
29+
help: consider importing the `a_very_long_name` crate
30+
|
31+
LL + extern crate a_very_long_name;
32+
|
2433

2534
error: aborting due to 3 previous errors
2635

tests/ui/imports/issue-36881.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `issue_36881_aux`
44
LL | use issue_36881_aux::Foo;
55
| ^^^^^^^^^^^^^^^ maybe a missing crate `issue_36881_aux`?
66
|
7-
= help: consider adding `extern crate issue_36881_aux` to use the `issue_36881_aux` crate
7+
help: consider importing the `issue_36881_aux` crate
8+
|
9+
LL + extern crate issue_36881_aux;
10+
|
811

912
error: aborting due to 1 previous error
1013

tests/ui/imports/issue-37887.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `test`
44
LL | use test::*;
55
| ^^^^ maybe a missing crate `test`?
66
|
7-
= help: consider adding `extern crate test` to use the `test` crate
7+
help: consider importing the `test` crate
8+
|
9+
LL + extern crate test;
10+
|
811

912
error[E0658]: use of unstable library feature 'test'
1013
--> $DIR/issue-37887.rs:2:5

tests/ui/imports/issue-53269.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `nonexistent_module`
44
LL | use nonexistent_module::mac;
55
| ^^^^^^^^^^^^^^^^^^ maybe a missing crate `nonexistent_module`?
66
|
7-
= help: consider adding `extern crate nonexistent_module` to use the `nonexistent_module` crate
7+
help: consider importing the `nonexistent_module` crate
8+
|
9+
LL + extern crate nonexistent_module;
10+
|
811

912
error[E0659]: `mac` is ambiguous
1013
--> $DIR/issue-53269.rs:8:5

tests/ui/imports/issue-55457.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ error[E0432]: unresolved import `non_existent`
1313
LL | use non_existent::non_existent;
1414
| ^^^^^^^^^^^^ maybe a missing crate `non_existent`?
1515
|
16-
= help: consider adding `extern crate non_existent` to use the `non_existent` crate
16+
help: consider importing the `non_existent` crate
17+
|
18+
LL + extern crate non_existent;
19+
|
1720

1821
error: aborting due to 2 previous errors
1922

tests/ui/imports/issue-81413.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0432]: unresolved import `doesnt_exist`
44
LL | pub use doesnt_exist::*;
55
| ^^^^^^^^^^^^ maybe a missing crate `doesnt_exist`?
66
|
7-
= help: consider adding `extern crate doesnt_exist` to use the `doesnt_exist` crate
7+
help: consider importing the `doesnt_exist` crate
8+
|
9+
LL + extern crate doesnt_exist;
10+
|
811

912
error: aborting due to 1 previous error
1013

tests/ui/imports/tool-mod-child.stderr

+16-4
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,43 @@ error[E0433]: failed to resolve: maybe a missing crate `clippy`?
44
LL | use clippy::a::b;
55
| ^^^^^^ maybe a missing crate `clippy`?
66
|
7-
= help: consider adding `extern crate clippy` to use the `clippy` crate
7+
help: consider importing the `clippy` crate
8+
|
9+
LL + extern crate clippy;
10+
|
811

912
error[E0432]: unresolved import `clippy`
1013
--> $DIR/tool-mod-child.rs:1:5
1114
|
1215
LL | use clippy::a;
1316
| ^^^^^^ maybe a missing crate `clippy`?
1417
|
15-
= help: consider adding `extern crate clippy` to use the `clippy` crate
18+
help: consider importing the `clippy` crate
19+
|
20+
LL + extern crate clippy;
21+
|
1622

1723
error[E0433]: failed to resolve: maybe a missing crate `rustdoc`?
1824
--> $DIR/tool-mod-child.rs:5:5
1925
|
2026
LL | use rustdoc::a::b;
2127
| ^^^^^^^ maybe a missing crate `rustdoc`?
2228
|
23-
= help: consider adding `extern crate rustdoc` to use the `rustdoc` crate
29+
help: consider importing the `rustdoc` crate
30+
|
31+
LL + extern crate rustdoc;
32+
|
2433

2534
error[E0432]: unresolved import `rustdoc`
2635
--> $DIR/tool-mod-child.rs:4:5
2736
|
2837
LL | use rustdoc::a;
2938
| ^^^^^^^ maybe a missing crate `rustdoc`?
3039
|
31-
= help: consider adding `extern crate rustdoc` to use the `rustdoc` crate
40+
help: consider importing the `rustdoc` crate
41+
|
42+
LL + extern crate rustdoc;
43+
|
3244

3345
error: aborting due to 4 previous errors
3446

tests/ui/imports/unresolved-imports-used.stderr

+16-4
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,43 @@ error[E0432]: unresolved import `foo`
1616
LL | use foo::bar;
1717
| ^^^ maybe a missing crate `foo`?
1818
|
19-
= help: consider adding `extern crate foo` to use the `foo` crate
19+
help: consider importing the `foo` crate
20+
|
21+
LL + extern crate foo;
22+
|
2023

2124
error[E0432]: unresolved import `baz`
2225
--> $DIR/unresolved-imports-used.rs:12:5
2326
|
2427
LL | use baz::*;
2528
| ^^^ maybe a missing crate `baz`?
2629
|
27-
= help: consider adding `extern crate baz` to use the `baz` crate
30+
help: consider importing the `baz` crate
31+
|
32+
LL + extern crate baz;
33+
|
2834

2935
error[E0432]: unresolved import `foo2`
3036
--> $DIR/unresolved-imports-used.rs:14:5
3137
|
3238
LL | use foo2::bar2;
3339
| ^^^^ maybe a missing crate `foo2`?
3440
|
35-
= help: consider adding `extern crate foo2` to use the `foo2` crate
41+
help: consider importing the `foo2` crate
42+
|
43+
LL + extern crate foo2;
44+
|
3645

3746
error[E0432]: unresolved import `baz2`
3847
--> $DIR/unresolved-imports-used.rs:15:5
3948
|
4049
LL | use baz2::*;
4150
| ^^^^ maybe a missing crate `baz2`?
4251
|
43-
= help: consider adding `extern crate baz2` to use the `baz2` crate
52+
help: consider importing the `baz2` crate
53+
|
54+
LL + extern crate baz2;
55+
|
4456

4557
error[E0603]: function `quz` is private
4658
--> $DIR/unresolved-imports-used.rs:9:10

tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ error[E0432]: unresolved import `r#extern`
1515
LL | use extern::foo;
1616
| ^^^^^^ maybe a missing crate `r#extern`?
1717
|
18-
= help: consider adding `extern crate r#extern` to use the `r#extern` crate
18+
help: consider importing the `r#extern` crate
19+
|
20+
LL + extern crate r#extern;
21+
|
1922

2023
error: aborting due to 2 previous errors
2124

tests/ui/privacy/restricted/test.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0433]: failed to resolve: maybe a missing crate `bad`?
44
LL | pub(in bad::path) mod m1 {}
55
| ^^^ maybe a missing crate `bad`?
66
|
7-
= help: consider adding `extern crate bad` to use the `bad` crate
7+
help: consider importing the `bad` crate
8+
|
9+
LL + extern crate bad;
10+
|
811

912
error[E0742]: visibilities can only be restricted to ancestor modules
1013
--> $DIR/test.rs:51:12

0 commit comments

Comments
 (0)