resolve: Split extern prelude into two scopes
One for `--extern` options and another for `extern crate` items.
This commit is contained in:
@@ -971,40 +971,35 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||
let imported_binding = self.r.import(binding, import);
|
||||
if ident.name != kw::Underscore && parent == self.r.graph_root {
|
||||
let norm_ident = Macros20NormalizedIdent::new(ident);
|
||||
// FIXME: this error is technically unnecessary now when extern prelude is split into
|
||||
// two scopes, remove it with lang team approval.
|
||||
if let Some(entry) = self.r.extern_prelude.get(&norm_ident)
|
||||
&& expansion != LocalExpnId::ROOT
|
||||
&& orig_name.is_some()
|
||||
&& !entry.is_import()
|
||||
&& entry.item_binding.is_none()
|
||||
{
|
||||
self.r.dcx().emit_err(
|
||||
errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span },
|
||||
);
|
||||
// `return` is intended to discard this binding because it's an
|
||||
// unregistered ambiguity error which would result in a panic
|
||||
// caused by inconsistency `path_res`
|
||||
// more details: https://github.com/rust-lang/rust/pull/111761
|
||||
return;
|
||||
}
|
||||
|
||||
use indexmap::map::Entry;
|
||||
match self.r.extern_prelude.entry(norm_ident) {
|
||||
Entry::Occupied(mut occupied) => {
|
||||
let entry = occupied.get_mut();
|
||||
if let Some(old_binding) = entry.binding.get()
|
||||
&& old_binding.is_import()
|
||||
{
|
||||
if entry.item_binding.is_some() {
|
||||
let msg = format!("extern crate `{ident}` already in extern prelude");
|
||||
self.r.tcx.dcx().span_delayed_bug(item.span, msg);
|
||||
} else {
|
||||
// Binding from `extern crate` item in source code can replace
|
||||
// a binding from `--extern` on command line here.
|
||||
entry.binding.set(Some(imported_binding));
|
||||
entry.item_binding = Some(imported_binding);
|
||||
entry.introduced_by_item = orig_name.is_some();
|
||||
}
|
||||
entry
|
||||
}
|
||||
Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry {
|
||||
binding: Cell::new(Some(imported_binding)),
|
||||
item_binding: Some(imported_binding),
|
||||
flag_binding: Cell::new(None),
|
||||
only_item: true,
|
||||
introduced_by_item: true,
|
||||
}),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user