resolve: Split extern prelude into two scopes
One for `--extern` options and another for `extern crate` items.
This commit is contained in:
@@ -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.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0578,edition2018
|
||||
```ignore (no longer emitted)
|
||||
foo!();
|
||||
|
||||
pub (in ::Sea) struct Shark; // error!
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -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| {
|
||||
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
|
||||
filter_fn(res).then_some(TypoSuggestion::typo_from_ident(ident.0, res))
|
||||
}));
|
||||
}
|
||||
Scope::ExternPreludeFlags => {}
|
||||
Scope::ToolPrelude => {
|
||||
let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
|
||||
suggestions.extend(
|
||||
|
||||
@@ -102,6 +102,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
ScopeSet::All(ns)
|
||||
| ScopeSet::ModuleAndExternPrelude(ns, _)
|
||||
| ScopeSet::Late(ns, ..) => (ns, None),
|
||||
ScopeSet::ExternPrelude => (TypeNS, None),
|
||||
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
|
||||
};
|
||||
let module = match scope_set {
|
||||
@@ -111,8 +112,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
_ => parent_scope.module.nearest_item_scope(),
|
||||
};
|
||||
let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
|
||||
let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);
|
||||
let mut scope = match ns {
|
||||
_ if module_and_extern_prelude => Scope::Module(module, None),
|
||||
_ if extern_prelude => Scope::ExternPreludeItems,
|
||||
TypeNS | ValueNS => Scope::Module(module, None),
|
||||
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
|
||||
};
|
||||
@@ -143,7 +146,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
Scope::Module(..) => true,
|
||||
Scope::MacroUsePrelude => use_prelude || rust_2015,
|
||||
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::StdLibPrelude => use_prelude || ns == MacroNS,
|
||||
Scope::BuiltinTypes => true,
|
||||
@@ -182,7 +187,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
Scope::Module(..) if module_and_extern_prelude => match ns {
|
||||
TypeNS => {
|
||||
ctxt.adjust(ExpnId::root());
|
||||
Scope::ExternPrelude
|
||||
Scope::ExternPreludeItems
|
||||
}
|
||||
ValueNS | MacroNS => break,
|
||||
},
|
||||
@@ -199,7 +204,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
None => {
|
||||
ctxt.adjust(ExpnId::root());
|
||||
match ns {
|
||||
TypeNS => Scope::ExternPrelude,
|
||||
TypeNS => Scope::ExternPreludeItems,
|
||||
ValueNS => Scope::StdLibPrelude,
|
||||
MacroNS => Scope::MacroUsePrelude,
|
||||
}
|
||||
@@ -208,8 +213,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
}
|
||||
Scope::MacroUsePrelude => Scope::StdLibPrelude,
|
||||
Scope::BuiltinAttrs => break, // nowhere else to search
|
||||
Scope::ExternPrelude if module_and_extern_prelude => break,
|
||||
Scope::ExternPrelude => Scope::ToolPrelude,
|
||||
Scope::ExternPreludeItems => Scope::ExternPreludeFlags,
|
||||
Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,
|
||||
Scope::ExternPreludeFlags => Scope::ToolPrelude,
|
||||
Scope::ToolPrelude => Scope::StdLibPrelude,
|
||||
Scope::StdLibPrelude => match ns {
|
||||
TypeNS => Scope::BuiltinTypes,
|
||||
@@ -413,6 +419,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
ScopeSet::All(ns)
|
||||
| ScopeSet::ModuleAndExternPrelude(ns, _)
|
||||
| ScopeSet::Late(ns, ..) => (ns, None),
|
||||
ScopeSet::ExternPrelude => (TypeNS, None),
|
||||
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
|
||||
};
|
||||
|
||||
@@ -429,6 +436,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
// to detect potential ambiguities.
|
||||
let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
|
||||
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.
|
||||
let break_result = self.visit_scopes(
|
||||
@@ -494,7 +505,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
_ => Err(Determinacy::Determined),
|
||||
},
|
||||
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(..)) {
|
||||
(parent_scope, finalize)
|
||||
} else {
|
||||
@@ -513,7 +525,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
} else {
|
||||
Shadowing::Restricted
|
||||
},
|
||||
finalize,
|
||||
adjusted_finalize,
|
||||
ignore_binding,
|
||||
ignore_import,
|
||||
);
|
||||
@@ -561,14 +573,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
Some(binding) => Ok((*binding, Flags::empty())),
|
||||
None => Err(Determinacy::Determined),
|
||||
},
|
||||
Scope::ExternPrelude => {
|
||||
match this.reborrow().extern_prelude_get(ident, finalize.is_some()) {
|
||||
Scope::ExternPreludeItems => {
|
||||
// FIXME: use `finalize_scope` here.
|
||||
match this.reborrow().extern_prelude_get_item(ident, finalize.is_some()) {
|
||||
Some(binding) => Ok((binding, Flags::empty())),
|
||||
None => Err(Determinacy::determined(
|
||||
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) {
|
||||
Some(binding) => Ok((*binding, Flags::empty())),
|
||||
None => Err(Determinacy::Determined),
|
||||
@@ -599,8 +618,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
if matches!(ident.name, sym::f16)
|
||||
&& !this.tcx.features().f16()
|
||||
&& !ident.span.allows_unstable(sym::f16)
|
||||
&& finalize.is_some()
|
||||
&& innermost_result.is_none()
|
||||
&& finalize_scope!().is_some()
|
||||
{
|
||||
feature_err(
|
||||
this.tcx.sess,
|
||||
@@ -613,8 +631,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
if matches!(ident.name, sym::f128)
|
||||
&& !this.tcx.features().f128()
|
||||
&& !ident.span.allows_unstable(sym::f128)
|
||||
&& finalize.is_some()
|
||||
&& innermost_result.is_none()
|
||||
&& finalize_scope!().is_some()
|
||||
{
|
||||
feature_err(
|
||||
this.tcx.sess,
|
||||
@@ -829,15 +846,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
assert_eq!(shadowing, Shadowing::Unrestricted);
|
||||
return if ns != TypeNS {
|
||||
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 {
|
||||
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 => {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#![feature(arbitrary_self_types)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(rustc_attrs)]
|
||||
@@ -113,34 +114,46 @@ impl Determinacy {
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
enum Scope<'ra> {
|
||||
/// Inert attributes registered by derive macros.
|
||||
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,
|
||||
/// Textual `let`-like scopes introduced by `macro_rules!` items.
|
||||
MacroRules(MacroRulesScopeRef<'ra>),
|
||||
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
|
||||
// lint if it should be reported.
|
||||
/// Names declared in the given module.
|
||||
/// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
|
||||
/// lint if it should be reported.
|
||||
Module(Module<'ra>, Option<NodeId>),
|
||||
/// Names introduced by `#[macro_use]` attributes on `extern crate` items.
|
||||
MacroUsePrelude,
|
||||
/// Built-in attributes.
|
||||
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,
|
||||
/// Standard library prelude introduced with an internal `#[prelude_import]` import.
|
||||
StdLibPrelude,
|
||||
/// Built-in types.
|
||||
BuiltinTypes,
|
||||
}
|
||||
|
||||
/// Names from different contexts may want to visit different subsets of all specific scopes
|
||||
/// 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)]
|
||||
enum ScopeSet<'ra> {
|
||||
/// All scopes with the given namespace.
|
||||
All(Namespace),
|
||||
/// A module, then extern prelude (used for mixed 2015-2018 mode in macros).
|
||||
ModuleAndExternPrelude(Namespace, Module<'ra>),
|
||||
/// Just two extern prelude scopes.
|
||||
ExternPrelude,
|
||||
/// All scopes with macro namespace and the given macro kind restriction.
|
||||
Macro(MacroKind),
|
||||
/// All scopes with the given namespace, used for partially performing late resolution.
|
||||
@@ -1012,16 +1025,18 @@ impl<'ra> NameBindingData<'ra> {
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
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,
|
||||
}
|
||||
|
||||
impl ExternPreludeEntry<'_> {
|
||||
fn is_import(&self) -> bool {
|
||||
self.binding.get().is_some_and(|binding| binding.is_import())
|
||||
}
|
||||
}
|
||||
|
||||
struct DeriveData {
|
||||
resolutions: Vec<DeriveResolution>,
|
||||
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);
|
||||
}
|
||||
}
|
||||
Scope::ExternPrelude | Scope::ToolPrelude | Scope::BuiltinTypes => {}
|
||||
Scope::ExternPreludeItems
|
||||
| Scope::ExternPreludeFlags
|
||||
| Scope::ToolPrelude
|
||||
| Scope::BuiltinTypes => {}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
None::<()>
|
||||
@@ -2054,7 +2072,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
// but not introduce it, as used if they are accessed from lexical scope.
|
||||
if used == Used::Scope {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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>,
|
||||
ident: Ident,
|
||||
finalize: bool,
|
||||
) -> Option<NameBinding<'ra>> {
|
||||
let mut record_use = None;
|
||||
let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident));
|
||||
let binding = entry.and_then(|entry| match entry.binding.get() {
|
||||
Some(binding) if binding.is_import() => {
|
||||
entry.and_then(|entry| entry.item_binding).map(|binding| {
|
||||
if finalize {
|
||||
record_use = Some(binding);
|
||||
self.get_mut().record_use(ident, binding, Used::Scope);
|
||||
}
|
||||
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) => {
|
||||
if finalize {
|
||||
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
|
||||
}
|
||||
Some(binding)
|
||||
}
|
||||
None if entry.only_item => None,
|
||||
None => {
|
||||
let crate_id = if finalize {
|
||||
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 binding =
|
||||
self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT);
|
||||
entry.binding.set(Some(binding));
|
||||
entry.flag_binding.set(Some(binding));
|
||||
Some(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>`
|
||||
|
||||
@@ -10,6 +10,7 @@ macro_rules! m {
|
||||
|
||||
m!();
|
||||
|
||||
use std::mem;
|
||||
use std::mem; //~ ERROR `std` is ambiguous
|
||||
use ::std::mem as _; //~ ERROR `std` is ambiguous
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -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)
|
||||
|
||||
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`.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//@ edition: 2018
|
||||
|
||||
macro_rules! define_other_core {
|
||||
( ) => {
|
||||
extern crate std as core;
|
||||
@@ -6,7 +8,8 @@ macro_rules! define_other_core {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
core::panic!();
|
||||
core::panic!(); //~ ERROR `core` is ambiguous
|
||||
::core::panic!(); //~ ERROR `core` is ambiguous
|
||||
}
|
||||
|
||||
define_other_core!();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -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)
|
||||
|
||||
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`.
|
||||
|
||||
10
tests/ui/resolve/extern-prelude-speculative.rs
Normal file
10
tests/ui/resolve/extern-prelude-speculative.rs
Normal 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!();
|
||||
}
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
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() {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
error[E0578]: cannot determine resolution for the visibility
|
||||
--> $DIR/visibility-indeterminate.rs:5:8
|
||||
error[E0433]: failed to resolve: could not find `bar` in the list of imported crates
|
||||
--> $DIR/visibility-indeterminate.rs:5:10
|
||||
|
|
||||
LL | pub(in ::bar) struct Baz {}
|
||||
| ^^^^^
|
||||
| ^^^ could not find `bar` in the list of imported crates
|
||||
|
||||
error: cannot find macro `foo` in this scope
|
||||
--> $DIR/visibility-indeterminate.rs:3:1
|
||||
@@ -12,4 +12,4 @@ LL | foo!();
|
||||
|
||||
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`.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//@ compile-flags:--extern foo --extern 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`
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -4,12 +4,6 @@ error[E0463]: can't find crate for `bar`
|
||||
LL | use bar::foo;
|
||||
| ^^^ 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`
|
||||
--> $DIR/deadlock.rs:4:5
|
||||
|
|
||||
@@ -18,7 +12,7 @@ LL | use bar::foo;
|
||||
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.
|
||||
For more information about an error, try `rustc --explain E0432`.
|
||||
|
||||
Reference in New Issue
Block a user