diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index eab35a86c69e4..1b2760cf457d8 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 347b72885657a..ab2aeb2fa8251 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2894,15 +2894,16 @@ fn names_to_string(names: &[Name]) -> String { if i > 0 { result.push_str("::"); } + if Ident::with_dummy_span(*name).is_raw_guess() { + 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::>()) + names_to_string(&path.segments.iter().map(|seg| seg.ident.name).collect::>()) } /// A somewhat inefficient routine to obtain the name of a module. diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index 95ded537ab35b..7ed822a5cd5a1 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 17bd5b54738b9..aa0fa0e3c0a5e 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(x: Foo<&'x isize>>::A) | ^^^ expected identifier, found keyword - | -help: you can escape reserved keywords to use them as identifiers - | -LL | fn foo2(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 ce399dbbf456d..15ce94a6d00fa 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 0d15151b7d451..7de2c730a7069 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 7a461cf630c33..192ab5eb7f965 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 0000000000000..6c01383d9610d --- /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 0000000000000..58eb87c00a411 --- /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 7547dadf9e209..9b4fe2c1205db 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