Skip to content

Commit 2e58d62

Browse files
authored
Rollup merge of #128932 - bvanjoi:issue-128813, r=petrochenkov
skip updating when external binding is existed Fixes #128813 For following code: ```rs extern crate core; fn f() { use ::core; } macro_rules! m { () => { extern crate std as core; }; } m!(); fn main() {} ``` - In the first loop, we define `extern crate core` and `use ::core` will be referred to `core` (yes, it does not consider if there are some macros that are not expanded. Ideally, this should be delayed if there are some unexpanded macros in the root, but I didn't change it like that because it seems like a huge change). - Then `m` is expanded, which makes `extern_prelude('core')` return `std` rather than `core`, causing the inconsistency. r? `@petrochenkov`
2 parents 552b5c7 + df019a9 commit 2e58d62

14 files changed

+179
-17
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,8 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
896896
self.r.potentially_unused_imports.push(import);
897897
let imported_binding = self.r.import(binding, import);
898898
if parent == self.r.graph_root {
899-
if let Some(entry) = self.r.extern_prelude.get(&ident.normalize_to_macros_2_0()) {
899+
let ident = ident.normalize_to_macros_2_0();
900+
if let Some(entry) = self.r.extern_prelude.get(&ident) {
900901
if expansion != LocalExpnId::ROOT && orig_name.is_some() && !entry.is_import() {
901902
self.r.dcx().emit_err(
902903
errors::MacroExpandedExternCrateCannotShadowExternArguments {
@@ -913,14 +914,21 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
913914
let entry = self
914915
.r
915916
.extern_prelude
916-
.entry(ident.normalize_to_macros_2_0())
917+
.entry(ident)
917918
.or_insert(ExternPreludeEntry { binding: None, introduced_by_item: true });
918-
// Binding from `extern crate` item in source code can replace
919-
// a binding from `--extern` on command line here.
920-
entry.binding = Some(imported_binding);
921919
if orig_name.is_some() {
922920
entry.introduced_by_item = true;
923921
}
922+
// Binding from `extern crate` item in source code can replace
923+
// a binding from `--extern` on command line here.
924+
if !entry.is_import() {
925+
entry.binding = Some(imported_binding)
926+
} else if ident.name != kw::Underscore {
927+
self.r.dcx().span_delayed_bug(
928+
item.span,
929+
format!("it had been define the external module '{ident}' multiple times"),
930+
);
931+
}
924932
}
925933
self.r.define(parent, ident, TypeNS, imported_binding);
926934
}

src/tools/tidy/src/issues.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -1289,8 +1289,7 @@ ui/imports/auxiliary/issue-52891.rs
12891289
ui/imports/auxiliary/issue-55811.rs
12901290
ui/imports/auxiliary/issue-56125.rs
12911291
ui/imports/auxiliary/issue-59764.rs
1292-
ui/imports/auxiliary/issue-85992-extern-1.rs
1293-
ui/imports/auxiliary/issue-85992-extern-2.rs
1292+
ui/imports/auxiliary/issue-85992-extern.rs
12941293
ui/imports/issue-109148.rs
12951294
ui/imports/issue-109343.rs
12961295
ui/imports/issue-113953.rs
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[macro_export]
22
macro_rules! m {
33
() => {
4-
use issue_85992_extern_2::Outcome;
4+
use empty::Outcome;
55
}
66
}

tests/ui/imports/issue-85992.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
//@ edition: 2021
2-
//@ compile-flags: --extern issue_85992_extern_1 --extern issue_85992_extern_2
3-
//@ aux-build: issue-85992-extern-1.rs
4-
//@ aux-build: issue-85992-extern-2.rs
2+
//@ compile-flags: --extern issue_85992_extern --extern empty
3+
//@ aux-build: issue-85992-extern.rs
4+
//@ aux-build: empty.rs
55

6-
issue_85992_extern_1::m!();
6+
issue_85992_extern::m!();
77

8-
use crate::issue_85992_extern_2;
9-
//~^ ERROR unresolved import `crate::issue_85992_extern_2`
8+
use crate::empty;
9+
//~^ ERROR unresolved import `crate::empty`
1010

1111
fn main() {}

tests/ui/imports/issue-85992.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0432]: unresolved import `crate::issue_85992_extern_2`
1+
error[E0432]: unresolved import `crate::empty`
22
--> $DIR/issue-85992.rs:8:5
33
|
4-
LL | use crate::issue_85992_extern_2;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `issue_85992_extern_2` in the root
4+
LL | use crate::empty;
5+
| ^^^^^^^^^^^^ no `empty` in the root
66

77
error: aborting due to 1 previous error
88

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ edition: 2021
2+
3+
// issue#128813
4+
5+
extern crate core;
6+
7+
macro_rules! m {
8+
() => {
9+
extern crate std as core;
10+
//~^ ERROR: the name `core` is defined multiple times
11+
};
12+
}
13+
14+
m!();
15+
16+
fn main() {
17+
use ::core;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0259]: the name `core` is defined multiple times
2+
--> $DIR/multiple-extern-by-macro-for-buitlin.rs:9:9
3+
|
4+
LL | extern crate core;
5+
| ------------------ previous import of the extern crate `core` here
6+
...
7+
LL | extern crate std as core;
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ `core` reimported here
9+
...
10+
LL | m!();
11+
| ---- in this macro invocation
12+
|
13+
= note: `core` must be defined only once in the type namespace of this module
14+
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
15+
help: you can use `as` to change the binding name of the import
16+
|
17+
LL | extern crate std as other_core;
18+
|
19+
20+
error: aborting due to 1 previous error
21+
22+
For more information about this error, try `rustc --explain E0259`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ edition: 2021
2+
//@ aux-build: empty.rs
3+
4+
// issue#128813
5+
6+
extern crate empty;
7+
8+
macro_rules! m {
9+
() => {
10+
extern crate std as empty;
11+
//~^ ERROR: the name `empty` is defined multiple times
12+
};
13+
}
14+
15+
m!();
16+
17+
fn main() {
18+
use ::empty;
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0259]: the name `empty` is defined multiple times
2+
--> $DIR/multiple-extern-by-macro-for-custom.rs:10:9
3+
|
4+
LL | extern crate empty;
5+
| ------------------- previous import of the extern crate `empty` here
6+
...
7+
LL | extern crate std as empty;
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `empty` reimported here
9+
...
10+
LL | m!();
11+
| ---- in this macro invocation
12+
|
13+
= note: `empty` must be defined only once in the type namespace of this module
14+
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
15+
help: you can use `as` to change the binding name of the import
16+
|
17+
LL | extern crate std as other_empty;
18+
|
19+
20+
error: aborting due to 1 previous error
21+
22+
For more information about this error, try `rustc --explain E0259`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ edition: 2021
2+
3+
// issue#128813
4+
5+
extern crate non_existent;
6+
//~^ ERROR: can't find crate for `non_existent`
7+
8+
macro_rules! m {
9+
() => {
10+
extern crate std as non_existent;
11+
//~^ ERROR: the name `non_existent` is defined multiple times
12+
};
13+
}
14+
15+
m!();
16+
17+
fn main() {
18+
use ::non_existent;
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0463]: can't find crate for `non_existent`
2+
--> $DIR/multiple-extern-by-macro-for-inexist.rs:5:1
3+
|
4+
LL | extern crate non_existent;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
6+
7+
error[E0259]: the name `non_existent` is defined multiple times
8+
--> $DIR/multiple-extern-by-macro-for-inexist.rs:10:9
9+
|
10+
LL | extern crate non_existent;
11+
| -------------------------- previous import of the extern crate `non_existent` here
12+
...
13+
LL | extern crate std as non_existent;
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `non_existent` reimported here
15+
...
16+
LL | m!();
17+
| ---- in this macro invocation
18+
|
19+
= note: `non_existent` must be defined only once in the type namespace of this module
20+
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
21+
help: you can use `as` to change the binding name of the import
22+
|
23+
LL | extern crate std as other_non_existent;
24+
|
25+
26+
error: aborting due to 2 previous errors
27+
28+
Some errors have detailed explanations: E0259, E0463.
29+
For more information about an error, try `rustc --explain E0259`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ edition: 2021
2+
3+
// issue#128813
4+
5+
extern crate core as _;
6+
7+
macro_rules! m {
8+
() => {
9+
extern crate std as _;
10+
};
11+
}
12+
13+
m!();
14+
15+
fn main() {
16+
use ::_;
17+
//~^ ERROR: expected identifier, found reserved identifier `_`
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected identifier, found reserved identifier `_`
2+
--> $DIR/multiple-extern-by-macro-for-underscore.rs:16:11
3+
|
4+
LL | use ::_;
5+
| ^ expected identifier, found reserved identifier
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)