about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-12-30 03:12:16 +0000
committerbors <bors@rust-lang.org>2018-12-30 03:12:16 +0000
commit171c1fc25ed22e34fa4f666a15909b762ac1307b (patch)
treecf23bc98a34c990895fa9da8f67c807bf22597f6
parenta35cf79fcb961d43828aa9f010e7109b60633f52 (diff)
parentddb550a0e35921d2f4ecf023a7883b247f2ac407 (diff)
downloadrust-171c1fc25ed22e34fa4f666a15909b762ac1307b.tar.gz
rust-171c1fc25ed22e34fa4f666a15909b762ac1307b.zip
Auto merge of #57185 - petrochenkov:impice4, r=estebank
resolve: Fix one more ICE in import validation

So if you have an unresolved import
```rust
mod m {
    use foo::bar;
}
```
error recovery will insert a special item with `Def::Err` definition into module `m`, so other things depending on `bar` won't produce extra errors.

The issue was that erroneous `bar` was overwriting legitimate `bar`s coming from globs, e.g.
```rust
mod m {
    use baz::*; // imports real existing `bar`
    use foo::bar;
}
```
causing some unwanted diagnostics talking about "unresolved items", and producing inconsistent resolutions like https://github.com/rust-lang/rust/issues/57015.
This PR stops overwriting real successful resolutions with `Def::Err`s.

Fixes https://github.com/rust-lang/rust/issues/57015
-rw-r--r--src/librustc_resolve/resolve_imports.rs4
-rw-r--r--src/test/ui/imports/duplicate.rs2
-rw-r--r--src/test/ui/imports/duplicate.stderr21
-rw-r--r--src/test/ui/imports/issue-56125.stderr10
-rw-r--r--src/test/ui/imports/issue-57015.rs13
-rw-r--r--src/test/ui/imports/issue-57015.stderr9
6 files changed, 33 insertions, 26 deletions
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index ba4b18abdfc..ab440eda538 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -472,6 +472,10 @@ impl<'a> Resolver<'a> {
         self.set_binding_parent_module(binding, module);
         self.update_resolution(module, ident, ns, |this, resolution| {
             if let Some(old_binding) = resolution.binding {
+                if binding.def() == Def::Err {
+                    // Do not override real bindings with `Def::Err`s from error recovery.
+                    return Ok(());
+                }
                 match (old_binding.is_glob_import(), binding.is_glob_import()) {
                     (true, true) => {
                         if binding.def() != old_binding.def() {
diff --git a/src/test/ui/imports/duplicate.rs b/src/test/ui/imports/duplicate.rs
index 95bb69043e9..d62bbf765b7 100644
--- a/src/test/ui/imports/duplicate.rs
+++ b/src/test/ui/imports/duplicate.rs
@@ -33,7 +33,7 @@ mod g {
 fn main() {
     e::foo();
     f::foo(); //~ ERROR `foo` is ambiguous
-    g::foo(); //~ ERROR `foo` is ambiguous
+    g::foo();
 }
 
 mod ambiguous_module_errors {
diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr
index 3df2c5930e8..acd66826fdf 100644
--- a/src/test/ui/imports/duplicate.stderr
+++ b/src/test/ui/imports/duplicate.stderr
@@ -51,25 +51,6 @@ LL |     pub use b::*;
    = help: consider adding an explicit import of `foo` to disambiguate
 
 error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
-  --> $DIR/duplicate.rs:36:8
-   |
-LL |     g::foo(); //~ ERROR `foo` is ambiguous
-   |        ^^^ ambiguous name
-   |
-note: `foo` could refer to the function imported here
-  --> $DIR/duplicate.rs:29:13
-   |
-LL |     pub use a::*;
-   |             ^^^^
-   = help: consider adding an explicit import of `foo` to disambiguate
-note: `foo` could also refer to the unresolved item imported here
-  --> $DIR/duplicate.rs:30:13
-   |
-LL |     pub use f::*;
-   |             ^^^^
-   = help: consider adding an explicit import of `foo` to disambiguate
-
-error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
   --> $DIR/duplicate.rs:49:9
    |
 LL |         foo::bar(); //~ ERROR `foo` is ambiguous
@@ -88,7 +69,7 @@ LL |     use self::m2::*;
    |         ^^^^^^^^^^^
    = help: consider adding an explicit import of `foo` to disambiguate
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors occurred: E0252, E0659.
 For more information about an error, try `rustc --explain E0252`.
diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr
index 559979e5d51..210f6a43996 100644
--- a/src/test/ui/imports/issue-56125.stderr
+++ b/src/test/ui/imports/issue-56125.stderr
@@ -42,12 +42,12 @@ LL |     use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
    |
    = note: `issue_56125` could refer to an extern crate passed with `--extern`
    = help: use `::issue_56125` to refer to this extern crate unambiguously
-note: `issue_56125` could also refer to the unresolved item imported here
-  --> $DIR/issue-56125.rs:19:9
+note: `issue_56125` could also refer to the module imported here
+  --> $DIR/issue-56125.rs:20:9
    |
-LL |     use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
-   |         ^^^^^^^^^^^^^^^^^^
-   = help: use `self::issue_56125` to refer to this unresolved item unambiguously
+LL |     use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
+   |         ^^^^^^^^^^^^^^
+   = help: use `self::issue_56125` to refer to this module unambiguously
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/imports/issue-57015.rs b/src/test/ui/imports/issue-57015.rs
new file mode 100644
index 00000000000..27688fd34f6
--- /dev/null
+++ b/src/test/ui/imports/issue-57015.rs
@@ -0,0 +1,13 @@
+mod glob_ok {
+    pub mod something {
+        pub mod something_else {}
+    }
+}
+
+mod single_err {}
+
+use glob_ok::*; // glob_ok::something
+use single_err::something; //~ ERROR unresolved import `single_err::something`
+use something::something_else;
+
+fn main() {}
diff --git a/src/test/ui/imports/issue-57015.stderr b/src/test/ui/imports/issue-57015.stderr
new file mode 100644
index 00000000000..b0fcf5bec6a
--- /dev/null
+++ b/src/test/ui/imports/issue-57015.stderr
@@ -0,0 +1,9 @@
+error[E0432]: unresolved import `single_err::something`
+  --> $DIR/issue-57015.rs:10:5
+   |
+LL | use single_err::something; //~ ERROR unresolved import `single_err::something`
+   |     ^^^^^^^^^^^^^^^^^^^^^ no `something` in `single_err`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0432`.