Skip to content

Commit 1dcc67f

Browse files
committed
[WIP] resolve: Split extern prelude into two scopes
One for `--extern` options and another for `extern crate` items
1 parent 65b6cdb commit 1dcc67f

File tree

8 files changed

+133
-129
lines changed

8 files changed

+133
-129
lines changed

compiler/rustc_resolve/messages.ftl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,6 @@ resolve_macro_cannot_use_as_derive =
251251
resolve_macro_defined_later =
252252
a macro with the same name exists, but it appears later
253253
254-
resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments =
255-
macro-expanded `extern crate` items cannot shadow names passed with `--extern`
256-
257254
resolve_macro_expected_found =
258255
expected {$expected}, found {$found} `{$macro_path}`
259256
.label = not {$article} {$expected}

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ use crate::def_collector::collect_definitions;
3636
use crate::imports::{ImportData, ImportKind};
3737
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
3838
use crate::{
39-
BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot,
40-
NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Used,
41-
VisResolutionError, errors,
39+
BindingKey, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot, NameBinding,
40+
ParentScope, PathResult, ResolutionError, Resolver, Segment, Used, VisResolutionError, errors,
4241
};
4342

4443
type Res = def::Res<NodeId>;
@@ -968,38 +967,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
968967
}
969968
self.r.potentially_unused_imports.push(import);
970969
let imported_binding = self.r.import(binding, import);
971-
if parent == self.r.graph_root {
970+
if ident.name != kw::Underscore && parent == self.r.graph_root {
972971
let ident = ident.normalize_to_macros_2_0();
973-
if let Some(entry) = self.r.extern_prelude.get(&ident)
974-
&& expansion != LocalExpnId::ROOT
975-
&& orig_name.is_some()
976-
&& !entry.is_import()
977-
{
978-
self.r.dcx().emit_err(
979-
errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span },
980-
);
981-
// `return` is intended to discard this binding because it's an
982-
// unregistered ambiguity error which would result in a panic
983-
// caused by inconsistency `path_res`
984-
// more details: https://github.com/rust-lang/rust/pull/111761
985-
return;
986-
}
987-
let entry = self
988-
.r
989-
.extern_prelude
990-
.entry(ident)
991-
.or_insert(ExternPreludeEntry { binding: None, introduced_by_item: true });
992-
if orig_name.is_some() {
993-
entry.introduced_by_item = true;
994-
}
995-
// Binding from `extern crate` item in source code can replace
996-
// a binding from `--extern` on command line here.
997-
if !entry.is_import() {
998-
entry.binding = Some(imported_binding)
999-
} else if ident.name != kw::Underscore {
972+
if self.r.extern_prelude_item.insert(ident, imported_binding).is_some() {
1000973
self.r.dcx().span_delayed_bug(
1001974
item.span,
1002-
format!("it had been define the external module '{ident}' multiple times"),
975+
format!("extern crate '{ident}' already in extern prelude"),
1003976
);
1004977
}
1005978
}

compiler/rustc_resolve/src/check_unused.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,14 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
200200

201201
// If the extern crate isn't in the extern prelude,
202202
// there is no way it can be written as a `use`.
203-
if self
204-
.r
205-
.extern_prelude
206-
.get(&extern_crate.ident)
207-
.is_none_or(|entry| entry.introduced_by_item)
208-
{
209-
continue;
210-
}
203+
// if self
204+
// .r
205+
// .extern_prelude
206+
// .get(&extern_crate.ident)
207+
// .is_none_or(|entry| entry.introduced_by_item)
208+
// {
209+
// continue;
210+
// }
211211

212212
let module = self
213213
.r

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
322322
// Check if the target of the use for both bindings is the same.
323323
let duplicate = new_binding.res().opt_def_id() == old_binding.res().opt_def_id();
324324
let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy();
325-
let from_item =
326-
self.extern_prelude.get(&ident).is_none_or(|entry| entry.introduced_by_item);
325+
// let from_item = self.extern_prelud.get(&ident).is_none_or(|entry| entry.introduced_by_item);
326+
let from_item = false;
327327
// Only suggest removing an import if both bindings are to the same def, if both spans
328328
// aren't dummy spans. Further, if both bindings are imports, then the ident must have
329329
// been introduced by an item.
@@ -1097,8 +1097,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10971097
);
10981098
}
10991099
}
1100-
Scope::ExternPrelude => {
1101-
suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
1100+
Scope::ExternPreludeItem => {
1101+
suggestions.extend(this.extern_prelude_item.iter().filter_map(|(ident, _)| {
1102+
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
1103+
filter_fn(res).then_some(TypoSuggestion::typo_from_ident(*ident, res))
1104+
}));
1105+
}
1106+
Scope::ExternPreludeCmd => {
1107+
suggestions.extend(this.extern_prelude_cmd.iter().filter_map(|(ident, _)| {
11021108
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
11031109
filter_fn(res).then_some(TypoSuggestion::typo_from_ident(*ident, res))
11041110
}));
@@ -1411,7 +1417,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14111417
);
14121418

14131419
if lookup_ident.span.at_least_rust_2018() {
1414-
for ident in self.extern_prelude.clone().into_keys() {
1420+
// let mut zlaks = Vec::new();
1421+
// for (ident, binding) in &self.extern_prelude_item {
1422+
// zlaks.push(ident, binding.res().def_id());
1423+
// }
1424+
for ident in self.extern_prelude_item.clone().into_keys() {
1425+
if true {
1426+
continue;
1427+
}
14151428
if ident.span.from_expansion() {
14161429
// Idents are adjusted to the root context before being
14171430
// resolved in the extern prelude, so reporting this to the
@@ -2150,9 +2163,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21502163
current_module: Module<'ra>,
21512164
) -> Option<Symbol> {
21522165
let mut candidates = self
2153-
.extern_prelude
2166+
.extern_prelude_item
21542167
.keys()
21552168
.map(|ident| ident.name)
2169+
.chain(self.extern_prelude_cmd.keys().map(|ident| ident.name))
21562170
.chain(
21572171
self.local_module_map
21582172
.iter()
@@ -2611,8 +2625,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
26112625
// Sort extern crate names in *reverse* order to get
26122626
// 1) some consistent ordering for emitted diagnostics, and
26132627
// 2) `std` suggestions before `core` suggestions.
2614-
let mut extern_crate_names =
2615-
self.extern_prelude.keys().map(|ident| ident.name).collect::<Vec<_>>();
2628+
let mut extern_crate_names = self
2629+
.extern_prelude_item
2630+
.keys()
2631+
.chain(self.extern_prelude_cmd.keys())
2632+
.map(|ident| ident.name)
2633+
.collect::<Vec<_>>();
26162634
extern_crate_names.sort_by(|a, b| b.as_str().cmp(a.as_str()));
26172635

26182636
for name in extern_crate_names.into_iter() {

compiler/rustc_resolve/src/errors.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -862,13 +862,6 @@ pub(crate) struct UnnamedCrateRootImport {
862862
pub(crate) span: Span,
863863
}
864864

865-
#[derive(Diagnostic)]
866-
#[diag(resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments)]
867-
pub(crate) struct MacroExpandedExternCrateCannotShadowExternArguments {
868-
#[primary_span]
869-
pub(crate) span: Span,
870-
}
871-
872865
#[derive(Diagnostic)]
873866
#[diag(resolve_elided_anonymous_lifetime_report_error, code = E0637)]
874867
pub(crate) struct ElidedAnonymousLifetimeReportError {

compiler/rustc_resolve/src/ident.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
138138
Scope::Module(..) => true,
139139
Scope::MacroUsePrelude => use_prelude || rust_2015,
140140
Scope::BuiltinAttrs => true,
141-
Scope::ExternPrelude => use_prelude || module_and_extern_prelude,
141+
Scope::ExternPreludeCmd | Scope::ExternPreludeItem => {
142+
use_prelude || module_and_extern_prelude
143+
}
142144
Scope::ToolPrelude => use_prelude,
143145
Scope::StdLibPrelude => use_prelude || ns == MacroNS,
144146
Scope::BuiltinTypes => true,
@@ -177,7 +179,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
177179
Scope::Module(..) if module_and_extern_prelude => match ns {
178180
TypeNS => {
179181
ctxt.adjust(ExpnId::root());
180-
Scope::ExternPrelude
182+
Scope::ExternPreludeItem
181183
}
182184
ValueNS | MacroNS => break,
183185
},
@@ -194,7 +196,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
194196
None => {
195197
ctxt.adjust(ExpnId::root());
196198
match ns {
197-
TypeNS => Scope::ExternPrelude,
199+
TypeNS => Scope::ExternPreludeItem,
198200
ValueNS => Scope::StdLibPrelude,
199201
MacroNS => Scope::MacroUsePrelude,
200202
}
@@ -203,8 +205,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
203205
}
204206
Scope::MacroUsePrelude => Scope::StdLibPrelude,
205207
Scope::BuiltinAttrs => break, // nowhere else to search
206-
Scope::ExternPrelude if module_and_extern_prelude => break,
207-
Scope::ExternPrelude => Scope::ToolPrelude,
208+
Scope::ExternPreludeItem => Scope::ExternPreludeCmd,
209+
Scope::ExternPreludeCmd if module_and_extern_prelude => break,
210+
Scope::ExternPreludeCmd => Scope::ToolPrelude,
208211
Scope::ToolPrelude => Scope::StdLibPrelude,
209212
Scope::StdLibPrelude => match ns {
210213
TypeNS => Scope::BuiltinTypes,
@@ -555,14 +558,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
555558
Some(binding) => Ok((*binding, Flags::empty())),
556559
None => Err(Determinacy::Determined),
557560
},
558-
Scope::ExternPrelude => {
559-
match this.extern_prelude_get(ident, finalize.is_some()) {
561+
Scope::ExternPreludeItem => {
562+
match this.extern_prelude_get_item(ident, finalize.is_some()) {
560563
Some(binding) => Ok((binding, Flags::empty())),
561564
None => Err(Determinacy::determined(
562565
this.graph_root.unexpanded_invocations.borrow().is_empty(),
563566
)),
564567
}
565568
}
569+
Scope::ExternPreludeCmd => {
570+
match this.extern_prelude_get_cmd(ident, finalize.is_some()) {
571+
Some(binding) => Ok((binding, Flags::empty())),
572+
None => Err(Determinacy::Determined),
573+
}
574+
}
566575
Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) {
567576
Some(binding) => Ok((*binding, Flags::empty())),
568577
None => Err(Determinacy::Determined),
@@ -812,11 +821,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
812821
assert_eq!(shadowing, Shadowing::Unrestricted);
813822
return if ns != TypeNS {
814823
Err((Determined, Weak::No))
815-
} else if let Some(binding) = self.extern_prelude_get(ident, finalize.is_some()) {
824+
} else if let Some(binding) =
825+
self.extern_prelude_get_item(ident, finalize.is_some())
826+
{
816827
Ok(binding)
817828
} else if !self.graph_root.unexpanded_invocations.borrow().is_empty() {
818829
// Macro-expanded `extern crate` items can add names to extern prelude.
819830
Err((Undetermined, Weak::No))
831+
} else if let Some(binding) = self.extern_prelude_get_cmd(ident, finalize.is_some())
832+
{
833+
Ok(binding)
820834
} else {
821835
Err((Determined, Weak::No))
822836
};

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,20 +2477,17 @@ 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, _)| {
2480+
names.extend(
24822481
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-
})
2493-
}));
2482+
.extern_prelude_item
2483+
.keys()
2484+
.chain(self.r.extern_prelude_cmd.keys())
2485+
.flat_map(|ident| {
2486+
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
2487+
filter_fn(res)
2488+
.then(|| TypoSuggestion::typo_from_ident(*ident, res))
2489+
}),
2490+
);
24942491

24952492
if let Some(prelude) = self.r.prelude {
24962493
self.r.add_module_candidates(prelude, &mut names, &filter_fn, None);

0 commit comments

Comments
 (0)