about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_parse/parser/diagnostics.rs15
-rw-r--r--src/librustc_resolve/lib.rs7
-rw-r--r--src/libsyntax_pos/symbol.rs12
-rw-r--r--src/test/ui/async-await/no-const-async.stderr5
-rw-r--r--src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr5
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr5
-rw-r--r--src/test/ui/parser/removed-syntax-field-let.stderr5
-rw-r--r--src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr5
-rw-r--r--src/test/ui/suggestions/raw-name-use-suggestion.rs9
-rw-r--r--src/test/ui/suggestions/raw-name-use-suggestion.stderr36
-rw-r--r--src/test/ui/try-block/try-block-in-edition2015.stderr5
11 files changed, 73 insertions, 36 deletions
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index 5036759da3f..e3a17c5c5e3 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -225,8 +225,21 @@ impl<'a> Parser<'a> {
             self.token.span,
             &format!("expected identifier, found {}", self.this_token_descr()),
         );
+        let valid_follow = &[
+            TokenKind::Eq,
+            TokenKind::Colon,
+            TokenKind::Comma,
+            TokenKind::Semi,
+            TokenKind::ModSep,
+            TokenKind::OpenDelim(token::DelimToken::Brace),
+            TokenKind::OpenDelim(token::DelimToken::Paren),
+            TokenKind::CloseDelim(token::DelimToken::Brace),
+            TokenKind::CloseDelim(token::DelimToken::Paren),
+        ];
         if let token::Ident(name, false) = self.token.kind {
-            if Ident::new(name, self.token.span).is_raw_guess() {
+            if Ident::new(name, self.token.span).is_raw_guess() &&
+                self.look_ahead(1, |t| valid_follow.contains(&t.kind))
+            {
                 err.span_suggestion(
                     self.token.span,
                     "you can escape reserved keywords to use them as identifiers",
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index c49db39643b..4e78dfa3e72 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2893,15 +2893,16 @@ fn names_to_string(names: &[Name]) -> String {
         if i > 0 {
             result.push_str("::");
         }
+        if name.is_used_keyword() && name.can_be_raw() {
+            result.push_str("r#");
+        }
         result.push_str(&name.as_str());
     }
     result
 }
 
 fn path_names_to_string(path: &Path) -> String {
-    names_to_string(&path.segments.iter()
-                        .map(|seg| seg.ident.name)
-                        .collect::<Vec<_>>())
+    names_to_string(&path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>())
 }
 
 /// A somewhat inefficient routine to obtain the name of a module.
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 979074f17c7..1e4bfe1b4ca 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1013,7 +1013,15 @@ pub mod sym {
 }
 
 impl Symbol {
-    fn is_used_keyword_2018(self) -> bool {
+    pub fn is_used_keyword(self) -> bool {
+        self.is_used_keyword_2015() || self.is_used_keyword_2018()
+    }
+
+    pub fn is_used_keyword_2015(self) -> bool {
+        self >= kw::As && self <= kw::While
+    }
+
+    pub fn is_used_keyword_2018(self) -> bool {
         self >= kw::Async && self <= kw::Dyn
     }
 
@@ -1057,7 +1065,7 @@ impl Ident {
     /// Returns `true` if the token is a keyword used in the language.
     pub fn is_used_keyword(self) -> bool {
         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
-        self.name >= kw::As && self.name <= kw::While ||
+        self.name.is_used_keyword_2015() ||
         self.name.is_used_keyword_2018() && self.span.rust_2018()
     }
 
diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr
index 95ded537ab3..7ed822a5cd5 100644
--- a/src/test/ui/async-await/no-const-async.stderr
+++ b/src/test/ui/async-await/no-const-async.stderr
@@ -3,11 +3,6 @@ error: expected identifier, found keyword `async`
    |
 LL | pub const async fn x() {}
    |           ^^^^^ expected identifier, found keyword
-   |
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | pub const r#async fn x() {}
-   |           ^^^^^^^
 
 error: expected `:`, found keyword `fn`
   --> $DIR/no-const-async.rs:5:17
diff --git a/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr
index 17bd5b54738..aa0fa0e3c0a 100644
--- a/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr
+++ b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr
@@ -3,11 +3,6 @@ error: expected identifier, found keyword `for`
    |
 LL | fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A)
    |                     ^^^ expected identifier, found keyword
-   |
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | fn foo2<I>(x: <I as r#for<'x> Foo<&'x isize>>::A)
-   |                     ^^^^^
 
 error: expected one of `::` or `>`, found `Foo`
   --> $DIR/associated-types-project-from-hrtb-explicit.rs:10:29
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
index ce399dbbf45..15ce94a6d00 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
@@ -12,11 +12,6 @@ error: expected identifier, found keyword `trait`
    |
 LL | trait T {
    | ^^^^^ expected identifier, found keyword
-   |
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | r#trait T {
-   | ^^^^^^^
 
 error: expected `:`, found `T`
   --> $DIR/missing-close-brace-in-struct.rs:4:7
diff --git a/src/test/ui/parser/removed-syntax-field-let.stderr b/src/test/ui/parser/removed-syntax-field-let.stderr
index 0d15151b7d4..7de2c730a70 100644
--- a/src/test/ui/parser/removed-syntax-field-let.stderr
+++ b/src/test/ui/parser/removed-syntax-field-let.stderr
@@ -3,11 +3,6 @@ error: expected identifier, found keyword `let`
    |
 LL |     let foo: (),
    |     ^^^ expected identifier, found keyword
-   |
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL |     r#let foo: (),
-   |     ^^^^^
 
 error: expected `:`, found `foo`
   --> $DIR/removed-syntax-field-let.rs:2:9
diff --git a/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr
index 7a461cf630c..192ab5eb7f9 100644
--- a/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr
+++ b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr
@@ -3,11 +3,6 @@ error: expected identifier, found keyword `as`
    |
 LL | use std::any:: as foo;
    |                ^^ expected identifier, found keyword
-   |
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | use std::any:: r#as foo;
-   |                ^^^^
 
 error: expected one of `::`, `;`, or `as`, found `foo`
   --> $DIR/use-as-where-use-ends-with-mod-sep.rs:1:19
diff --git a/src/test/ui/suggestions/raw-name-use-suggestion.rs b/src/test/ui/suggestions/raw-name-use-suggestion.rs
new file mode 100644
index 00000000000..6c01383d961
--- /dev/null
+++ b/src/test/ui/suggestions/raw-name-use-suggestion.rs
@@ -0,0 +1,9 @@
+mod foo {
+    pub fn r#let() {}
+    pub fn break() {} //~ ERROR expected identifier, found keyword `break`
+}
+
+fn main() {
+    foo::let(); //~ ERROR expected identifier, found keyword `let`
+    r#break(); //~ ERROR cannot find function `break` in this scope
+}
diff --git a/src/test/ui/suggestions/raw-name-use-suggestion.stderr b/src/test/ui/suggestions/raw-name-use-suggestion.stderr
new file mode 100644
index 00000000000..58eb87c00a4
--- /dev/null
+++ b/src/test/ui/suggestions/raw-name-use-suggestion.stderr
@@ -0,0 +1,36 @@
+error: expected identifier, found keyword `break`
+  --> $DIR/raw-name-use-suggestion.rs:3:12
+   |
+LL |     pub fn break() {}
+   |            ^^^^^ expected identifier, found keyword
+   |
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     pub fn r#break() {}
+   |            ^^^^^^^
+
+error: expected identifier, found keyword `let`
+  --> $DIR/raw-name-use-suggestion.rs:7:10
+   |
+LL |     foo::let();
+   |          ^^^ expected identifier, found keyword
+   |
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     foo::r#let();
+   |          ^^^^^
+
+error[E0425]: cannot find function `break` in this scope
+  --> $DIR/raw-name-use-suggestion.rs:8:5
+   |
+LL |     r#break();
+   |     ^^^^^^^ not found in this scope
+   |
+help: possible candidate is found in another module, you can import it into scope
+   |
+LL | use foo::r#break;
+   |
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr
index 7547dadf9e2..9b4fe2c1205 100644
--- a/src/test/ui/try-block/try-block-in-edition2015.stderr
+++ b/src/test/ui/try-block/try-block-in-edition2015.stderr
@@ -6,11 +6,6 @@ LL |     let try_result: Option<_> = try {
 LL |
 LL |         let x = 5;
    |         ^^^ expected identifier, found keyword
-   |
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL |         r#let x = 5;
-   |         ^^^^^
 
 error[E0574]: expected struct, variant or union type, found macro `try`
   --> $DIR/try-block-in-edition2015.rs:4:33