about summary refs log tree commit diff
diff options
context:
space:
mode:
authormibac138 <5672750+mibac138@users.noreply.github.com>2020-05-03 18:54:21 +0200
committermibac138 <5672750+mibac138@users.noreply.github.com>2020-05-19 20:40:46 +0200
commit84a44218ad9dd0e278d934a72975dbad4f88c235 (patch)
tree18c8f9514874def9fd90d694886645acd80c67d3
parent672b272077561ca7b5027a8aff9ea2957c7d4c21 (diff)
downloadrust-84a44218ad9dd0e278d934a72975dbad4f88c235.tar.gz
rust-84a44218ad9dd0e278d934a72975dbad4f88c235.zip
Suggest fixes for `use foo::self`
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs19
-rw-r--r--src/librustc_resolve/diagnostics.rs41
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/test/ui/error-codes/E0429.stderr13
-rw-r--r--src/test/ui/issues/issue-45829/import-self.stderr13
-rw-r--r--src/test/ui/use/use-keyword.stderr2
-rw-r--r--src/test/ui/use/use-mod/use-mod-4.stderr26
7 files changed, 97 insertions, 19 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index d0eb1cfc222..35bba2e8b08 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -435,9 +435,24 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 } else {
                     // Disallow `self`
                     if source.ident.name == kw::SelfLower {
+                        let parent = module_path.last();
+
+                        let span = match parent {
+                            // only `::self` from `use foo::self as bar`
+                            Some(seg) => seg.ident.span.shrink_to_hi().to(source.ident.span),
+                            None => source.ident.span,
+                        };
+                        let span_with_rename = match rename {
+                            // only `self as bar` from `use foo::self as bar`
+                            Some(rename) => source.ident.span.to(rename.span),
+                            None => source.ident.span,
+                        };
                         self.r.report_error(
-                            use_tree.span,
-                            ResolutionError::SelfImportsOnlyAllowedWithin,
+                            span,
+                            ResolutionError::SelfImportsOnlyAllowedWithin {
+                                root: parent.is_none(),
+                                span_with_rename,
+                            },
                         );
                     }
 
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index c66e9a60406..e4f1d7a123d 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -301,13 +301,40 @@ impl<'a> Resolver<'a> {
                 }
                 err
             }
-            ResolutionError::SelfImportsOnlyAllowedWithin => struct_span_err!(
-                self.session,
-                span,
-                E0429,
-                "{}",
-                "`self` imports are only allowed within a { } list"
-            ),
+            ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => {
+                let mut err = struct_span_err!(
+                    self.session,
+                    span,
+                    E0429,
+                    "{}",
+                    "`self` imports are only allowed within a { } list"
+                );
+
+                // None of the suggestions below would help with a case like `use self`.
+                if !root {
+                    // use foo::bar::self        -> foo::bar
+                    // use foo::bar::self as abc -> foo::bar as abc
+                    err.span_suggestion(
+                        span,
+                        "Remove `::self`..",
+                        "".to_string(),
+                        Applicability::MachineApplicable,
+                    );
+
+                    // use foo::bar::self        -> foo::bar::{self}
+                    // use foo::bar::self as abc -> foo::bar::{self as abc}
+                    let braces = vec![
+                        (span_with_rename.shrink_to_lo(), "{".to_string()),
+                        (span_with_rename.shrink_to_hi(), "}".to_string()),
+                    ];
+                    err.multipart_suggestion(
+                        "..or add braces around `self`",
+                        braces,
+                        Applicability::MachineApplicable,
+                    );
+                }
+                err
+            }
             ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
                 let mut err = struct_span_err!(
                     self.session,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 2031b7868c0..bfb7f081fc3 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -194,7 +194,7 @@ enum ResolutionError<'a> {
     /// Error E0426: use of undeclared label.
     UndeclaredLabel(&'a str, Option<Symbol>),
     /// Error E0429: `self` imports are only allowed within a `{ }` list.
-    SelfImportsOnlyAllowedWithin,
+    SelfImportsOnlyAllowedWithin { root: bool, span_with_rename: Span },
     /// Error E0430: `self` import can only appear once in the list.
     SelfImportCanOnlyAppearOnceInTheList,
     /// Error E0431: `self` import can only appear in an import list with a non-empty prefix.
diff --git a/src/test/ui/error-codes/E0429.stderr b/src/test/ui/error-codes/E0429.stderr
index b5f76a1fcd8..457782583a5 100644
--- a/src/test/ui/error-codes/E0429.stderr
+++ b/src/test/ui/error-codes/E0429.stderr
@@ -1,8 +1,17 @@
 error[E0429]: `self` imports are only allowed within a { } list
-  --> $DIR/E0429.rs:1:5
+  --> $DIR/E0429.rs:1:13
    |
 LL | use std::fmt::self;
-   |     ^^^^^^^^^^^^^^
+   |             ^^^^^^
+   |
+help: Remove `::self`..
+   |
+LL | use std::fmt;
+   |            --
+help: ..or add braces around `self`
+   |
+LL | use std::fmt::{self};
+   |               ^    ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-45829/import-self.stderr b/src/test/ui/issues/issue-45829/import-self.stderr
index 39522cd8183..9d9a785387f 100644
--- a/src/test/ui/issues/issue-45829/import-self.stderr
+++ b/src/test/ui/issues/issue-45829/import-self.stderr
@@ -5,10 +5,19 @@ LL | use foo as self;
    |            ^^^^ expected identifier, found keyword
 
 error[E0429]: `self` imports are only allowed within a { } list
-  --> $DIR/import-self.rs:12:5
+  --> $DIR/import-self.rs:12:8
    |
 LL | use foo::self;
-   |     ^^^^^^^^^
+   |        ^^^^^^
+   |
+help: Remove `::self`..
+   |
+LL | use foo;
+   |       --
+help: ..or add braces around `self`
+   |
+LL | use foo::{self};
+   |          ^    ^
 
 error[E0255]: the name `foo` is defined multiple times
   --> $DIR/import-self.rs:6:11
diff --git a/src/test/ui/use/use-keyword.stderr b/src/test/ui/use/use-keyword.stderr
index 62b6a77fbfb..501d14be521 100644
--- a/src/test/ui/use/use-keyword.stderr
+++ b/src/test/ui/use/use-keyword.stderr
@@ -2,7 +2,7 @@ error[E0429]: `self` imports are only allowed within a { } list
   --> $DIR/use-keyword.rs:6:13
    |
 LL |         use self as A;
-   |             ^^^^^^^^^
+   |             ^^^^
 
 error[E0432]: unresolved import `super`
   --> $DIR/use-keyword.rs:8:13
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 e30e5c3ceb1..9d853296798 100644
--- a/src/test/ui/use/use-mod/use-mod-4.stderr
+++ b/src/test/ui/use/use-mod/use-mod-4.stderr
@@ -1,14 +1,32 @@
 error[E0429]: `self` imports are only allowed within a { } list
-  --> $DIR/use-mod-4.rs:1:5
+  --> $DIR/use-mod-4.rs:1:8
    |
 LL | use foo::self;
-   |     ^^^^^^^^^
+   |        ^^^^^^
+   |
+help: Remove `::self`..
+   |
+LL | use foo;
+   |       --
+help: ..or add braces around `self`
+   |
+LL | use foo::{self};
+   |          ^    ^
 
 error[E0429]: `self` imports are only allowed within a { } list
-  --> $DIR/use-mod-4.rs:4:5
+  --> $DIR/use-mod-4.rs:4:13
    |
 LL | use std::mem::self;
-   |     ^^^^^^^^^^^^^^
+   |             ^^^^^^
+   |
+help: Remove `::self`..
+   |
+LL | use std::mem;
+   |            --
+help: ..or add braces around `self`
+   |
+LL | use std::mem::{self};
+   |               ^    ^
 
 error[E0432]: unresolved import `foo`
   --> $DIR/use-mod-4.rs:1:5