From c553c5d86c93ab5744ac90e65e175c11a8000af4 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 17 Feb 2024 17:54:06 +0800 Subject: [PATCH] Fix issues in suggesting importing extern crate paths --- compiler/rustc_resolve/src/diagnostics.rs | 22 +++++++++++++++---- tests/run-make/extern-alias/Makefile | 11 ++++++++++ tests/run-make/extern-alias/main.rs | 6 +++++ .../extern-alias/unwieldy_crate_name.rs | 1 + ...xtern-prelude-from-opaque-fail-2018.stderr | 7 ++---- tests/ui/imports/issue-56125.stderr | 7 ++---- tests/ui/mir/issue-106062.stderr | 12 ++++------ .../core-std-import-order-issue-83564.rs | 2 +- .../core-std-import-order-issue-83564.stderr | 4 +--- .../suggestions/crate-or-module-typo.stderr | 4 +--- .../suggest-tryinto-edition-change.rs | 3 --- .../suggest-tryinto-edition-change.stderr | 19 +++++----------- 12 files changed, 52 insertions(+), 46 deletions(-) create mode 100644 tests/run-make/extern-alias/Makefile create mode 100644 tests/run-make/extern-alias/main.rs create mode 100644 tests/run-make/extern-alias/unwieldy_crate_name.rs diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d91a865e38aba..98e3709ed1f72 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1287,10 +1287,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut path_segments = path_segments.clone(); path_segments.push(ast::PathSegment::from_ident(ident)); + let alias_import = if let NameBindingKind::Import { import, .. } = + name_binding.kind + && let ImportKind::ExternCrate { source: Some(_), .. } = import.kind + && import.parent_scope.expansion == parent_scope.expansion + { + true + } else { + false + }; + let is_extern_crate_that_also_appears_in_prelude = name_binding.is_extern_crate() && lookup_ident.span.at_least_rust_2018(); - if !is_extern_crate_that_also_appears_in_prelude { + if !is_extern_crate_that_also_appears_in_prelude || alias_import { // add the module to the lookup if seen_modules.insert(module.def_id()) { if via_import { &mut worklist_via_import } else { &mut worklist } @@ -1378,15 +1388,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { crate_path.push(ast::PathSegment::path_root(rustc_span::DUMMY_SP)); } crate_path.push(ast::PathSegment::from_ident(ident)); - - suggestions.extend(self.lookup_import_candidates_from_module( + let suggest_imports = self.lookup_import_candidates_from_module( lookup_ident, namespace, parent_scope, crate_root, crate_path, &filter_fn, - )); + ); + for item in suggest_imports { + if suggestions.iter().all(|sugg| sugg.did != item.did) { + suggestions.push(item); + } + } } } } diff --git a/tests/run-make/extern-alias/Makefile b/tests/run-make/extern-alias/Makefile new file mode 100644 index 0000000000000..89733acad134c --- /dev/null +++ b/tests/run-make/extern-alias/Makefile @@ -0,0 +1,11 @@ +# ignore-cross-compile +include ../tools.mk + +all: + $(RUSTC) --crate-type=rlib unwieldy_crate_name.rs -o $(TMPDIR)/libunwieldy_crate_name.rlib + $(RUSTC) --crate-type rlib main.rs --extern unwieldy_crate_name=$(TMPDIR)/libunwieldy_crate_name.rlib \ + 2>&1 | $(CGREP) "use nice_crate_name::Foo;" + + $(RUSTC) --crate-type=rlib --edition=2021 unwieldy_crate_name.rs -o $(TMPDIR)/libunwieldy_crate_name.rlib + $(RUSTC) --crate-type rlib main.rs --edition=2021 --extern unwieldy_crate_name=$(TMPDIR)/libunwieldy_crate_name.rlib \ + 2>&1 | $(CGREP) "use crate::nice_crate_name::Foo;" diff --git a/tests/run-make/extern-alias/main.rs b/tests/run-make/extern-alias/main.rs new file mode 100644 index 0000000000000..215dc76eb8180 --- /dev/null +++ b/tests/run-make/extern-alias/main.rs @@ -0,0 +1,6 @@ +extern crate unwieldy_crate_name as nice_crate_name; + +fn use_foo_from_another_crate_without_importing_it_first() { + //use nice_crate_name::Foo; + let _: Foo = todo!(); +} diff --git a/tests/run-make/extern-alias/unwieldy_crate_name.rs b/tests/run-make/extern-alias/unwieldy_crate_name.rs new file mode 100644 index 0000000000000..a665eb8eb96aa --- /dev/null +++ b/tests/run-make/extern-alias/unwieldy_crate_name.rs @@ -0,0 +1 @@ +pub struct Foo(pub core::ptr::NonNull); diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr index 78e6376bca2e8..ffe4f800c7390 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr @@ -24,9 +24,8 @@ LL | fn f() { my_core::mem::drop(0); } LL | a!(); | ---- in this macro invocation | - = help: consider importing one of these items: + = help: consider importing this module: core::mem - std::mem = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0433]: failed to resolve: use of undeclared crate or module `my_core` @@ -35,12 +34,10 @@ error[E0433]: failed to resolve: use of undeclared crate or module `my_core` LL | fn f() { my_core::mem::drop(0); } | ^^^^^^^ use of undeclared crate or module `my_core` | -help: consider importing one of these items +help: consider importing this module | LL + use core::mem; | -LL + use std::mem; - | help: if you import `mem`, refer to it directly | LL - fn f() { my_core::mem::drop(0); } diff --git a/tests/ui/imports/issue-56125.stderr b/tests/ui/imports/issue-56125.stderr index d2a0f436c42d0..27bbce1526f58 100644 --- a/tests/ui/imports/issue-56125.stderr +++ b/tests/ui/imports/issue-56125.stderr @@ -8,13 +8,10 @@ help: consider importing one of these items instead | LL | use ::issue_56125::issue_56125; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ -LL | use ::issue_56125::last_segment::issue_56125; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LL | use ::issue_56125::non_last_segment::non_last_segment::issue_56125; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LL | use crate::m3::last_segment::issue_56125; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - and 1 other candidate +LL | use crate::m3::non_last_segment::non_last_segment::issue_56125; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0659]: `issue_56125` is ambiguous --> $DIR/issue-56125.rs:6:9 diff --git a/tests/ui/mir/issue-106062.stderr b/tests/ui/mir/issue-106062.stderr index 30635148dae64..f366c88a2b7cc 100644 --- a/tests/ui/mir/issue-106062.stderr +++ b/tests/ui/mir/issue-106062.stderr @@ -2,14 +2,10 @@ error[E0573]: expected type, found variant `Ok` --> $DIR/issue-106062.rs:15:64 | LL | async fn connection_handler(handler: impl Sized) -> Result { - | ^^ not a type - | -help: try using the variant's enum - | -LL | async fn connection_handler(handler: impl Sized) -> Result { - | ~~~~~~~~~~~~~~~~~~~~ -LL | async fn connection_handler(handler: impl Sized) -> Result { - | ~~~~~~~~~~~~~~~~~~~ + | ^^ + | | + | not a type + | help: try using the variant's enum: `core::result::Result` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.rs b/tests/ui/suggestions/core-std-import-order-issue-83564.rs index b7fe5af7bf8a1..b5ccb793b9798 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.rs +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.rs @@ -4,7 +4,7 @@ // For some reason, Rust 2018 or higher is required to reproduce the bug. fn main() { - //~^ HELP consider importing one of these items + //~^ HELP consider importing this type alias let _x = NonZeroU32::new(5).unwrap(); //~^ ERROR failed to resolve: use of undeclared type `NonZeroU32` } diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.stderr b/tests/ui/suggestions/core-std-import-order-issue-83564.stderr index c2634e3070ea9..437af83923951 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.stderr +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.stderr @@ -4,12 +4,10 @@ error[E0433]: failed to resolve: use of undeclared type `NonZeroU32` LL | let _x = NonZeroU32::new(5).unwrap(); | ^^^^^^^^^^ use of undeclared type `NonZeroU32` | -help: consider importing one of these items +help: consider importing this type alias | LL + use core::num::NonZeroU32; | -LL + use std::num::NonZeroU32; - | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/crate-or-module-typo.stderr b/tests/ui/suggestions/crate-or-module-typo.stderr index 457d779064682..dfd03e4aaea05 100644 --- a/tests/ui/suggestions/crate-or-module-typo.stderr +++ b/tests/ui/suggestions/crate-or-module-typo.stderr @@ -30,12 +30,10 @@ help: there is a crate or module with a similar name | LL | bar: std::cell::Cell | ~~~ -help: consider importing one of these items +help: consider importing this module | LL + use core::cell; | -LL + use std::cell; - | help: if you import `cell`, refer to it directly | LL - bar: st::cell::Cell diff --git a/tests/ui/suggestions/suggest-tryinto-edition-change.rs b/tests/ui/suggestions/suggest-tryinto-edition-change.rs index 70c4b210d3a7b..3700798c576b7 100644 --- a/tests/ui/suggestions/suggest-tryinto-edition-change.rs +++ b/tests/ui/suggestions/suggest-tryinto-edition-change.rs @@ -11,19 +11,16 @@ fn test() { let _i: i16 = TryFrom::try_from(0_i32).unwrap(); //~^ ERROR failed to resolve: use of undeclared type //~| NOTE use of undeclared type - //~| NOTE 'std::convert::TryFrom' is included in the prelude starting in Edition 2021 //~| NOTE 'core::convert::TryFrom' is included in the prelude starting in Edition 2021 let _i: i16 = TryInto::try_into(0_i32).unwrap(); //~^ ERROR failed to resolve: use of undeclared type //~| NOTE use of undeclared type - //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021 //~| NOTE 'core::convert::TryInto' is included in the prelude starting in Edition 2021 let _v: Vec<_> = FromIterator::from_iter(&[1]); //~^ ERROR failed to resolve: use of undeclared type //~| NOTE use of undeclared type - //~| NOTE 'std::iter::FromIterator' is included in the prelude starting in Edition 2021 //~| NOTE 'core::iter::FromIterator' is included in the prelude starting in Edition 2021 } diff --git a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr index 057e37dbe109f..3fc6c3ae7393c 100644 --- a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr +++ b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr @@ -5,47 +5,38 @@ LL | let _i: i16 = TryFrom::try_from(0_i32).unwrap(); | ^^^^^^^ use of undeclared type `TryFrom` | = note: 'core::convert::TryFrom' is included in the prelude starting in Edition 2021 - = note: 'std::convert::TryFrom' is included in the prelude starting in Edition 2021 -help: consider importing one of these items +help: consider importing this trait | LL + use core::convert::TryFrom; | -LL + use std::convert::TryFrom; - | error[E0433]: failed to resolve: use of undeclared type `TryInto` - --> $DIR/suggest-tryinto-edition-change.rs:17:19 + --> $DIR/suggest-tryinto-edition-change.rs:16:19 | LL | let _i: i16 = TryInto::try_into(0_i32).unwrap(); | ^^^^^^^ use of undeclared type `TryInto` | = note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021 - = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021 -help: consider importing one of these items +help: consider importing this trait | LL + use core::convert::TryInto; | -LL + use std::convert::TryInto; - | error[E0433]: failed to resolve: use of undeclared type `FromIterator` - --> $DIR/suggest-tryinto-edition-change.rs:23:22 + --> $DIR/suggest-tryinto-edition-change.rs:21:22 | LL | let _v: Vec<_> = FromIterator::from_iter(&[1]); | ^^^^^^^^^^^^ use of undeclared type `FromIterator` | = note: 'core::iter::FromIterator' is included in the prelude starting in Edition 2021 - = note: 'std::iter::FromIterator' is included in the prelude starting in Edition 2021 help: a trait with a similar name exists | LL | let _v: Vec<_> = IntoIterator::from_iter(&[1]); | ~~~~~~~~~~~~ -help: consider importing one of these items +help: consider importing this trait | LL + use core::iter::FromIterator; | -LL + use std::iter::FromIterator; - | error[E0599]: no method named `try_into` found for type `i32` in the current scope --> $DIR/suggest-tryinto-edition-change.rs:6:25