From df019a9f46d58fcb1b32ee69022a294a93e1a0a7 Mon Sep 17 00:00:00 2001 From: bohan Date: Fri, 16 Aug 2024 23:58:19 +0800 Subject: [PATCH] skip updating when external binding is existed --- .../rustc_resolve/src/build_reduced_graph.rs | 18 ++++++++---- src/tools/tidy/src/issues.txt | 3 +- .../{issue-85992-extern-2.rs => empty.rs} | 0 ...5992-extern-1.rs => issue-85992-extern.rs} | 2 +- tests/ui/imports/issue-85992.rs | 12 ++++---- tests/ui/imports/issue-85992.stderr | 6 ++-- .../multiple-extern-by-macro-for-buitlin.rs | 18 ++++++++++++ ...ultiple-extern-by-macro-for-buitlin.stderr | 22 ++++++++++++++ .../multiple-extern-by-macro-for-custom.rs | 19 ++++++++++++ ...multiple-extern-by-macro-for-custom.stderr | 22 ++++++++++++++ .../multiple-extern-by-macro-for-inexist.rs | 19 ++++++++++++ ...ultiple-extern-by-macro-for-inexist.stderr | 29 +++++++++++++++++++ ...multiple-extern-by-macro-for-underscore.rs | 18 ++++++++++++ ...iple-extern-by-macro-for-underscore.stderr | 8 +++++ 14 files changed, 179 insertions(+), 17 deletions(-) rename tests/ui/imports/auxiliary/{issue-85992-extern-2.rs => empty.rs} (100%) rename tests/ui/imports/auxiliary/{issue-85992-extern-1.rs => issue-85992-extern.rs} (54%) create mode 100644 tests/ui/imports/multiple-extern-by-macro-for-buitlin.rs create mode 100644 tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr create mode 100644 tests/ui/imports/multiple-extern-by-macro-for-custom.rs create mode 100644 tests/ui/imports/multiple-extern-by-macro-for-custom.stderr create mode 100644 tests/ui/imports/multiple-extern-by-macro-for-inexist.rs create mode 100644 tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr create mode 100644 tests/ui/imports/multiple-extern-by-macro-for-underscore.rs create mode 100644 tests/ui/imports/multiple-extern-by-macro-for-underscore.stderr diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index d57dabdd78d..3a27f96dde8 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -896,7 +896,8 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { self.r.potentially_unused_imports.push(import); let imported_binding = self.r.import(binding, import); if parent == self.r.graph_root { - if let Some(entry) = self.r.extern_prelude.get(&ident.normalize_to_macros_2_0()) { + let ident = ident.normalize_to_macros_2_0(); + if let Some(entry) = self.r.extern_prelude.get(&ident) { if expansion != LocalExpnId::ROOT && orig_name.is_some() && !entry.is_import() { self.r.dcx().emit_err( errors::MacroExpandedExternCrateCannotShadowExternArguments { @@ -913,14 +914,21 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { let entry = self .r .extern_prelude - .entry(ident.normalize_to_macros_2_0()) + .entry(ident) .or_insert(ExternPreludeEntry { binding: None, introduced_by_item: true }); - // Binding from `extern crate` item in source code can replace - // a binding from `--extern` on command line here. - entry.binding = Some(imported_binding); if orig_name.is_some() { entry.introduced_by_item = true; } + // Binding from `extern crate` item in source code can replace + // a binding from `--extern` on command line here. + if !entry.is_import() { + entry.binding = Some(imported_binding) + } else if ident.name != kw::Underscore { + self.r.dcx().span_delayed_bug( + item.span, + format!("it had been define the external module '{ident}' multiple times"), + ); + } } self.r.define(parent, ident, TypeNS, imported_binding); } diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 57310977704..5205fa14294 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -1289,8 +1289,7 @@ ui/imports/auxiliary/issue-52891.rs ui/imports/auxiliary/issue-55811.rs ui/imports/auxiliary/issue-56125.rs ui/imports/auxiliary/issue-59764.rs -ui/imports/auxiliary/issue-85992-extern-1.rs -ui/imports/auxiliary/issue-85992-extern-2.rs +ui/imports/auxiliary/issue-85992-extern.rs ui/imports/issue-109148.rs ui/imports/issue-109343.rs ui/imports/issue-113953.rs diff --git a/tests/ui/imports/auxiliary/issue-85992-extern-2.rs b/tests/ui/imports/auxiliary/empty.rs similarity index 100% rename from tests/ui/imports/auxiliary/issue-85992-extern-2.rs rename to tests/ui/imports/auxiliary/empty.rs diff --git a/tests/ui/imports/auxiliary/issue-85992-extern-1.rs b/tests/ui/imports/auxiliary/issue-85992-extern.rs similarity index 54% rename from tests/ui/imports/auxiliary/issue-85992-extern-1.rs rename to tests/ui/imports/auxiliary/issue-85992-extern.rs index a2d0e206065..076d6045190 100644 --- a/tests/ui/imports/auxiliary/issue-85992-extern-1.rs +++ b/tests/ui/imports/auxiliary/issue-85992-extern.rs @@ -1,6 +1,6 @@ #[macro_export] macro_rules! m { () => { - use issue_85992_extern_2::Outcome; + use empty::Outcome; } } diff --git a/tests/ui/imports/issue-85992.rs b/tests/ui/imports/issue-85992.rs index 321c3a9218d..38cf0384501 100644 --- a/tests/ui/imports/issue-85992.rs +++ b/tests/ui/imports/issue-85992.rs @@ -1,11 +1,11 @@ //@ edition: 2021 -//@ compile-flags: --extern issue_85992_extern_1 --extern issue_85992_extern_2 -//@ aux-build: issue-85992-extern-1.rs -//@ aux-build: issue-85992-extern-2.rs +//@ compile-flags: --extern issue_85992_extern --extern empty +//@ aux-build: issue-85992-extern.rs +//@ aux-build: empty.rs -issue_85992_extern_1::m!(); +issue_85992_extern::m!(); -use crate::issue_85992_extern_2; -//~^ ERROR unresolved import `crate::issue_85992_extern_2` +use crate::empty; +//~^ ERROR unresolved import `crate::empty` fn main() {} diff --git a/tests/ui/imports/issue-85992.stderr b/tests/ui/imports/issue-85992.stderr index 6c75b45d926..490b2d4d88b 100644 --- a/tests/ui/imports/issue-85992.stderr +++ b/tests/ui/imports/issue-85992.stderr @@ -1,8 +1,8 @@ -error[E0432]: unresolved import `crate::issue_85992_extern_2` +error[E0432]: unresolved import `crate::empty` --> $DIR/issue-85992.rs:8:5 | -LL | use crate::issue_85992_extern_2; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `issue_85992_extern_2` in the root +LL | use crate::empty; + | ^^^^^^^^^^^^ no `empty` in the root error: aborting due to 1 previous error diff --git a/tests/ui/imports/multiple-extern-by-macro-for-buitlin.rs b/tests/ui/imports/multiple-extern-by-macro-for-buitlin.rs new file mode 100644 index 00000000000..f0e5e4b4325 --- /dev/null +++ b/tests/ui/imports/multiple-extern-by-macro-for-buitlin.rs @@ -0,0 +1,18 @@ +//@ edition: 2021 + +// issue#128813 + +extern crate core; + +macro_rules! m { + () => { + extern crate std as core; + //~^ ERROR: the name `core` is defined multiple times + }; +} + +m!(); + +fn main() { + use ::core; +} diff --git a/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr b/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr new file mode 100644 index 00000000000..a84a6c42aa8 --- /dev/null +++ b/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr @@ -0,0 +1,22 @@ +error[E0259]: the name `core` is defined multiple times + --> $DIR/multiple-extern-by-macro-for-buitlin.rs:9:9 + | +LL | extern crate core; + | ------------------ previous import of the extern crate `core` here +... +LL | extern crate std as core; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `core` reimported here +... +LL | m!(); + | ---- in this macro invocation + | + = note: `core` must be defined only once in the type namespace of this module + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you can use `as` to change the binding name of the import + | +LL | extern crate std as other_core; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0259`. diff --git a/tests/ui/imports/multiple-extern-by-macro-for-custom.rs b/tests/ui/imports/multiple-extern-by-macro-for-custom.rs new file mode 100644 index 00000000000..6bf544566e3 --- /dev/null +++ b/tests/ui/imports/multiple-extern-by-macro-for-custom.rs @@ -0,0 +1,19 @@ +//@ edition: 2021 +//@ aux-build: empty.rs + +// issue#128813 + +extern crate empty; + +macro_rules! m { + () => { + extern crate std as empty; + //~^ ERROR: the name `empty` is defined multiple times + }; +} + +m!(); + +fn main() { + use ::empty; +} diff --git a/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr b/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr new file mode 100644 index 00000000000..556d75a4dbb --- /dev/null +++ b/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr @@ -0,0 +1,22 @@ +error[E0259]: the name `empty` is defined multiple times + --> $DIR/multiple-extern-by-macro-for-custom.rs:10:9 + | +LL | extern crate empty; + | ------------------- previous import of the extern crate `empty` here +... +LL | extern crate std as empty; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `empty` reimported here +... +LL | m!(); + | ---- in this macro invocation + | + = note: `empty` must be defined only once in the type namespace of this module + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you can use `as` to change the binding name of the import + | +LL | extern crate std as other_empty; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0259`. diff --git a/tests/ui/imports/multiple-extern-by-macro-for-inexist.rs b/tests/ui/imports/multiple-extern-by-macro-for-inexist.rs new file mode 100644 index 00000000000..c23f275b9ff --- /dev/null +++ b/tests/ui/imports/multiple-extern-by-macro-for-inexist.rs @@ -0,0 +1,19 @@ +//@ edition: 2021 + +// issue#128813 + +extern crate non_existent; +//~^ ERROR: can't find crate for `non_existent` + +macro_rules! m { + () => { + extern crate std as non_existent; + //~^ ERROR: the name `non_existent` is defined multiple times + }; +} + +m!(); + +fn main() { + use ::non_existent; +} diff --git a/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr b/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr new file mode 100644 index 00000000000..ec34489f232 --- /dev/null +++ b/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr @@ -0,0 +1,29 @@ +error[E0463]: can't find crate for `non_existent` + --> $DIR/multiple-extern-by-macro-for-inexist.rs:5:1 + | +LL | extern crate non_existent; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate + +error[E0259]: the name `non_existent` is defined multiple times + --> $DIR/multiple-extern-by-macro-for-inexist.rs:10:9 + | +LL | extern crate non_existent; + | -------------------------- previous import of the extern crate `non_existent` here +... +LL | extern crate std as non_existent; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `non_existent` reimported here +... +LL | m!(); + | ---- in this macro invocation + | + = note: `non_existent` must be defined only once in the type namespace of this module + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you can use `as` to change the binding name of the import + | +LL | extern crate std as other_non_existent; + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0259, E0463. +For more information about an error, try `rustc --explain E0259`. diff --git a/tests/ui/imports/multiple-extern-by-macro-for-underscore.rs b/tests/ui/imports/multiple-extern-by-macro-for-underscore.rs new file mode 100644 index 00000000000..ddf735d8947 --- /dev/null +++ b/tests/ui/imports/multiple-extern-by-macro-for-underscore.rs @@ -0,0 +1,18 @@ +//@ edition: 2021 + +// issue#128813 + +extern crate core as _; + +macro_rules! m { + () => { + extern crate std as _; + }; +} + +m!(); + +fn main() { + use ::_; + //~^ ERROR: expected identifier, found reserved identifier `_` +} diff --git a/tests/ui/imports/multiple-extern-by-macro-for-underscore.stderr b/tests/ui/imports/multiple-extern-by-macro-for-underscore.stderr new file mode 100644 index 00000000000..1da5aa87070 --- /dev/null +++ b/tests/ui/imports/multiple-extern-by-macro-for-underscore.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/multiple-extern-by-macro-for-underscore.rs:16:11 + | +LL | use ::_; + | ^ expected identifier, found reserved identifier + +error: aborting due to 1 previous error +