mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-09 14:25:24 +00:00
resolve: Simplify import resolution for mixed 2015/2018 edition mode
This commit is contained in:
parent
8f4c226fc5
commit
1d6f4d66ad
@ -131,12 +131,9 @@ impl<'a> Resolver<'a> {
|
||||
// so prefixes are prepended with crate root segment if necessary.
|
||||
// The root is prepended lazily, when the first non-empty prefix or terminating glob
|
||||
// appears, so imports in braced groups can have roots prepended independently.
|
||||
// 2015 identifiers used on global 2018 edition enter special "virtual 2015 mode", don't
|
||||
// get crate root prepended, but get special treatment during in-scope resolution instead.
|
||||
let is_glob = if let ast::UseTreeKind::Glob = use_tree.kind { true } else { false };
|
||||
let crate_root = match prefix_iter.peek() {
|
||||
Some(seg) if !seg.ident.is_path_segment_keyword() &&
|
||||
seg.ident.span.rust_2015() && self.session.rust_2015() => {
|
||||
Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.rust_2015() => {
|
||||
Some(seg.ident.span.ctxt())
|
||||
}
|
||||
None if is_glob && use_tree.span.rust_2015() => {
|
||||
|
@ -1273,7 +1273,6 @@ struct UseError<'a> {
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
enum AmbiguityKind {
|
||||
Import,
|
||||
AbsolutePath,
|
||||
BuiltinAttr,
|
||||
DeriveHelper,
|
||||
LegacyHelperVsPrelude,
|
||||
@ -1289,8 +1288,6 @@ 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 =>
|
||||
|
@ -572,7 +572,7 @@ impl<'a> Resolver<'a> {
|
||||
ScopeSet::Module => (TypeNS, None, false, false),
|
||||
};
|
||||
let mut where_to_resolve = match ns {
|
||||
_ if is_absolute_path || is_import && rust_2015 => WhereToResolve::CrateRoot,
|
||||
_ if is_absolute_path => WhereToResolve::CrateRoot,
|
||||
TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module),
|
||||
MacroNS => WhereToResolve::DeriveHelpers,
|
||||
};
|
||||
@ -770,8 +770,6 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
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 {
|
||||
@ -841,18 +839,13 @@ impl<'a> Resolver<'a> {
|
||||
LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
|
||||
LegacyScope::Uninitialized => unreachable!(),
|
||||
}
|
||||
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 {
|
||||
WhereToResolve::CrateRoot => 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),
|
||||
@ -885,44 +878,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
// The first found solution was the only one, return it.
|
||||
if let Some((binding, flags)) = innermost_result {
|
||||
// We get to here only if there's no ambiguity, in ambiguous cases an error will
|
||||
// be reported anyway, so there's no reason to report an additional feature error.
|
||||
// The `binding` can actually be introduced by something other than `--extern`,
|
||||
// but its `Def` should coincide with a crate passed with `--extern`
|
||||
// (otherwise there would be ambiguity) and we can skip feature error in this case.
|
||||
'ok: {
|
||||
if !is_import || !rust_2015 {
|
||||
break 'ok;
|
||||
}
|
||||
if ns == TypeNS && use_prelude && self.extern_prelude_get(ident, true).is_some() {
|
||||
break 'ok;
|
||||
}
|
||||
let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span);
|
||||
let root_module = self.resolve_crate_root(root_ident);
|
||||
if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
|
||||
orig_ident, ns, None, false, path_span)
|
||||
.is_ok() {
|
||||
break 'ok;
|
||||
}
|
||||
|
||||
let msg = "imports can only refer to extern crate names passed with \
|
||||
`--extern` in macros originating from 2015 edition";
|
||||
let mut err = self.session.struct_span_err(ident.span, msg);
|
||||
let what = self.binding_description(binding, ident,
|
||||
flags.contains(Flags::MISC_FROM_PRELUDE));
|
||||
let note_msg = format!("this import refers to {what}", what = what);
|
||||
let label_span = if binding.span.is_dummy() {
|
||||
err.note(¬e_msg);
|
||||
ident.span
|
||||
} else {
|
||||
err.span_note(binding.span, ¬e_msg);
|
||||
binding.span
|
||||
};
|
||||
err.span_label(label_span, "not an extern crate passed with `--extern`");
|
||||
err.emit();
|
||||
}
|
||||
|
||||
if let Some((binding, _)) = innermost_result {
|
||||
return Ok(binding);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
// compile-pass
|
||||
// edition:2018
|
||||
// compile-flags:--extern edition_imports_2015
|
||||
// aux-build:edition-imports-2015.rs
|
||||
@ -12,8 +13,7 @@ mod check {
|
||||
pub struct Ambiguous {}
|
||||
|
||||
fn check() {
|
||||
edition_imports_2015::gen_ambiguous!(); //~ ERROR `Ambiguous` is ambiguous
|
||||
//~| ERROR `edition_imports_2015` is ambiguous
|
||||
edition_imports_2015::gen_ambiguous!(); // OK
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
error[E0659]: `Ambiguous` is ambiguous (name vs any other name during import resolution)
|
||||
--> $DIR/edition-imports-virtual-2015-ambiguity.rs:15:9
|
||||
|
|
||||
LL | edition_imports_2015::gen_ambiguous!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name
|
||||
|
|
||||
note: `Ambiguous` could refer to the struct defined here
|
||||
--> $DIR/edition-imports-virtual-2015-ambiguity.rs:9:1
|
||||
|
|
||||
LL | pub struct Ambiguous {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: use `crate::Ambiguous` to refer to this struct unambiguously
|
||||
note: `Ambiguous` could also refer to the struct defined here
|
||||
--> $DIR/edition-imports-virtual-2015-ambiguity.rs:12:5
|
||||
|
|
||||
LL | pub struct Ambiguous {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: use `self::Ambiguous` to refer to this struct unambiguously
|
||||
= 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[E0659]: `edition_imports_2015` is ambiguous (name in the crate root vs extern crate during absolute path resolution)
|
||||
--> $DIR/edition-imports-virtual-2015-ambiguity.rs:15:9
|
||||
|
|
||||
LL | edition_imports_2015::gen_ambiguous!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name
|
||||
|
|
||||
= note: `edition_imports_2015` could refer to an extern crate passed with `--extern`
|
||||
note: `edition_imports_2015` could also refer to the module defined here
|
||||
--> $DIR/edition-imports-virtual-2015-ambiguity.rs:5:1
|
||||
|
|
||||
LL | / mod edition_imports_2015 {
|
||||
LL | | pub struct Path;
|
||||
LL | | }
|
||||
| |_^
|
||||
= help: use `crate::edition_imports_2015` to refer to this module unambiguously
|
||||
= 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 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0659`.
|
@ -1,12 +1,11 @@
|
||||
// edition:2018
|
||||
// aux-build:edition-imports-2015.rs
|
||||
// error-pattern: imports can only refer to extern crate names passed with `--extern`
|
||||
|
||||
#[macro_use]
|
||||
extern crate edition_imports_2015;
|
||||
|
||||
mod check {
|
||||
gen_gated!();
|
||||
gen_gated!(); //~ ERROR unresolved import `E`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,20 +1,11 @@
|
||||
error: imports can only refer to extern crate names passed with `--extern` in macros originating from 2015 edition
|
||||
--> <::edition_imports_2015::gen_gated macros>:1:50
|
||||
|
|
||||
LL | ( ) => { fn check_gated ( ) { enum E { A } use E :: * ; } }
|
||||
| ^
|
||||
|
|
||||
::: $DIR/edition-imports-virtual-2015-gated.rs:9:5
|
||||
error[E0432]: unresolved import `E`
|
||||
--> $DIR/edition-imports-virtual-2015-gated.rs:8:5
|
||||
|
|
||||
LL | gen_gated!();
|
||||
| ------------- not an extern crate passed with `--extern`
|
||||
| ^^^^^^^^^^^^^ could not find `E` in `{{root}}`
|
||||
|
|
||||
note: this import refers to the enum defined here
|
||||
--> $DIR/edition-imports-virtual-2015-gated.rs:9:5
|
||||
|
|
||||
LL | gen_gated!();
|
||||
| ^^^^^^^^^^^^^
|
||||
= 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
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
||||
|
Loading…
Reference in New Issue
Block a user