enum ScopeSet {
Import(Namespace),
+ AbsolutePath(Namespace),
Macro(MacroKind),
Module,
}
/// Regular module.
Module(Module<'a>),
+ /// Virtual module that denotes resolution in crate root with fallback to extern prelude.
+ CrateRootAndExternPrelude,
+
/// Virtual module that denotes resolution in extern prelude.
/// Used for paths starting with `::` on 2018 edition or `extern::`.
ExternPrelude,
impl<'a> PartialEq for ModuleOrUniformRoot<'a> {
fn eq(&self, other: &Self) -> bool {
match (*self, *other) {
- (ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) =>
- ptr::eq(lhs, rhs),
- (ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) => true,
+ (ModuleOrUniformRoot::Module(lhs),
+ ModuleOrUniformRoot::Module(rhs)) => ptr::eq(lhs, rhs),
+ (ModuleOrUniformRoot::CrateRootAndExternPrelude,
+ ModuleOrUniformRoot::CrateRootAndExternPrelude) |
+ (ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) |
(ModuleOrUniformRoot::CurrentScope, ModuleOrUniformRoot::CurrentScope) => true,
_ => false,
}
#[derive(Clone, Copy, PartialEq, Debug)]
enum AmbiguityKind {
Import,
+ AbsolutePath,
BuiltinAttr,
DeriveHelper,
LegacyHelperVsPrelude,
match self {
AmbiguityKind::Import =>
"name vs any other name during import resolution",
+ AmbiguityKind::AbsolutePath =>
+ "name in the crate root vs extern crate during absolute path resolution",
AmbiguityKind::BuiltinAttr =>
"built-in attribute vs any other name",
AmbiguityKind::DeriveHelper =>
ident.span = ident.span.modern();
ident.span.adjust(Mark::root());
}
+ ModuleOrUniformRoot::CrateRootAndExternPrelude |
ModuleOrUniformRoot::CurrentScope => {
// No adjustments
}
module = Some(ModuleOrUniformRoot::ExternPrelude);
continue;
}
+ if name == keywords::CrateRoot.name() &&
+ ident.span.rust_2015() && self.session.rust_2018() {
+ // `::a::b` from 2015 macro on 2018 global edition
+ module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
+ continue;
+ }
if name == keywords::CrateRoot.name() ||
name == keywords::Crate.name() ||
name == keywords::DollarCrate.name() {
// Go through all the scopes and try to resolve the name.
let rust_2015 = orig_ident.span.rust_2015();
- let (ns, macro_kind, is_import) = match scope_set {
- ScopeSet::Import(ns) => (ns, None, true),
- ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
- ScopeSet::Module => (TypeNS, None, false),
+ let (ns, macro_kind, is_import, is_absolute_path) = match scope_set {
+ ScopeSet::Import(ns) => (ns, None, true, false),
+ ScopeSet::AbsolutePath(ns) => (ns, None, false, true),
+ ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false, false),
+ ScopeSet::Module => (TypeNS, None, false, false),
};
let mut where_to_resolve = match ns {
- _ if is_import && rust_2015 => WhereToResolve::CrateRoot,
+ _ if is_absolute_path || is_import && rust_2015 => WhereToResolve::CrateRoot,
TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module),
MacroNS => WhereToResolve::DeriveHelpers,
};
}
}
WhereToResolve::ExternPrelude => {
- if use_prelude {
+ if use_prelude || is_absolute_path {
match self.extern_prelude_get(ident, !record_used) {
Some(binding) => Ok((binding, Flags::PRELUDE)),
None => Err(Determinacy::determined(
let ambiguity_error_kind = if is_import {
Some(AmbiguityKind::Import)
+ } else if is_absolute_path {
+ Some(AmbiguityKind::AbsolutePath)
} else if innermost_def == builtin || def == builtin {
Some(AmbiguityKind::BuiltinAttr)
} else if innermost_def == derive_helper || def == derive_helper {
LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
LegacyScope::Uninitialized => unreachable!(),
}
- WhereToResolve::CrateRoot => match ns {
+ WhereToResolve::CrateRoot if is_import => match ns {
TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module),
MacroNS => WhereToResolve::DeriveHelpers,
}
+ WhereToResolve::CrateRoot if is_absolute_path => match ns {
+ TypeNS => {
+ ident.span.adjust(Mark::root());
+ WhereToResolve::ExternPrelude
+ }
+ ValueNS | MacroNS => break,
+ }
+ WhereToResolve::CrateRoot => unreachable!(),
WhereToResolve::Module(module) => {
match self.hygienic_lexical_parent(module, &mut ident.span) {
Some(parent_module) => WhereToResolve::Module(parent_module),
WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers,
WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search
+ WhereToResolve::ExternPrelude if is_absolute_path => break,
WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
WhereToResolve::StdLibPrelude => match ns {
) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> {
let module = match module {
ModuleOrUniformRoot::Module(module) => module,
+ ModuleOrUniformRoot::CrateRootAndExternPrelude => {
+ assert!(!restricted_shadowing);
+ let parent_scope = self.dummy_parent_scope();
+ let binding = self.early_resolve_ident_in_lexical_scope(
+ ident, ScopeSet::AbsolutePath(ns), &parent_scope,
+ record_used, record_used, path_span,
+ );
+ return binding.map_err(|determinacy| (determinacy, Weak::No));
+ }
ModuleOrUniformRoot::ExternPrelude => {
assert!(!restricted_shadowing);
return if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
fn check_absolute() {
::absolute::Path;
- // ::std::collections::LinkedList::<u8>::new(); // FIXME
+ ::std::collections::LinkedList::<u8>::new();
}
}}
#[macro_export]
macro_rules! gen_ambiguous { () => {
use Ambiguous;
+ type A = ::edition_imports_2015::Path;
}}
-// compile-pass
// edition:2018
// aux-build:edition-imports-2015.rs
}
mod check_glob {
- gen_glob!(); // OK
-
- fn check() {
- import::Path;
- absolute::Path;
- }
+ gen_glob!(); //~ ERROR cannot glob-import all possible crates
}
fn main() {}
--- /dev/null
+error: cannot glob-import all possible crates
+ --> $DIR/edition-imports-2018.rs:24:5
+ |
+LL | gen_glob!(); //~ ERROR cannot glob-import all possible crates
+ | ^^^^^^^^^^^^
+ |
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
// edition:2018
+// compile-flags:--extern edition_imports_2015
// aux-build:edition-imports-2015.rs
// error-pattern: `Ambiguous` is ambiguous
+// error-pattern: `edition_imports_2015` is ambiguous
-#[macro_use]
-extern crate edition_imports_2015;
+mod edition_imports_2015 {
+ pub struct Path;
+}
pub struct Ambiguous {}
pub struct Ambiguous {}
fn check() {
- gen_ambiguous!();
+ edition_imports_2015::gen_ambiguous!();
}
}
error[E0659]: `Ambiguous` is ambiguous (name vs any other name during import resolution)
--> <::edition_imports_2015::gen_ambiguous macros>:1:15
|
-LL | ( ) => { use Ambiguous ; }
+LL | ( ) => { use Ambiguous ; type A = :: edition_imports_2015 :: Path ; }
| ^^^^^^^^^ ambiguous name
|
note: `Ambiguous` could refer to the struct defined here
- --> $DIR/edition-imports-virtual-2015-ambiguity.rs:8:1
+ --> $DIR/edition-imports-virtual-2015-ambiguity.rs:11:1
|
LL | pub struct Ambiguous {}
| ^^^^^^^^^^^^^^^^^^^^^^^
note: `Ambiguous` could also refer to the struct defined here
- --> $DIR/edition-imports-virtual-2015-ambiguity.rs:11:5
+ --> $DIR/edition-imports-virtual-2015-ambiguity.rs:14:5
|
LL | pub struct Ambiguous {}
| ^^^^^^^^^^^^^^^^^^^^^^^
= help: use `self::Ambiguous` to refer to this struct unambiguously
-error: aborting due to previous error
+error[E0659]: `edition_imports_2015` is ambiguous (name in the crate root vs extern crate during absolute path resolution)
+ --> <::edition_imports_2015::gen_ambiguous macros>:1:39
+ |
+LL | ( ) => { use Ambiguous ; type A = :: edition_imports_2015 :: Path ; }
+ | ^^^^^^^^^^^^^^^^^^^^ ambiguous name
+ |
+ = note: `edition_imports_2015` could refer to an extern crate passed with `--extern`
+ = help: use `::edition_imports_2015` to refer to this extern crate unambiguously
+note: `edition_imports_2015` could also refer to the module defined here
+ --> $DIR/edition-imports-virtual-2015-ambiguity.rs:7:1
+ |
+LL | / mod edition_imports_2015 {
+LL | | pub struct Path;
+LL | | }
+ | |_^
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0659`.