Skip to content

Commit 9a7979d

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 9a7979d

30 files changed

+178
-63
lines changed

compiler/rustc_resolve/src/def_collector.rs

Lines changed: 1 addition & 0 deletions
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

Lines changed: 9 additions & 7 deletions
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

Lines changed: 5 additions & 0 deletions
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/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`?
44
LL | use unresolved_crate::module::Name;
55
| ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`?
66
|
7-
= help: consider adding `extern crate unresolved_crate` to use the `unresolved_crate` crate
7+
help: consider importing the `unresolved_crate` crate
8+
|
9+
LL + extern crate unresolved_crate;
10+
|
811

912
error: aborting due to 1 previous error
1013

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

Lines changed: 8 additions & 2 deletions
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

Lines changed: 4 additions & 1 deletion
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

Lines changed: 4 additions & 1 deletion
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

Lines changed: 8 additions & 2 deletions
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

Lines changed: 4 additions & 1 deletion
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

Lines changed: 4 additions & 1 deletion
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

0 commit comments

Comments
 (0)