mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
resolve: Fallback to extern prelude in 2015 imports used from global 2018 edition
This commit is contained in:
parent
5e121756ef
commit
d1862b4196
@ -104,6 +104,7 @@ enum Weak {
|
||||
|
||||
enum ScopeSet {
|
||||
Import(Namespace),
|
||||
AbsolutePath(Namespace),
|
||||
Macro(MacroKind),
|
||||
Module,
|
||||
}
|
||||
@ -1008,6 +1009,9 @@ enum ModuleOrUniformRoot<'a> {
|
||||
/// 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,
|
||||
@ -1021,9 +1025,11 @@ enum ModuleOrUniformRoot<'a> {
|
||||
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,
|
||||
}
|
||||
@ -1243,6 +1249,7 @@ struct UseError<'a> {
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
enum AmbiguityKind {
|
||||
Import,
|
||||
AbsolutePath,
|
||||
BuiltinAttr,
|
||||
DeriveHelper,
|
||||
LegacyHelperVsPrelude,
|
||||
@ -1258,6 +1265,8 @@ impl AmbiguityKind {
|
||||
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 =>
|
||||
@ -2226,6 +2235,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
ident.span = ident.span.modern();
|
||||
ident.span.adjust(Mark::root());
|
||||
}
|
||||
ModuleOrUniformRoot::CrateRootAndExternPrelude |
|
||||
ModuleOrUniformRoot::CurrentScope => {
|
||||
// No adjustments
|
||||
}
|
||||
@ -3791,6 +3801,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
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() {
|
||||
|
@ -625,13 +625,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
|
||||
// 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,
|
||||
};
|
||||
@ -761,7 +762,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
}
|
||||
}
|
||||
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(
|
||||
@ -827,6 +828,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
|
||||
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 {
|
||||
@ -894,10 +897,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
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),
|
||||
@ -915,6 +926,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
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 {
|
||||
|
@ -162,6 +162,15 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
||||
) -> 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) {
|
||||
|
@ -7,7 +7,7 @@ macro_rules! gen_imports { () => {
|
||||
|
||||
fn check_absolute() {
|
||||
::absolute::Path;
|
||||
// ::std::collections::LinkedList::<u8>::new(); // FIXME
|
||||
::std::collections::LinkedList::<u8>::new();
|
||||
}
|
||||
}}
|
||||
|
||||
@ -27,4 +27,5 @@ macro_rules! gen_gated { () => {
|
||||
#[macro_export]
|
||||
macro_rules! gen_ambiguous { () => {
|
||||
use Ambiguous;
|
||||
type A = ::edition_imports_2015::Path;
|
||||
}}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// compile-pass
|
||||
// edition:2018
|
||||
// aux-build:edition-imports-2015.rs
|
||||
|
||||
@ -22,12 +21,7 @@ mod check {
|
||||
}
|
||||
|
||||
mod check_glob {
|
||||
gen_glob!(); // OK
|
||||
|
||||
fn check() {
|
||||
import::Path;
|
||||
absolute::Path;
|
||||
}
|
||||
gen_glob!(); //~ ERROR cannot glob-import all possible crates
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
10
src/test/ui/editions/edition-imports-2018.stderr
Normal file
10
src/test/ui/editions/edition-imports-2018.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
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
|
||||
|
@ -1,9 +1,12 @@
|
||||
// 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 {}
|
||||
|
||||
@ -11,7 +14,7 @@ mod check {
|
||||
pub struct Ambiguous {}
|
||||
|
||||
fn check() {
|
||||
gen_ambiguous!();
|
||||
edition_imports_2015::gen_ambiguous!();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,37 @@
|
||||
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`.
|
||||
|
Loading…
Reference in New Issue
Block a user