about summary refs log tree commit diff
diff options
context:
space:
mode:
authormibac138 <5672750+mibac138@users.noreply.github.com>2020-05-03 18:56:52 +0200
committermibac138 <5672750+mibac138@users.noreply.github.com>2020-05-19 20:40:47 +0200
commitd190e10f74afbe7edb5755bb0e0825450ea6c3bb (patch)
tree9b385884079dd5da02dcace11b49662c32690744
parent84a44218ad9dd0e278d934a72975dbad4f88c235 (diff)
downloadrust-d190e10f74afbe7edb5755bb0e0825450ea6c3bb.tar.gz
rust-d190e10f74afbe7edb5755bb0e0825450ea6c3bb.zip
Add error recovery for `use foo::self`
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs10
-rw-r--r--src/test/ui/issues/issue-45829/import-self.rs2
-rw-r--r--src/test/ui/issues/issue-45829/import-self.stderr17
-rw-r--r--src/test/ui/use/use-mod/use-mod-4.stderr2
-rw-r--r--src/test/ui/use/use-mod/use-mod-5.rs13
-rw-r--r--src/test/ui/use/use-mod/use-mod-5.stderr18
-rw-r--r--src/test/ui/use/use-mod/use-mod-6.rs13
-rw-r--r--src/test/ui/use/use-mod/use-mod-6.stderr18
8 files changed, 89 insertions, 4 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 35bba2e8b08..988ec3d4374 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -426,7 +426,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                             return;
                         }
 
-                        // Replace `use foo::self;` with `use foo;`
+                        // Replace `use foo::{ self };` with `use foo;`
                         source = module_path.pop().unwrap();
                         if rename.is_none() {
                             ident = source.ident;
@@ -454,6 +454,14 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                                 span_with_rename,
                             },
                         );
+
+                        // Error recovery: replace `use foo::self;` with `use foo;`
+                        if let Some(parent) = module_path.pop() {
+                            source = parent;
+                            if rename.is_none() {
+                                ident = source.ident;
+                            }
+                        }
                     }
 
                     // Disallow `use $crate;`
diff --git a/src/test/ui/issues/issue-45829/import-self.rs b/src/test/ui/issues/issue-45829/import-self.rs
index 6cb18e1cdb7..2dc4331ced7 100644
--- a/src/test/ui/issues/issue-45829/import-self.rs
+++ b/src/test/ui/issues/issue-45829/import-self.rs
@@ -9,7 +9,7 @@ use foo::{self};
 use foo as self;
 //~^ ERROR expected identifier
 
-use foo::self;
+use foo::self; //~ ERROR is defined multiple times
 //~^ ERROR `self` imports are only allowed within a { } list
 
 use foo::A;
diff --git a/src/test/ui/issues/issue-45829/import-self.stderr b/src/test/ui/issues/issue-45829/import-self.stderr
index 9d9a785387f..2ae2713b004 100644
--- a/src/test/ui/issues/issue-45829/import-self.stderr
+++ b/src/test/ui/issues/issue-45829/import-self.stderr
@@ -34,6 +34,21 @@ help: you can use `as` to change the binding name of the import
 LL | use foo::{self as other_foo};
    |           ^^^^^^^^^^^^^^^^^
 
+error[E0255]: the name `foo` is defined multiple times
+  --> $DIR/import-self.rs:12:5
+   |
+LL | mod foo {
+   | ------- previous definition of the module `foo` here
+...
+LL | use foo::self;
+   |     ^^^^^^^^^ `foo` reimported here
+   |
+   = note: `foo` must be defined only once in the type namespace of this module
+help: you can use `as` to change the binding name of the import
+   |
+LL | use foo as other_foo;
+   |     ^^^^^^^^^^^^^^^^
+
 error[E0252]: the name `A` is defined multiple times
   --> $DIR/import-self.rs:16:11
    |
@@ -48,7 +63,7 @@ help: you can use `as` to change the binding name of the import
 LL | use foo::{self as OtherA};
    |           ^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0252, E0255, E0429.
 For more information about an error, try `rustc --explain E0252`.
diff --git a/src/test/ui/use/use-mod/use-mod-4.stderr b/src/test/ui/use/use-mod/use-mod-4.stderr
index 9d853296798..e01c2cbf732 100644
--- a/src/test/ui/use/use-mod/use-mod-4.stderr
+++ b/src/test/ui/use/use-mod/use-mod-4.stderr
@@ -32,7 +32,7 @@ error[E0432]: unresolved import `foo`
   --> $DIR/use-mod-4.rs:1:5
    |
 LL | use foo::self;
-   |     ^^^ maybe a missing crate `foo`?
+   |     ^^^^^^^^^ no `foo` in the root
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/use/use-mod/use-mod-5.rs b/src/test/ui/use/use-mod/use-mod-5.rs
new file mode 100644
index 00000000000..df5b423ec57
--- /dev/null
+++ b/src/test/ui/use/use-mod/use-mod-5.rs
@@ -0,0 +1,13 @@
+mod foo {
+    pub mod bar {
+        pub fn drop() {}
+    }
+}
+
+use foo::bar::self;
+//~^ ERROR `self` imports are only allowed within a { } list
+
+fn main() {
+    // Because of error recovery this shouldn't error
+    bar::drop();
+}
diff --git a/src/test/ui/use/use-mod/use-mod-5.stderr b/src/test/ui/use/use-mod/use-mod-5.stderr
new file mode 100644
index 00000000000..859547fbc4d
--- /dev/null
+++ b/src/test/ui/use/use-mod/use-mod-5.stderr
@@ -0,0 +1,18 @@
+error[E0429]: `self` imports are only allowed within a { } list
+  --> $DIR/use-mod-5.rs:7:13
+   |
+LL | use foo::bar::self;
+   |             ^^^^^^
+   |
+help: Remove `::self`..
+   |
+LL | use foo::bar;
+   |            --
+help: ..or add braces around `self`
+   |
+LL | use foo::bar::{self};
+   |               ^    ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0429`.
diff --git a/src/test/ui/use/use-mod/use-mod-6.rs b/src/test/ui/use/use-mod/use-mod-6.rs
new file mode 100644
index 00000000000..1f8777daca4
--- /dev/null
+++ b/src/test/ui/use/use-mod/use-mod-6.rs
@@ -0,0 +1,13 @@
+mod foo {
+    pub mod bar {
+        pub fn drop() {}
+    }
+}
+
+use foo::bar::self as abc;
+//~^ ERROR `self` imports are only allowed within a { } list
+
+fn main() {
+    // Because of error recovery this shouldn't error
+    abc::drop();
+}
diff --git a/src/test/ui/use/use-mod/use-mod-6.stderr b/src/test/ui/use/use-mod/use-mod-6.stderr
new file mode 100644
index 00000000000..0042325229a
--- /dev/null
+++ b/src/test/ui/use/use-mod/use-mod-6.stderr
@@ -0,0 +1,18 @@
+error[E0429]: `self` imports are only allowed within a { } list
+  --> $DIR/use-mod-6.rs:7:13
+   |
+LL | use foo::bar::self as abc;
+   |             ^^^^^^
+   |
+help: Remove `::self`..
+   |
+LL | use foo::bar as abc;
+   |            --
+help: ..or add braces around `self`
+   |
+LL | use foo::bar::{self as abc};
+   |               ^           ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0429`.