From cf19131cb356591d27dded5bdb1d00df1bd077c9 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Sun, 3 Oct 2021 14:14:35 +0200 Subject: [PATCH 1/2] Try to recover from a `=>` -> `=` or `->` typo in a match arm --- compiler/rustc_parse/src/parser/expr.rs | 16 +++++++++++++++- src/test/ui/parser/issue-89396.fixed | 16 ++++++++++++++++ src/test/ui/parser/issue-89396.rs | 16 ++++++++++++++++ src/test/ui/parser/issue-89396.stderr | 20 ++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/parser/issue-89396.fixed create mode 100644 src/test/ui/parser/issue-89396.rs create mode 100644 src/test/ui/parser/issue-89396.stderr diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c5417ea23f219..e6a0c4c79524f 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2322,7 +2322,21 @@ impl<'a> Parser<'a> { None }; let arrow_span = this.token.span; - this.expect(&token::FatArrow)?; + if let Err(mut err) = this.expect(&token::FatArrow) { + // We might have a `=>` -> `=` or `->` typo (issue #89396). + if let token::Eq | token::RArrow = this.token.kind { + err.span_suggestion( + this.token.span, + "try using a fat arrow here", + "=>".to_string(), + Applicability::MaybeIncorrect, + ); + err.emit(); + this.bump(); + } else { + return Err(err); + } + } let arm_start_span = this.token.span; let expr = this.parse_expr_res(Restrictions::STMT_EXPR, None).map_err(|mut err| { diff --git a/src/test/ui/parser/issue-89396.fixed b/src/test/ui/parser/issue-89396.fixed new file mode 100644 index 0000000000000..823ad8cd1f8df --- /dev/null +++ b/src/test/ui/parser/issue-89396.fixed @@ -0,0 +1,16 @@ +// Regression test for issue #89396: Try to recover from a +// `=>` -> `=` or `->` typo in a match arm. + +// run-rustfix + +fn main() { + let opt = Some(42); + let _ = match opt { + Some(_) => true, + //~^ ERROR: expected one of + //~| HELP: try using a fat arrow here + None => false, + //~^ ERROR: expected one of + //~| HELP: try using a fat arrow here + }; +} diff --git a/src/test/ui/parser/issue-89396.rs b/src/test/ui/parser/issue-89396.rs new file mode 100644 index 0000000000000..f1d9efa524f46 --- /dev/null +++ b/src/test/ui/parser/issue-89396.rs @@ -0,0 +1,16 @@ +// Regression test for issue #89396: Try to recover from a +// `=>` -> `=` or `->` typo in a match arm. + +// run-rustfix + +fn main() { + let opt = Some(42); + let _ = match opt { + Some(_) = true, + //~^ ERROR: expected one of + //~| HELP: try using a fat arrow here + None -> false, + //~^ ERROR: expected one of + //~| HELP: try using a fat arrow here + }; +} diff --git a/src/test/ui/parser/issue-89396.stderr b/src/test/ui/parser/issue-89396.stderr new file mode 100644 index 0000000000000..504420574e249 --- /dev/null +++ b/src/test/ui/parser/issue-89396.stderr @@ -0,0 +1,20 @@ +error: expected one of `=>`, `if`, or `|`, found `=` + --> $DIR/issue-89396.rs:9:17 + | +LL | Some(_) = true, + | ^ + | | + | expected one of `=>`, `if`, or `|` + | help: try using a fat arrow here: `=>` + +error: expected one of `=>`, `@`, `if`, or `|`, found `->` + --> $DIR/issue-89396.rs:12:14 + | +LL | None -> false, + | ^^ + | | + | expected one of `=>`, `@`, `if`, or `|` + | help: try using a fat arrow here: `=>` + +error: aborting due to 2 previous errors + From 079c075f24d2aae84cd6715f350cf56420816f63 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Mon, 4 Oct 2021 22:13:00 +0200 Subject: [PATCH 2/2] Use `TokenKind::similar_tokens()` --- compiler/rustc_ast/src/token.rs | 1 + compiler/rustc_parse/src/parser/expr.rs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 3a65ffe41ae87..db066d7c6a519 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -295,6 +295,7 @@ impl TokenKind { match *self { Comma => Some(vec![Dot, Lt, Semi]), Semi => Some(vec![Colon, Comma]), + FatArrow => Some(vec![Eq, RArrow]), _ => None, } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e6a0c4c79524f..79f46be73f6c2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2324,7 +2324,10 @@ impl<'a> Parser<'a> { let arrow_span = this.token.span; if let Err(mut err) = this.expect(&token::FatArrow) { // We might have a `=>` -> `=` or `->` typo (issue #89396). - if let token::Eq | token::RArrow = this.token.kind { + if TokenKind::FatArrow + .similar_tokens() + .map_or(false, |similar_tokens| similar_tokens.contains(&this.token.kind)) + { err.span_suggestion( this.token.span, "try using a fat arrow here",