Skip to content
Permalink
Browse files

resolve: Simplify import resolution for mixed 2015/2018 edition mode

  • Loading branch information...
petrochenkov committed Jan 16, 2019
1 parent 8f4c226 commit 1d6f4d66ad9004d406169742c3098748a0419384
@@ -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(&note_msg);
ident.span
} else {
err.span_note(binding.span, &note_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
}
}

This file was deleted.

Oops, something went wrong.
@@ -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`
|
note: this import refers to the enum defined here
--> $DIR/edition-imports-virtual-2015-gated.rs:9:5
| ^^^^^^^^^^^^^ could not find `E` in `{{root}}`
|
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`.

0 comments on commit 1d6f4d6

Please sign in to comment.
You can’t perform that action at this time.