Skip to content

Commit cde0374

Browse files
committed
resolve: Clarify extern prelude insertion for extern crate items
1 parent 3fb1b53 commit cde0374

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4552,6 +4552,7 @@ name = "rustc_resolve"
45524552
version = "0.0.0"
45534553
dependencies = [
45544554
"bitflags",
4555+
"indexmap",
45554556
"itertools",
45564557
"pulldown-cmark",
45574558
"rustc_arena",

compiler/rustc_resolve/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2024"
66
[dependencies]
77
# tidy-alphabetical-start
88
bitflags = "2.4.1"
9+
indexmap = "2.4.0"
910
itertools = "0.12"
1011
pulldown-cmark = { version = "0.11", features = ["html"], default-features = false }
1112
rustc_arena = { path = "../rustc_arena" }

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
968968
}
969969
self.r.potentially_unused_imports.push(import);
970970
let imported_binding = self.r.import(binding, import);
971-
if parent == self.r.graph_root {
971+
if ident.name != kw::Underscore && parent == self.r.graph_root {
972972
let ident = ident.normalize_to_macros_2_0();
973973
if let Some(entry) = self.r.extern_prelude.get(&ident)
974974
&& expansion != LocalExpnId::ROOT
@@ -984,23 +984,29 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
984984
// more details: https://github.com/rust-lang/rust/pull/111761
985985
return;
986986
}
987-
let entry = self.r.extern_prelude.entry(ident).or_insert(ExternPreludeEntry {
988-
binding: Cell::new(None),
989-
introduced_by_item: true,
990-
});
991-
if orig_name.is_some() {
992-
entry.introduced_by_item = true;
993-
}
994-
// Binding from `extern crate` item in source code can replace
995-
// a binding from `--extern` on command line here.
996-
if !entry.is_import() {
997-
entry.binding.set(Some(imported_binding));
998-
} else if ident.name != kw::Underscore {
999-
self.r.dcx().span_delayed_bug(
1000-
item.span,
1001-
format!("it had been define the external module '{ident}' multiple times"),
1002-
);
1003-
}
987+
988+
use indexmap::map::Entry;
989+
match self.r.extern_prelude.entry(ident) {
990+
Entry::Occupied(mut occupied) => {
991+
let entry = occupied.get_mut();
992+
if let Some(old_binding) = entry.binding.get()
993+
&& old_binding.is_import()
994+
{
995+
let msg = format!("extern crate `{ident}` already in extern prelude");
996+
self.r.tcx.dcx().span_delayed_bug(item.span, msg);
997+
} else {
998+
// Binding from `extern crate` item in source code can replace
999+
// a binding from `--extern` on command line here.
1000+
entry.binding.set(Some(imported_binding));
1001+
entry.introduced_by_item = orig_name.is_some();
1002+
}
1003+
entry
1004+
}
1005+
Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry {
1006+
binding: Cell::new(Some(imported_binding)),
1007+
introduced_by_item: true,
1008+
}),
1009+
};
10041010
}
10051011
self.r.define_binding_local(parent, ident, TypeNS, imported_binding);
10061012
}

0 commit comments

Comments
 (0)