Skip to content

Commit 29bbf36

Browse files
Auto merge of #144746 - petrochenkov:extpreltidy, r=<try>
resolve: Cleanups and micro-optimizations to extern prelude
2 parents 3fb1b53 + e58e6f8 commit 29bbf36

File tree

6 files changed

+74
-63
lines changed

6 files changed

+74
-63
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
}

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10981098
}
10991099
}
11001100
Scope::ExternPrelude => {
1101-
suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
1101+
suggestions.extend(this.extern_prelude.keys().filter_map(|ident| {
11021102
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
11031103
filter_fn(res).then_some(TypoSuggestion::typo_from_ident(*ident, res))
11041104
}));
@@ -1411,7 +1411,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14111411
);
14121412

14131413
if lookup_ident.span.at_least_rust_2018() {
1414-
for ident in self.extern_prelude.clone().into_keys() {
1414+
for &ident in self.extern_prelude.keys() {
14151415
if ident.span.from_expansion() {
14161416
// Idents are adjusted to the root context before being
14171417
// resolved in the extern prelude, so reporting this to the

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,19 +2477,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
24772477
} else {
24782478
// Items from the prelude
24792479
if !module.no_implicit_prelude {
2480-
let extern_prelude = self.r.extern_prelude.clone();
2481-
names.extend(extern_prelude.iter().flat_map(|(ident, _)| {
2482-
self.r
2483-
.cstore_mut()
2484-
.maybe_process_path_extern(self.r.tcx, ident.name)
2485-
.and_then(|crate_id| {
2486-
let crate_mod =
2487-
Res::Def(DefKind::Mod, crate_id.as_def_id());
2488-
2489-
filter_fn(crate_mod).then(|| {
2490-
TypoSuggestion::typo_from_ident(*ident, crate_mod)
2491-
})
2492-
})
2480+
names.extend(self.r.extern_prelude.keys().flat_map(|ident| {
2481+
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
2482+
filter_fn(res)
2483+
.then_some(TypoSuggestion::typo_from_ident(*ident, res))
24932484
}));
24942485

24952486
if let Some(prelude) = self.r.prelude {

compiler/rustc_resolve/src/lib.rs

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,13 +1487,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14871487
let mut invocation_parents = FxHashMap::default();
14881488
invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT);
14891489

1490-
let mut extern_prelude: FxIndexMap<Ident, ExternPreludeEntry<'_>> = tcx
1490+
let mut extern_prelude: FxIndexMap<_, _> = tcx
14911491
.sess
14921492
.opts
14931493
.externs
14941494
.iter()
1495-
.filter(|(_, entry)| entry.add_prelude)
1496-
.map(|(name, _)| (Ident::from_str(name), Default::default()))
1495+
.filter_map(|(name, entry)| {
1496+
// Make sure `self`, `super`, `_` etc do not get into extern prelude.
1497+
// FIXME: reject `--extern self` and similar in option parsing instead.
1498+
if entry.add_prelude
1499+
&& let name = Symbol::intern(name)
1500+
&& name.can_be_raw()
1501+
{
1502+
Some((Ident::with_dummy_span(name), Default::default()))
1503+
} else {
1504+
None
1505+
}
1506+
})
14971507
.collect();
14981508

14991509
if !attr::contains_name(attrs, sym::no_core) {
@@ -2168,40 +2178,42 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21682178
}
21692179

21702180
fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBinding<'ra>> {
2171-
if ident.is_path_segment_keyword() {
2172-
// Make sure `self`, `super` etc produce an error when passed to here.
2173-
return None;
2174-
}
2175-
2176-
let norm_ident = ident.normalize_to_macros_2_0();
2177-
let binding = self.extern_prelude.get(&norm_ident).cloned().and_then(|entry| {
2178-
Some(if let Some(binding) = entry.binding.get() {
2181+
let mut record_use = None;
2182+
let entry = self.extern_prelude.get(&ident.normalize_to_macros_2_0());
2183+
let binding = entry.and_then(|entry| match entry.binding.get() {
2184+
Some(binding) if binding.is_import() => {
21792185
if finalize {
2180-
if !entry.is_import() {
2181-
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
2182-
} else if entry.introduced_by_item {
2183-
self.record_use(ident, binding, Used::Other);
2184-
}
2186+
record_use = Some(binding);
21852187
}
2186-
binding
2187-
} else {
2188+
Some(binding)
2189+
}
2190+
Some(binding) => {
2191+
if finalize {
2192+
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
2193+
}
2194+
Some(binding)
2195+
}
2196+
None => {
21882197
let crate_id = if finalize {
2189-
let Some(crate_id) =
2190-
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span)
2191-
else {
2192-
return Some(self.dummy_binding);
2193-
};
2194-
crate_id
2198+
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span)
21952199
} else {
2196-
self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name)?
2200+
self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name)
21972201
};
2198-
let res = Res::Def(DefKind::Mod, crate_id.as_def_id());
2199-
self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT)
2200-
})
2202+
match crate_id {
2203+
Some(crate_id) => {
2204+
let res = Res::Def(DefKind::Mod, crate_id.as_def_id());
2205+
let binding =
2206+
self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT);
2207+
entry.binding.set(Some(binding));
2208+
Some(binding)
2209+
}
2210+
None => finalize.then_some(self.dummy_binding),
2211+
}
2212+
}
22012213
});
22022214

2203-
if let Some(entry) = self.extern_prelude.get(&norm_ident) {
2204-
entry.binding.set(binding);
2215+
if let Some(binding) = record_use {
2216+
self.record_use(ident, binding, Used::Scope);
22052217
}
22062218

22072219
binding

0 commit comments

Comments
 (0)