resolve: Split extern prelude into two scopes

One for `--extern` options and another for `extern crate` items.
This commit is contained in:
Vadim Petrochenkov
2025-08-01 18:07:59 +03:00
parent 350d0ef0ec
commit 772493d51d
14 changed files with 212 additions and 86 deletions

View File

@@ -1,8 +1,10 @@
#### Note: this error code is no longer emitted by the compiler.
A module cannot be found and therefore, the visibility cannot be determined. A module cannot be found and therefore, the visibility cannot be determined.
Erroneous code example: Erroneous code example:
```compile_fail,E0578,edition2018 ```ignore (no longer emitted)
foo!(); foo!();
pub (in ::Sea) struct Shark; // error! pub (in ::Sea) struct Shark; // error!

View File

@@ -971,40 +971,35 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let imported_binding = self.r.import(binding, import); let imported_binding = self.r.import(binding, import);
if ident.name != kw::Underscore && parent == self.r.graph_root { if ident.name != kw::Underscore && parent == self.r.graph_root {
let norm_ident = Macros20NormalizedIdent::new(ident); 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) if let Some(entry) = self.r.extern_prelude.get(&norm_ident)
&& expansion != LocalExpnId::ROOT && expansion != LocalExpnId::ROOT
&& orig_name.is_some() && orig_name.is_some()
&& !entry.is_import() && entry.item_binding.is_none()
{ {
self.r.dcx().emit_err( self.r.dcx().emit_err(
errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span }, 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; use indexmap::map::Entry;
match self.r.extern_prelude.entry(norm_ident) { match self.r.extern_prelude.entry(norm_ident) {
Entry::Occupied(mut occupied) => { Entry::Occupied(mut occupied) => {
let entry = occupied.get_mut(); let entry = occupied.get_mut();
if let Some(old_binding) = entry.binding.get() if entry.item_binding.is_some() {
&& old_binding.is_import()
{
let msg = format!("extern crate `{ident}` already in extern prelude"); let msg = format!("extern crate `{ident}` already in extern prelude");
self.r.tcx.dcx().span_delayed_bug(item.span, msg); self.r.tcx.dcx().span_delayed_bug(item.span, msg);
} else { } else {
// Binding from `extern crate` item in source code can replace entry.item_binding = Some(imported_binding);
// a binding from `--extern` on command line here.
entry.binding.set(Some(imported_binding));
entry.introduced_by_item = orig_name.is_some(); entry.introduced_by_item = orig_name.is_some();
} }
entry entry
} }
Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry { 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, introduced_by_item: true,
}), }),
}; };

View File

@@ -1096,12 +1096,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
); );
} }
} }
Scope::ExternPrelude => { Scope::ExternPreludeItems => {
// Add idents from both item and flag scopes.
suggestions.extend(this.extern_prelude.keys().filter_map(|ident| { suggestions.extend(this.extern_prelude.keys().filter_map(|ident| {
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id()); let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
filter_fn(res).then_some(TypoSuggestion::typo_from_ident(ident.0, res)) filter_fn(res).then_some(TypoSuggestion::typo_from_ident(ident.0, res))
})); }));
} }
Scope::ExternPreludeFlags => {}
Scope::ToolPrelude => { Scope::ToolPrelude => {
let res = Res::NonMacroAttr(NonMacroAttrKind::Tool); let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
suggestions.extend( suggestions.extend(

View File

@@ -102,6 +102,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns) ScopeSet::All(ns)
| ScopeSet::ModuleAndExternPrelude(ns, _) | ScopeSet::ModuleAndExternPrelude(ns, _)
| ScopeSet::Late(ns, ..) => (ns, None), | ScopeSet::Late(ns, ..) => (ns, None),
ScopeSet::ExternPrelude => (TypeNS, None),
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
}; };
let module = match scope_set { let module = match scope_set {
@@ -111,8 +112,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
_ => parent_scope.module.nearest_item_scope(), _ => parent_scope.module.nearest_item_scope(),
}; };
let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)); let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);
let mut scope = match ns { let mut scope = match ns {
_ if module_and_extern_prelude => Scope::Module(module, None), _ if module_and_extern_prelude => Scope::Module(module, None),
_ if extern_prelude => Scope::ExternPreludeItems,
TypeNS | ValueNS => Scope::Module(module, None), TypeNS | ValueNS => Scope::Module(module, None),
MacroNS => Scope::DeriveHelpers(parent_scope.expansion), MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
}; };
@@ -143,7 +146,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Scope::Module(..) => true, Scope::Module(..) => true,
Scope::MacroUsePrelude => use_prelude || rust_2015, Scope::MacroUsePrelude => use_prelude || rust_2015,
Scope::BuiltinAttrs => true, Scope::BuiltinAttrs => true,
Scope::ExternPrelude => use_prelude || module_and_extern_prelude, Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {
use_prelude || module_and_extern_prelude || extern_prelude
}
Scope::ToolPrelude => use_prelude, Scope::ToolPrelude => use_prelude,
Scope::StdLibPrelude => use_prelude || ns == MacroNS, Scope::StdLibPrelude => use_prelude || ns == MacroNS,
Scope::BuiltinTypes => true, Scope::BuiltinTypes => true,
@@ -182,7 +187,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Scope::Module(..) if module_and_extern_prelude => match ns { Scope::Module(..) if module_and_extern_prelude => match ns {
TypeNS => { TypeNS => {
ctxt.adjust(ExpnId::root()); ctxt.adjust(ExpnId::root());
Scope::ExternPrelude Scope::ExternPreludeItems
} }
ValueNS | MacroNS => break, ValueNS | MacroNS => break,
}, },
@@ -199,7 +204,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None => { None => {
ctxt.adjust(ExpnId::root()); ctxt.adjust(ExpnId::root());
match ns { match ns {
TypeNS => Scope::ExternPrelude, TypeNS => Scope::ExternPreludeItems,
ValueNS => Scope::StdLibPrelude, ValueNS => Scope::StdLibPrelude,
MacroNS => Scope::MacroUsePrelude, MacroNS => Scope::MacroUsePrelude,
} }
@@ -208,8 +213,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
Scope::MacroUsePrelude => Scope::StdLibPrelude, Scope::MacroUsePrelude => Scope::StdLibPrelude,
Scope::BuiltinAttrs => break, // nowhere else to search Scope::BuiltinAttrs => break, // nowhere else to search
Scope::ExternPrelude if module_and_extern_prelude => break, Scope::ExternPreludeItems => Scope::ExternPreludeFlags,
Scope::ExternPrelude => Scope::ToolPrelude, Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,
Scope::ExternPreludeFlags => Scope::ToolPrelude,
Scope::ToolPrelude => Scope::StdLibPrelude, Scope::ToolPrelude => Scope::StdLibPrelude,
Scope::StdLibPrelude => match ns { Scope::StdLibPrelude => match ns {
TypeNS => Scope::BuiltinTypes, TypeNS => Scope::BuiltinTypes,
@@ -413,6 +419,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns) ScopeSet::All(ns)
| ScopeSet::ModuleAndExternPrelude(ns, _) | ScopeSet::ModuleAndExternPrelude(ns, _)
| ScopeSet::Late(ns, ..) => (ns, None), | ScopeSet::Late(ns, ..) => (ns, None),
ScopeSet::ExternPrelude => (TypeNS, None),
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
}; };
@@ -429,6 +436,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// to detect potential ambiguities. // to detect potential ambiguities.
let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None; let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
let mut determinacy = Determinacy::Determined; let mut determinacy = Determinacy::Determined;
// Shadowed bindings don't need to be marked as used or non-speculatively loaded.
macro finalize_scope() {
if innermost_result.is_none() { finalize } else { None }
}
// Go through all the scopes and try to resolve the name. // Go through all the scopes and try to resolve the name.
let break_result = self.visit_scopes( let break_result = self.visit_scopes(
@@ -494,7 +505,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
_ => Err(Determinacy::Determined), _ => Err(Determinacy::Determined),
}, },
Scope::Module(module, derive_fallback_lint_id) => { Scope::Module(module, derive_fallback_lint_id) => {
let (adjusted_parent_scope, finalize) = // FIXME: use `finalize_scope` here.
let (adjusted_parent_scope, adjusted_finalize) =
if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) { if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) {
(parent_scope, finalize) (parent_scope, finalize)
} else { } else {
@@ -513,7 +525,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} else { } else {
Shadowing::Restricted Shadowing::Restricted
}, },
finalize, adjusted_finalize,
ignore_binding, ignore_binding,
ignore_import, ignore_import,
); );
@@ -561,14 +573,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Some(binding) => Ok((*binding, Flags::empty())), Some(binding) => Ok((*binding, Flags::empty())),
None => Err(Determinacy::Determined), None => Err(Determinacy::Determined),
}, },
Scope::ExternPrelude => { Scope::ExternPreludeItems => {
match this.reborrow().extern_prelude_get(ident, finalize.is_some()) { // FIXME: use `finalize_scope` here.
match this.reborrow().extern_prelude_get_item(ident, finalize.is_some()) {
Some(binding) => Ok((binding, Flags::empty())), Some(binding) => Ok((binding, Flags::empty())),
None => Err(Determinacy::determined( None => Err(Determinacy::determined(
this.graph_root.unexpanded_invocations.borrow().is_empty(), this.graph_root.unexpanded_invocations.borrow().is_empty(),
)), )),
} }
} }
Scope::ExternPreludeFlags => {
match this.extern_prelude_get_flag(ident, finalize_scope!().is_some()) {
Some(binding) => Ok((binding, Flags::empty())),
None => Err(Determinacy::Determined),
}
}
Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) { Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) {
Some(binding) => Ok((*binding, Flags::empty())), Some(binding) => Ok((*binding, Flags::empty())),
None => Err(Determinacy::Determined), None => Err(Determinacy::Determined),
@@ -599,8 +618,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if matches!(ident.name, sym::f16) if matches!(ident.name, sym::f16)
&& !this.tcx.features().f16() && !this.tcx.features().f16()
&& !ident.span.allows_unstable(sym::f16) && !ident.span.allows_unstable(sym::f16)
&& finalize.is_some() && finalize_scope!().is_some()
&& innermost_result.is_none()
{ {
feature_err( feature_err(
this.tcx.sess, this.tcx.sess,
@@ -613,8 +631,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if matches!(ident.name, sym::f128) if matches!(ident.name, sym::f128)
&& !this.tcx.features().f128() && !this.tcx.features().f128()
&& !ident.span.allows_unstable(sym::f128) && !ident.span.allows_unstable(sym::f128)
&& finalize.is_some() && finalize_scope!().is_some()
&& innermost_result.is_none()
{ {
feature_err( feature_err(
this.tcx.sess, this.tcx.sess,
@@ -829,15 +846,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
assert_eq!(shadowing, Shadowing::Unrestricted); assert_eq!(shadowing, Shadowing::Unrestricted);
return if ns != TypeNS { return if ns != TypeNS {
Err((Determined, Weak::No)) Err((Determined, Weak::No))
} else if let Some(binding) =
self.reborrow().extern_prelude_get(ident, finalize.is_some())
{
Ok(binding)
} else if !self.graph_root.unexpanded_invocations.borrow().is_empty() {
// Macro-expanded `extern crate` items can add names to extern prelude.
Err((Undetermined, Weak::No))
} else { } else {
Err((Determined, Weak::No)) let binding = self.early_resolve_ident_in_lexical_scope(
ident,
ScopeSet::ExternPrelude,
parent_scope,
finalize,
finalize.is_some(),
ignore_binding,
ignore_import,
);
return binding.map_err(|determinacy| (determinacy, Weak::No));
}; };
} }
ModuleOrUniformRoot::CurrentScope => { ModuleOrUniformRoot::CurrentScope => {

View File

@@ -15,6 +15,7 @@
#![feature(arbitrary_self_types)] #![feature(arbitrary_self_types)]
#![feature(assert_matches)] #![feature(assert_matches)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(iter_intersperse)] #![feature(iter_intersperse)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
@@ -113,34 +114,46 @@ impl Determinacy {
} }
/// A specific scope in which a name can be looked up. /// A specific scope in which a name can be looked up.
/// This enum is currently used only for early resolution (imports and macros),
/// but not for late resolution yet.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
enum Scope<'ra> { enum Scope<'ra> {
/// Inert attributes registered by derive macros.
DeriveHelpers(LocalExpnId), DeriveHelpers(LocalExpnId),
/// Inert attributes registered by derive macros, but used before they are actually declared.
/// This scope will exist until the compatibility lint `LEGACY_DERIVE_HELPERS`
/// is turned into a hard error.
DeriveHelpersCompat, DeriveHelpersCompat,
/// Textual `let`-like scopes introduced by `macro_rules!` items.
MacroRules(MacroRulesScopeRef<'ra>), MacroRules(MacroRulesScopeRef<'ra>),
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` /// Names declared in the given module.
// lint if it should be reported. /// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
/// lint if it should be reported.
Module(Module<'ra>, Option<NodeId>), Module(Module<'ra>, Option<NodeId>),
/// Names introduced by `#[macro_use]` attributes on `extern crate` items.
MacroUsePrelude, MacroUsePrelude,
/// Built-in attributes.
BuiltinAttrs, BuiltinAttrs,
ExternPrelude, /// Extern prelude names introduced by `extern crate` items.
ExternPreludeItems,
/// Extern prelude names introduced by `--extern` flags.
ExternPreludeFlags,
/// Tool modules introduced with `#![register_tool]`.
ToolPrelude, ToolPrelude,
/// Standard library prelude introduced with an internal `#[prelude_import]` import.
StdLibPrelude, StdLibPrelude,
/// Built-in types.
BuiltinTypes, BuiltinTypes,
} }
/// Names from different contexts may want to visit different subsets of all specific scopes /// Names from different contexts may want to visit different subsets of all specific scopes
/// with different restrictions when looking up the resolution. /// with different restrictions when looking up the resolution.
/// This enum is currently used only for early resolution (imports and macros),
/// but not for late resolution yet.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
enum ScopeSet<'ra> { enum ScopeSet<'ra> {
/// All scopes with the given namespace. /// All scopes with the given namespace.
All(Namespace), All(Namespace),
/// A module, then extern prelude (used for mixed 2015-2018 mode in macros). /// A module, then extern prelude (used for mixed 2015-2018 mode in macros).
ModuleAndExternPrelude(Namespace, Module<'ra>), ModuleAndExternPrelude(Namespace, Module<'ra>),
/// Just two extern prelude scopes.
ExternPrelude,
/// All scopes with macro namespace and the given macro kind restriction. /// All scopes with macro namespace and the given macro kind restriction.
Macro(MacroKind), Macro(MacroKind),
/// All scopes with the given namespace, used for partially performing late resolution. /// All scopes with the given namespace, used for partially performing late resolution.
@@ -1012,16 +1025,18 @@ impl<'ra> NameBindingData<'ra> {
#[derive(Default, Clone)] #[derive(Default, Clone)]
struct ExternPreludeEntry<'ra> { struct ExternPreludeEntry<'ra> {
binding: Cell<Option<NameBinding<'ra>>>, /// Binding from an `extern crate` item.
item_binding: Option<NameBinding<'ra>>,
/// Binding from an `--extern` flag, lazily populated on first use.
flag_binding: Cell<Option<NameBinding<'ra>>>,
/// There was no `--extern` flag introducing this name,
/// `flag_binding` doesn't need to be populated.
only_item: bool,
/// `item_binding` is non-redundant, happens either when `only_item` is true,
/// or when `extern crate` introducing `item_binding` used renaming.
introduced_by_item: bool, introduced_by_item: bool,
} }
impl ExternPreludeEntry<'_> {
fn is_import(&self) -> bool {
self.binding.get().is_some_and(|binding| binding.is_import())
}
}
struct DeriveData { struct DeriveData {
resolutions: Vec<DeriveResolution>, resolutions: Vec<DeriveResolution>,
helper_attrs: Vec<(usize, Ident)>, helper_attrs: Vec<(usize, Ident)>,
@@ -1889,7 +1904,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
this.get_mut().traits_in_module(module, assoc_item, &mut found_traits); this.get_mut().traits_in_module(module, assoc_item, &mut found_traits);
} }
} }
Scope::ExternPrelude | Scope::ToolPrelude | Scope::BuiltinTypes => {} Scope::ExternPreludeItems
| Scope::ExternPreludeFlags
| Scope::ToolPrelude
| Scope::BuiltinTypes => {}
_ => unreachable!(), _ => unreachable!(),
} }
None::<()> None::<()>
@@ -2054,7 +2072,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// but not introduce it, as used if they are accessed from lexical scope. // but not introduce it, as used if they are accessed from lexical scope.
if used == Used::Scope { if used == Used::Scope {
if let Some(entry) = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)) { if let Some(entry) = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)) {
if !entry.introduced_by_item && entry.binding.get() == Some(used_binding) { if !entry.introduced_by_item && entry.item_binding == Some(used_binding) {
return; return;
} }
} }
@@ -2210,26 +2228,30 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
} }
fn extern_prelude_get<'r>( fn extern_prelude_get_item<'r>(
mut self: CmResolver<'r, 'ra, 'tcx>, mut self: CmResolver<'r, 'ra, 'tcx>,
ident: Ident, ident: Ident,
finalize: bool, finalize: bool,
) -> Option<NameBinding<'ra>> { ) -> Option<NameBinding<'ra>> {
let mut record_use = None;
let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)); let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident));
let binding = entry.and_then(|entry| match entry.binding.get() { entry.and_then(|entry| entry.item_binding).map(|binding| {
Some(binding) if binding.is_import() => { if finalize {
if finalize { self.get_mut().record_use(ident, binding, Used::Scope);
record_use = Some(binding);
}
Some(binding)
} }
binding
})
}
fn extern_prelude_get_flag(&self, ident: Ident, finalize: bool) -> Option<NameBinding<'ra>> {
let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident));
entry.and_then(|entry| match entry.flag_binding.get() {
Some(binding) => { Some(binding) => {
if finalize { if finalize {
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span); self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
} }
Some(binding) Some(binding)
} }
None if entry.only_item => None,
None => { None => {
let crate_id = if finalize { let crate_id = if finalize {
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span) self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span)
@@ -2241,19 +2263,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let res = Res::Def(DefKind::Mod, crate_id.as_def_id()); let res = Res::Def(DefKind::Mod, crate_id.as_def_id());
let binding = let binding =
self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT); self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT);
entry.binding.set(Some(binding)); entry.flag_binding.set(Some(binding));
Some(binding) Some(binding)
} }
None => finalize.then_some(self.dummy_binding), None => finalize.then_some(self.dummy_binding),
} }
} }
}); })
if let Some(binding) = record_use {
self.get_mut().record_use(ident, binding, Used::Scope);
}
binding
} }
/// Rustdoc uses this to resolve doc link paths in a recoverable way. `PathResult<'a>` /// Rustdoc uses this to resolve doc link paths in a recoverable way. `PathResult<'a>`

View File

@@ -10,6 +10,7 @@ macro_rules! m {
m!(); m!();
use std::mem; use std::mem; //~ ERROR `std` is ambiguous
use ::std::mem as _; //~ ERROR `std` is ambiguous
fn main() {} fn main() {}

View File

@@ -9,5 +9,47 @@ LL | m!();
| |
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 1 previous error error[E0659]: `std` is ambiguous
--> $DIR/issue-109148.rs:13:5
|
LL | use std::mem;
| ^^^ ambiguous name
|
= note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
= note: `std` could refer to a built-in crate
= help: use `::std` to refer to this crate unambiguously
note: `std` could also refer to the crate imported here
--> $DIR/issue-109148.rs:6:9
|
LL | extern crate core as std;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | m!();
| ---- in this macro invocation
= help: use `::std` to refer to this crate unambiguously
= help: or use `crate::std` to refer to this crate unambiguously
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0659]: `std` is ambiguous
--> $DIR/issue-109148.rs:14:7
|
LL | use ::std::mem as _;
| ^^^ ambiguous name
|
= note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
= note: `std` could refer to a built-in crate
= help: use `::std` to refer to this crate unambiguously
note: `std` could also refer to the crate imported here
--> $DIR/issue-109148.rs:6:9
|
LL | extern crate core as std;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | m!();
| ---- in this macro invocation
= help: use `::std` to refer to this crate unambiguously
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0659`.

View File

@@ -1,3 +1,5 @@
//@ edition: 2018
macro_rules! define_other_core { macro_rules! define_other_core {
( ) => { ( ) => {
extern crate std as core; extern crate std as core;
@@ -6,7 +8,8 @@ macro_rules! define_other_core {
} }
fn main() { fn main() {
core::panic!(); core::panic!(); //~ ERROR `core` is ambiguous
::core::panic!(); //~ ERROR `core` is ambiguous
} }
define_other_core!(); define_other_core!();

View File

@@ -1,5 +1,5 @@
error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` error: macro-expanded `extern crate` items cannot shadow names passed with `--extern`
--> $DIR/issue-78325-inconsistent-resolution.rs:3:9 --> $DIR/issue-78325-inconsistent-resolution.rs:5:9
| |
LL | extern crate std as core; LL | extern crate std as core;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,5 +9,47 @@ LL | define_other_core!();
| |
= note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 1 previous error error[E0659]: `core` is ambiguous
--> $DIR/issue-78325-inconsistent-resolution.rs:11:5
|
LL | core::panic!();
| ^^^^ ambiguous name
|
= note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
= note: `core` could refer to a built-in crate
= help: use `::core` to refer to this crate unambiguously
note: `core` could also refer to the crate imported here
--> $DIR/issue-78325-inconsistent-resolution.rs:5:9
|
LL | extern crate std as core;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | define_other_core!();
| -------------------- in this macro invocation
= help: use `::core` to refer to this crate unambiguously
= help: or use `crate::core` to refer to this crate unambiguously
= note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0659]: `core` is ambiguous
--> $DIR/issue-78325-inconsistent-resolution.rs:12:7
|
LL | ::core::panic!();
| ^^^^ ambiguous name
|
= note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
= note: `core` could refer to a built-in crate
= help: use `::core` to refer to this crate unambiguously
note: `core` could also refer to the crate imported here
--> $DIR/issue-78325-inconsistent-resolution.rs:5:9
|
LL | extern crate std as core;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | define_other_core!();
| -------------------- in this macro invocation
= help: use `::core` to refer to this crate unambiguously
= note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0659`.

View File

@@ -0,0 +1,10 @@
// Non-existent path in `--extern` doesn't result in an error if it's shadowed by `extern crate`.
//@ check-pass
//@ compile-flags: --extern something=/path/to/nowhere
extern crate std as something;
fn main() {
something::println!();
}

View File

@@ -2,6 +2,6 @@
foo!(); //~ ERROR cannot find macro `foo` in this scope foo!(); //~ ERROR cannot find macro `foo` in this scope
pub(in ::bar) struct Baz {} //~ ERROR cannot determine resolution for the visibility pub(in ::bar) struct Baz {} //~ ERROR failed to resolve: could not find `bar` in the list of imported crates
fn main() {} fn main() {}

View File

@@ -1,8 +1,8 @@
error[E0578]: cannot determine resolution for the visibility error[E0433]: failed to resolve: could not find `bar` in the list of imported crates
--> $DIR/visibility-indeterminate.rs:5:8 --> $DIR/visibility-indeterminate.rs:5:10
| |
LL | pub(in ::bar) struct Baz {} LL | pub(in ::bar) struct Baz {}
| ^^^^^ | ^^^ could not find `bar` in the list of imported crates
error: cannot find macro `foo` in this scope error: cannot find macro `foo` in this scope
--> $DIR/visibility-indeterminate.rs:3:1 --> $DIR/visibility-indeterminate.rs:3:1
@@ -12,4 +12,4 @@ LL | foo!();
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0578`. For more information about this error, try `rustc --explain E0433`.

View File

@@ -2,7 +2,7 @@
//@ compile-flags:--extern foo --extern bar //@ compile-flags:--extern foo --extern bar
use bar::foo; //~ ERROR can't find crate for `bar` use bar::foo; //~ ERROR can't find crate for `bar`
use foo::bar; //~ ERROR can't find crate for `foo` use foo::bar;
//~^^ ERROR unresolved imports `bar::foo`, `foo::bar` //~^^ ERROR unresolved imports `bar::foo`, `foo::bar`
fn main() {} fn main() {}

View File

@@ -4,12 +4,6 @@ error[E0463]: can't find crate for `bar`
LL | use bar::foo; LL | use bar::foo;
| ^^^ can't find crate | ^^^ can't find crate
error[E0463]: can't find crate for `foo`
--> $DIR/deadlock.rs:5:5
|
LL | use foo::bar;
| ^^^ can't find crate
error[E0432]: unresolved imports `bar::foo`, `foo::bar` error[E0432]: unresolved imports `bar::foo`, `foo::bar`
--> $DIR/deadlock.rs:4:5 --> $DIR/deadlock.rs:4:5
| |
@@ -18,7 +12,7 @@ LL | use bar::foo;
LL | use foo::bar; LL | use foo::bar;
| ^^^^^^^^ | ^^^^^^^^
error: aborting due to 3 previous errors error: aborting due to 2 previous errors
Some errors have detailed explanations: E0432, E0463. Some errors have detailed explanations: E0432, E0463.
For more information about an error, try `rustc --explain E0432`. For more information about an error, try `rustc --explain E0432`.