diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 52da8a072c751..7c471fdebb3a0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -798,6 +798,18 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(self.span, &format!("expected identifier, found {}", self.this_token_descr())); + if let token::Ident(ident, false) = &self.token { + if ident.is_reserved() && !ident.is_path_segment_keyword() && + ident.name != keywords::Underscore.name() + { + err.span_suggestion_with_applicability( + self.span, + "you can escape reserved keywords to use them as identifiers", + format!("r#{}", ident), + Applicability::MaybeIncorrect, + ); + } + } if let Some(token_descr) = self.token_descr() { err.span_label(self.span, format!("expected identifier, found {}", token_descr)); } else { diff --git a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr index 5dd7030c77ec6..af1ac19c837d5 100644 --- a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr @@ -5,6 +5,10 @@ LL | produces_async! {} //~ ERROR expected identifier, found reserved keywor | ^^^^^^^^^^^^^^^^^^ expected identifier, found reserved keyword | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) +help: you can escape reserved keywords to use them as identifiers + | +LL | ( ) => ( pub fn r#async ( ) { } ) + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr index bd49948eb9531..52399362482bc 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -3,12 +3,20 @@ error: expected identifier, found reserved keyword `async` | LL | let mut async = 1; //~ ERROR expected identifier, found reserved keyword `async` | ^^^^^ expected identifier, found reserved keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | let mut r#async = 1; //~ ERROR expected identifier, found reserved keyword `async` + | ^^^^^^^ error: expected identifier, found reserved keyword `async` --> $DIR/edition-keywords-2018-2015-parsing.rs:18:13 | LL | module::async(); //~ ERROR expected identifier, found reserved keyword `async` | ^^^^^ expected identifier, found reserved keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | module::r#async(); //~ ERROR expected identifier, found reserved keyword `async` + | ^^^^^^^ error: no rules expected the token `r#async` --> $DIR/edition-keywords-2018-2015-parsing.rs:12:31 diff --git a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr index 44d0e78d06a46..d997c3d8a421a 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr @@ -5,6 +5,10 @@ LL | produces_async! {} //~ ERROR expected identifier, found reserved keywor | ^^^^^^^^^^^^^^^^^^ expected identifier, found reserved keyword | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) +help: you can escape reserved keywords to use them as identifiers + | +LL | ( ) => ( pub fn r#async ( ) { } ) + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr index 8e596f743d7f7..1621368870a52 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -3,12 +3,20 @@ error: expected identifier, found reserved keyword `async` | LL | let mut async = 1; //~ ERROR expected identifier, found reserved keyword `async` | ^^^^^ expected identifier, found reserved keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | let mut r#async = 1; //~ ERROR expected identifier, found reserved keyword `async` + | ^^^^^^^ error: expected identifier, found reserved keyword `async` --> $DIR/edition-keywords-2018-2018-parsing.rs:18:13 | LL | module::async(); //~ ERROR expected identifier, found reserved keyword `async` | ^^^^^ expected identifier, found reserved keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | module::r#async(); //~ ERROR expected identifier, found reserved keyword `async` + | ^^^^^^^ error: no rules expected the token `r#async` --> $DIR/edition-keywords-2018-2018-parsing.rs:12:31 diff --git a/src/test/ui/issues/issue-28433.stderr b/src/test/ui/issues/issue-28433.stderr index 97df6db2b5215..d3cba3aae7101 100644 --- a/src/test/ui/issues/issue-28433.stderr +++ b/src/test/ui/issues/issue-28433.stderr @@ -3,6 +3,10 @@ error: expected identifier, found keyword `pub` | LL | pub duck, | ^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | r#pub duck, + | ^^^^^ error: expected one of `(`, `,`, `=`, `{`, or `}`, found `duck` --> $DIR/issue-28433.rs:4:9 diff --git a/src/test/ui/issues/issue-44406.stderr b/src/test/ui/issues/issue-44406.stderr index 45ea586373c3c..105dbb677dc02 100644 --- a/src/test/ui/issues/issue-44406.stderr +++ b/src/test/ui/issues/issue-44406.stderr @@ -3,6 +3,10 @@ error: expected identifier, found keyword `true` | LL | foo!(true); //~ ERROR expected type, found keyword | ^^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | foo!(r#true); //~ ERROR expected type, found keyword + | ^^^^^^ error: expected type, found keyword `true` --> $DIR/issue-44406.rs:8:10 diff --git a/src/test/ui/issues/issue-57198.stderr b/src/test/ui/issues/issue-57198.stderr index c4d297b2d95eb..2ab552ccbd3c8 100644 --- a/src/test/ui/issues/issue-57198.stderr +++ b/src/test/ui/issues/issue-57198.stderr @@ -3,6 +3,10 @@ error: expected identifier, found keyword `for` | LL | m::for(); | ^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | m::r#for(); + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr index 20efc1fab56b1..fa0a7ac002b2f 100644 --- a/src/test/ui/lifetime_starts_expressions.stderr +++ b/src/test/ui/lifetime_starts_expressions.stderr @@ -3,6 +3,10 @@ error: expected identifier, found keyword `loop` | LL | loop { break 'label: loop { break 'label 42; }; } | ^^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | loop { break 'label: r#loop { break 'label 42; }; } + | ^^^^^^ error: expected type, found keyword `loop` --> $DIR/lifetime_starts_expressions.rs:6:26 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 51b1e71a1bb90..ceea4625e3eb3 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,6 +3,10 @@ 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:12:29 diff --git a/src/test/ui/parser/bad-value-ident-false.stderr b/src/test/ui/parser/bad-value-ident-false.stderr index a78437a05f425..1a5c982a43dbc 100644 --- a/src/test/ui/parser/bad-value-ident-false.stderr +++ b/src/test/ui/parser/bad-value-ident-false.stderr @@ -3,6 +3,10 @@ error: expected identifier, found keyword `false` | LL | fn false() { } //~ ERROR expected identifier, found keyword `false` | ^^^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | fn r#false() { } //~ ERROR expected identifier, found keyword `false` + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/bad-value-ident-true.stderr b/src/test/ui/parser/bad-value-ident-true.stderr index 948fa4db50e8e..f431706ccd76b 100644 --- a/src/test/ui/parser/bad-value-ident-true.stderr +++ b/src/test/ui/parser/bad-value-ident-true.stderr @@ -3,6 +3,10 @@ error: expected identifier, found keyword `true` | LL | fn true() { } //~ ERROR expected identifier, found keyword `true` | ^^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | fn r#true() { } //~ ERROR expected identifier, found keyword `true` + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/issue-15980.stderr b/src/test/ui/parser/issue-15980.stderr index 748f21016a33b..96f3b03dc9240 100644 --- a/src/test/ui/parser/issue-15980.stderr +++ b/src/test/ui/parser/issue-15980.stderr @@ -6,6 +6,10 @@ LL | Err(ref e) if e.kind == io::EndOfFile { LL | //~^ NOTE while parsing this struct LL | return | ^^^^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | r#return + | error: expected one of `.`, `=>`, `?`, or an operator, found `_` --> $DIR/issue-15980.rs:15:9 diff --git a/src/test/ui/parser/keyword.stderr b/src/test/ui/parser/keyword.stderr index d97f6c5ce5aff..1c729ff083352 100644 --- a/src/test/ui/parser/keyword.stderr +++ b/src/test/ui/parser/keyword.stderr @@ -3,6 +3,10 @@ error: expected identifier, found keyword `break` | LL | pub mod break { | ^^^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | pub mod r#break { + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/macro-keyword.stderr b/src/test/ui/parser/macro-keyword.stderr index 0dca30a60d1da..d3edb04c11951 100644 --- a/src/test/ui/parser/macro-keyword.stderr +++ b/src/test/ui/parser/macro-keyword.stderr @@ -3,6 +3,10 @@ error: expected identifier, found reserved keyword `macro` | LL | fn macro() { //~ ERROR expected identifier, found reserved keyword `macro` | ^^^^^ expected identifier, found reserved keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | fn r#macro() { //~ ERROR expected identifier, found reserved keyword `macro` + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/removed-syntax-field-let.stderr b/src/test/ui/parser/removed-syntax-field-let.stderr index bec50e59664d6..0d489beae123a 100644 --- a/src/test/ui/parser/removed-syntax-field-let.stderr +++ b/src/test/ui/parser/removed-syntax-field-let.stderr @@ -3,6 +3,10 @@ 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:4: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 3be31ce9cec63..51e1a02cbd763 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,6 +3,10 @@ error: expected identifier, found keyword `as` | LL | use std::any:: as foo; //~ ERROR expected identifier, found keyword `as` | ^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | use std::any:: r#as foo; //~ ERROR expected identifier, found keyword `as` + | ^^^^ error: expected one of `::`, `;`, or `as`, found `foo` --> $DIR/use-as-where-use-ends-with-mod-sep.rs:3:19 diff --git a/src/test/ui/rust-2018/dyn-trait-compatibility.stderr b/src/test/ui/rust-2018/dyn-trait-compatibility.stderr index bd72f9c6786b2..6be0052046583 100644 --- a/src/test/ui/rust-2018/dyn-trait-compatibility.stderr +++ b/src/test/ui/rust-2018/dyn-trait-compatibility.stderr @@ -3,6 +3,10 @@ error: expected identifier, found keyword `dyn` | LL | type A1 = dyn::dyn; //~ERROR expected identifier, found keyword `dyn` | ^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | type A1 = dyn::r#dyn; //~ERROR expected identifier, found keyword `dyn` + | ^^^^^ error: expected identifier, found `<` --> $DIR/dyn-trait-compatibility.rs:5:14 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 b16aa59090d04..63650086bcaa9 100644 --- a/src/test/ui/try-block/try-block-in-edition2015.stderr +++ b/src/test/ui/try-block/try-block-in-edition2015.stderr @@ -6,6 +6,10 @@ LL | let try_result: Option<_> = try { LL | //~^ ERROR expected struct, variant or union type, found macro `try` LL | let x = 5; //~ ERROR expected identifier, found keyword | ^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | r#let x = 5; //~ ERROR expected identifier, found keyword + | ^^^^^ error[E0574]: expected struct, variant or union type, found macro `try` --> $DIR/try-block-in-edition2015.rs:4:33