Skip to content

Commit

Permalink
Structured suggestion for extern crate foo when foo isn't resolve…
Browse files Browse the repository at this point in the history
…d 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;
   |
```
  • Loading branch information
estebank committed Jul 24, 2024
1 parent 2a1c384 commit 9a7979d
Show file tree
Hide file tree
Showing 30 changed files with 178 additions and 63 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
}

fn visit_crate(&mut self, krate: &'a Crate) {
self.resolver.current_crate_outer_attr_insert_span = Some(krate.spans.inject_use_span);
if krate.is_placeholder {
self.visit_macro_invoc(krate.id)
} else {
Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2019,16 +2019,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Applicability::MaybeIncorrect,
)),
)
} else if ident.name == kw::Underscore {
(format!("`_` is not a valid crate or module name"), None)
} else if self.tcx.sess.is_rust_2015() {
(
format!("maybe a missing crate `{ident}`?"),
Some((
vec![],
format!(
"consider adding `extern crate {ident}` to use the `{ident}` crate"
),
Applicability::MaybeIncorrect,
)),
self.current_crate_outer_attr_insert_span.map(|sp| {
(
vec![(sp, format!("extern crate {ident};\n"))],
format!("consider importing the `{ident}` crate"),
Applicability::MaybeIncorrect,
)
}),
)
} else {
(format!("could not find `{ident}` in the crate root"), None)
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,10 @@ pub struct Resolver<'a, 'tcx> {
/// Simplified analogue of module `resolutions` but in trait impls, excluding glob delegations.
/// Needed because glob delegations exclude explicitly defined names.
impl_binding_keys: FxHashMap<LocalDefId, FxHashSet<BindingKey>>,

/// This is the `Span` where an `extern crate foo;` suggestion would be inserted, if `foo`
/// could be a crate that wasn't imported. For diagnostics use only.
current_crate_outer_attr_insert_span: Option<Span>,
}

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

let root_parent_scope = ParentScope::module(graph_root, &resolver);
Expand Down
5 changes: 4 additions & 1 deletion tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`?
LL | use unresolved_crate::module::Name;
| ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`?
|
= help: consider adding `extern crate unresolved_crate` to use the `unresolved_crate` crate
help: consider importing the `unresolved_crate` crate
|
LL + extern crate unresolved_crate;
|

error: aborting due to 1 previous error

Expand Down
10 changes: 8 additions & 2 deletions tests/ui/attributes/field-attributes-vis-unresolved.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
LL | pub(in nonexistent) field: u8
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
|
= help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
help: consider importing the `nonexistent` crate
|
LL + extern crate nonexistent;
|

error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
--> $DIR/field-attributes-vis-unresolved.rs:22:12
|
LL | pub(in nonexistent) u8
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
|
= help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
help: consider importing the `nonexistent` crate
|
LL + extern crate nonexistent;
|

error: aborting due to 2 previous errors

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/error-codes/E0432.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `something`
LL | use something::Foo;
| ^^^^^^^^^ maybe a missing crate `something`?
|
= help: consider adding `extern crate something` to use the `something` crate
help: consider importing the `something` crate
|
LL + extern crate something;
|

error: aborting due to 1 previous error

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/import-from-missing-star-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `spam`
LL | use spam::*;
| ^^^^ maybe a missing crate `spam`?
|
= help: consider adding `extern crate spam` to use the `spam` crate
help: consider importing the `spam` crate
|
LL + extern crate spam;
|

error: aborting due to 1 previous error

Expand Down
10 changes: 8 additions & 2 deletions tests/ui/imports/import-from-missing-star-3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ error[E0432]: unresolved import `spam`
LL | use spam::*;
| ^^^^ maybe a missing crate `spam`?
|
= help: consider adding `extern crate spam` to use the `spam` crate
help: consider importing the `spam` crate
|
LL + extern crate spam;
|

error[E0432]: unresolved import `spam`
--> $DIR/import-from-missing-star-3.rs:27:13
|
LL | use spam::*;
| ^^^^ maybe a missing crate `spam`?
|
= help: consider adding `extern crate spam` to use the `spam` crate
help: consider importing the `spam` crate
|
LL + extern crate spam;
|

error: aborting due to 2 previous errors

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/import-from-missing-star.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `spam`
LL | use spam::*;
| ^^^^ maybe a missing crate `spam`?
|
= help: consider adding `extern crate spam` to use the `spam` crate
help: consider importing the `spam` crate
|
LL + extern crate spam;
|

error: aborting due to 1 previous error

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/import3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `main`
LL | use main::bar;
| ^^^^ maybe a missing crate `main`?
|
= help: consider adding `extern crate main` to use the `main` crate
help: consider importing the `main` crate
|
LL + extern crate main;
|

error: aborting due to 1 previous error

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/issue-109343.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `unresolved`
LL | pub use unresolved::f;
| ^^^^^^^^^^ maybe a missing crate `unresolved`?
|
= help: consider adding `extern crate unresolved` to use the `unresolved` crate
help: consider importing the `unresolved` crate
|
LL + extern crate unresolved;
|

error: aborting due to 1 previous error

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/issue-1697.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `unresolved`
LL | use unresolved::*;
| ^^^^^^^^^^ maybe a missing crate `unresolved`?
|
= help: consider adding `extern crate unresolved` to use the `unresolved` crate
help: consider importing the `unresolved` crate
|
LL + extern crate unresolved;
|

error: aborting due to 1 previous error

Expand Down
15 changes: 12 additions & 3 deletions tests/ui/imports/issue-33464.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,32 @@ error[E0432]: unresolved import `abc`
LL | use abc::one_el;
| ^^^ maybe a missing crate `abc`?
|
= help: consider adding `extern crate abc` to use the `abc` crate
help: consider importing the `abc` crate
|
LL + extern crate abc;
|

error[E0432]: unresolved import `abc`
--> $DIR/issue-33464.rs:5:5
|
LL | use abc::{a, bbb, cccccc};
| ^^^ maybe a missing crate `abc`?
|
= help: consider adding `extern crate abc` to use the `abc` crate
help: consider importing the `abc` crate
|
LL + extern crate abc;
|

error[E0432]: unresolved import `a_very_long_name`
--> $DIR/issue-33464.rs:7:5
|
LL | use a_very_long_name::{el, el2};
| ^^^^^^^^^^^^^^^^ maybe a missing crate `a_very_long_name`?
|
= help: consider adding `extern crate a_very_long_name` to use the `a_very_long_name` crate
help: consider importing the `a_very_long_name` crate
|
LL + extern crate a_very_long_name;
|

error: aborting due to 3 previous errors

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/issue-36881.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `issue_36881_aux`
LL | use issue_36881_aux::Foo;
| ^^^^^^^^^^^^^^^ maybe a missing crate `issue_36881_aux`?
|
= help: consider adding `extern crate issue_36881_aux` to use the `issue_36881_aux` crate
help: consider importing the `issue_36881_aux` crate
|
LL + extern crate issue_36881_aux;
|

error: aborting due to 1 previous error

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/issue-37887.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `test`
LL | use test::*;
| ^^^^ maybe a missing crate `test`?
|
= help: consider adding `extern crate test` to use the `test` crate
help: consider importing the `test` crate
|
LL + extern crate test;
|

error[E0658]: use of unstable library feature 'test'
--> $DIR/issue-37887.rs:2:5
Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/issue-53269.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `nonexistent_module`
LL | use nonexistent_module::mac;
| ^^^^^^^^^^^^^^^^^^ maybe a missing crate `nonexistent_module`?
|
= help: consider adding `extern crate nonexistent_module` to use the `nonexistent_module` crate
help: consider importing the `nonexistent_module` crate
|
LL + extern crate nonexistent_module;
|

error[E0659]: `mac` is ambiguous
--> $DIR/issue-53269.rs:8:5
Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/issue-55457.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ error[E0432]: unresolved import `non_existent`
LL | use non_existent::non_existent;
| ^^^^^^^^^^^^ maybe a missing crate `non_existent`?
|
= help: consider adding `extern crate non_existent` to use the `non_existent` crate
help: consider importing the `non_existent` crate
|
LL + extern crate non_existent;
|

error: aborting due to 2 previous errors

Expand Down
5 changes: 4 additions & 1 deletion tests/ui/imports/issue-81413.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0432]: unresolved import `doesnt_exist`
LL | pub use doesnt_exist::*;
| ^^^^^^^^^^^^ maybe a missing crate `doesnt_exist`?
|
= help: consider adding `extern crate doesnt_exist` to use the `doesnt_exist` crate
help: consider importing the `doesnt_exist` crate
|
LL + extern crate doesnt_exist;
|

error: aborting due to 1 previous error

Expand Down
20 changes: 16 additions & 4 deletions tests/ui/imports/tool-mod-child.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,43 @@ error[E0433]: failed to resolve: maybe a missing crate `clippy`?
LL | use clippy::a::b;
| ^^^^^^ maybe a missing crate `clippy`?
|
= help: consider adding `extern crate clippy` to use the `clippy` crate
help: consider importing the `clippy` crate
|
LL + extern crate clippy;
|

error[E0432]: unresolved import `clippy`
--> $DIR/tool-mod-child.rs:1:5
|
LL | use clippy::a;
| ^^^^^^ maybe a missing crate `clippy`?
|
= help: consider adding `extern crate clippy` to use the `clippy` crate
help: consider importing the `clippy` crate
|
LL + extern crate clippy;
|

error[E0433]: failed to resolve: maybe a missing crate `rustdoc`?
--> $DIR/tool-mod-child.rs:5:5
|
LL | use rustdoc::a::b;
| ^^^^^^^ maybe a missing crate `rustdoc`?
|
= help: consider adding `extern crate rustdoc` to use the `rustdoc` crate
help: consider importing the `rustdoc` crate
|
LL + extern crate rustdoc;
|

error[E0432]: unresolved import `rustdoc`
--> $DIR/tool-mod-child.rs:4:5
|
LL | use rustdoc::a;
| ^^^^^^^ maybe a missing crate `rustdoc`?
|
= help: consider adding `extern crate rustdoc` to use the `rustdoc` crate
help: consider importing the `rustdoc` crate
|
LL + extern crate rustdoc;
|

error: aborting due to 4 previous errors

Expand Down
20 changes: 16 additions & 4 deletions tests/ui/imports/unresolved-imports-used.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,43 @@ error[E0432]: unresolved import `foo`
LL | use foo::bar;
| ^^^ maybe a missing crate `foo`?
|
= help: consider adding `extern crate foo` to use the `foo` crate
help: consider importing the `foo` crate
|
LL + extern crate foo;
|

error[E0432]: unresolved import `baz`
--> $DIR/unresolved-imports-used.rs:12:5
|
LL | use baz::*;
| ^^^ maybe a missing crate `baz`?
|
= help: consider adding `extern crate baz` to use the `baz` crate
help: consider importing the `baz` crate
|
LL + extern crate baz;
|

error[E0432]: unresolved import `foo2`
--> $DIR/unresolved-imports-used.rs:14:5
|
LL | use foo2::bar2;
| ^^^^ maybe a missing crate `foo2`?
|
= help: consider adding `extern crate foo2` to use the `foo2` crate
help: consider importing the `foo2` crate
|
LL + extern crate foo2;
|

error[E0432]: unresolved import `baz2`
--> $DIR/unresolved-imports-used.rs:15:5
|
LL | use baz2::*;
| ^^^^ maybe a missing crate `baz2`?
|
= help: consider adding `extern crate baz2` to use the `baz2` crate
help: consider importing the `baz2` crate
|
LL + extern crate baz2;
|

error[E0603]: function `quz` is private
--> $DIR/unresolved-imports-used.rs:9:10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ error[E0432]: unresolved import `r#extern`
LL | use extern::foo;
| ^^^^^^ maybe a missing crate `r#extern`?
|
= help: consider adding `extern crate r#extern` to use the `r#extern` crate
help: consider importing the `r#extern` crate
|
LL + extern crate r#extern;
|

error: aborting due to 2 previous errors

Expand Down
Loading

0 comments on commit 9a7979d

Please sign in to comment.