about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-03-13 14:59:05 +0000
committerbors <bors@rust-lang.org>2019-03-13 14:59:05 +0000
commit8bf1f1c8f4100247c1f9b3d9b7aecea5c970263e (patch)
treeff2b2fc46ded701458c0ab7b1c124bffd6f52bb9
parentcf6d881ac1f348e8cf16d8b9177d7dff39fd2570 (diff)
parent1d6f4d66ad9004d406169742c3098748a0419384 (diff)
downloadrust-8bf1f1c8f4100247c1f9b3d9b7aecea5c970263e.tar.gz
rust-8bf1f1c8f4100247c1f9b3d9b7aecea5c970263e.zip
Auto merge of #58349 - petrochenkov:uni201x, r=pnkfelix
resolve: Simplify import resolution for mixed 2015/2018 edition mode

Non-controversial part of https://github.com/rust-lang/rust/pull/57745.

Before:

| Local edition (per-span) | Global edition (--edition) | Imports (`use foo;`)                                 | Absolute paths (`::foo`)                                 |
| ------------- |----------------|-----------------------------------------|------------------------------------------------|
| 2018          | Any            | Uniform                                 | Extern prelude                                 |
| 2015          | 2015           | Crate-relative                          | Crate-relative                                 |
| 2015          | 2018           | Crate-relative with fallback to Uniform (future-proofed to error if the result is not Crate-relative or from Extern prelude) | Crate-relative with fallback to Extern prelude |

After:

| Local edition (per-span) | Global edition (--edition) | Imports (`use foo;`)                                 | Absolute paths (`::foo`)                                 |
| ------------- |----------------|-----------------------------------------|------------------------------------------------|
| 2018          | Any            | Uniform                                 | Extern prelude                                 |
| 2015          | 2015           | Crate-relative                          | Crate-relative                                 |
| 2015          | 2018           | Crate-relative with fallback to Extern prelude | Crate-relative with fallback to Extern prelude |

I.e. only the behavior of the mixed local-2015-global-2018 mode is changed.
This mixed mode has two goals:
- Address regressions from https://github.com/rust-lang/rust/pull/56053#issuecomment-440826397.
Both "before" and "after" variants address those regressions.
- Be retrofit-able to "full 2015" edition (https://github.com/rust-lang/rust/pull/57745).
Any more complex fallback scheme (with more candidates) than "Crate-relative with fallback to Extern prelude" will give more regressions than https://github.com/rust-lang/rust/pull/57745#issuecomment-455855089 and is therefore less retrofit-able while also being, well, more complex.
So, we can settle on "Crate-relative with fallback to Extern prelude".

(I'll hopefully proceed with https://github.com/rust-lang/rust/pull/57745 after mid-February.)

r? @Centril
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs5
-rw-r--r--src/librustc_resolve/lib.rs3
-rw-r--r--src/librustc_resolve/macros.rs50
-rw-r--r--src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs4
-rw-r--r--src/test/ui/editions/edition-imports-virtual-2015-ambiguity.stderr40
-rw-r--r--src/test/ui/editions/edition-imports-virtual-2015-gated.rs3
-rw-r--r--src/test/ui/editions/edition-imports-virtual-2015-gated.stderr17
7 files changed, 11 insertions, 111 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 29de5308a3c..5c9927011a7 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -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() => {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index b50e37519d4..ac149be4b2a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -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 =>
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 8e4b2a9a4cb..21ca8ea369f 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -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);
         }
 
diff --git a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs
index 53ec3867f01..940b0c3c63d 100644
--- a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs
+++ b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs
@@ -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
     }
 }
 
diff --git a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.stderr b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.stderr
deleted file mode 100644
index 1f309f5e8f0..00000000000
--- a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/ui/editions/edition-imports-virtual-2015-gated.rs b/src/test/ui/editions/edition-imports-virtual-2015-gated.rs
index a1bf4f5eb51..634d3e9a443 100644
--- a/src/test/ui/editions/edition-imports-virtual-2015-gated.rs
+++ b/src/test/ui/editions/edition-imports-virtual-2015-gated.rs
@@ -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() {}
diff --git a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr
index 7c78fbb26a1..e6d0f18a677 100644
--- a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr
+++ b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr
@@ -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`.