Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs58
-rw-r--r--crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast113
-rw-r--r--crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs11
3 files changed, 165 insertions, 17 deletions
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index 72848a1f2b..54ed5f0ba2 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -490,6 +490,18 @@ fn match_expr(p: &mut Parser<'_>) -> CompletedMarker {
m.complete(p, MATCH_EXPR)
}
+// test_err match_arms_recovery
+// fn foo() {
+// match () {
+// _ => (),,
+// _ => ,
+// _ => (),
+// => (),
+// if true => (),
+// _ => (),
+// () if => (),
+// }
+// }
pub(crate) fn match_arm_list(p: &mut Parser<'_>) {
assert!(p.at(T!['{']));
let m = p.start();
@@ -511,6 +523,10 @@ pub(crate) fn match_arm_list(p: &mut Parser<'_>) {
error_block(p, "expected match arm");
continue;
}
+ if p.at(T![,]) {
+ p.err_and_bump("expected pattern");
+ continue;
+ }
match_arm(p);
}
p.expect(T!['}']);
@@ -544,26 +560,30 @@ fn match_arm(p: &mut Parser<'_>) {
// }
attributes::outer_attrs(p);
- patterns::pattern_top_r(p, TokenSet::EMPTY);
+ patterns::pattern_top_r(p, TokenSet::new(&[T![=], T![if]]));
if p.at(T![if]) {
match_guard(p);
}
p.expect(T![=>]);
- let blocklike = match expr_stmt(p, None) {
- Some((_, blocklike)) => blocklike,
- None => BlockLike::NotBlock,
- };
-
- // test match_arms_commas
- // fn foo() {
- // match () {
- // _ => (),
- // _ => {}
- // _ => ()
- // }
- // }
- if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
- p.error("expected `,`");
+ if p.eat(T![,]) {
+ p.error("expected expression");
+ } else {
+ let blocklike = match expr_stmt(p, None) {
+ Some((_, blocklike)) => blocklike,
+ None => BlockLike::NotBlock,
+ };
+
+ // test match_arms_commas
+ // fn foo() {
+ // match () {
+ // _ => (),
+ // _ => {}
+ // _ => ()
+ // }
+ // }
+ if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
+ p.error("expected `,`");
+ }
}
m.complete(p, MATCH_ARM);
}
@@ -579,7 +599,11 @@ fn match_guard(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(T![if]));
let m = p.start();
p.bump(T![if]);
- expr(p);
+ if p.at(T![=]) {
+ p.error("expected expression");
+ } else {
+ expr(p);
+ }
m.complete(p, MATCH_GUARD)
}
diff --git a/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast b/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast
new file mode 100644
index 0000000000..5b191945e4
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast
@@ -0,0 +1,113 @@
+SOURCE_FILE
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "foo"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ MATCH_EXPR
+ MATCH_KW "match"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ MATCH_ARM_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ MATCH_ARM
+ WILDCARD_PAT
+ UNDERSCORE "_"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ ERROR
+ COMMA ","
+ WHITESPACE "\n "
+ MATCH_ARM
+ WILDCARD_PAT
+ UNDERSCORE "_"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ COMMA ","
+ WHITESPACE "\n "
+ MATCH_ARM
+ WILDCARD_PAT
+ UNDERSCORE "_"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ MATCH_ARM
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ MATCH_ARM
+ MATCH_GUARD
+ IF_KW "if"
+ WHITESPACE " "
+ LITERAL
+ TRUE_KW "true"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ MATCH_ARM
+ WILDCARD_PAT
+ UNDERSCORE "_"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ MATCH_ARM
+ TUPLE_PAT
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ MATCH_GUARD
+ IF_KW "if"
+ WHITESPACE " "
+ FAT_ARROW "=>"
+ WHITESPACE " "
+ TUPLE_EXPR
+ L_PAREN "("
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE "\n "
+ R_CURLY "}"
+ WHITESPACE "\n"
+ R_CURLY "}"
+ WHITESPACE "\n"
+error 42: expected pattern
+error 58: expected expression
+error 85: expected pattern
+error 100: expected pattern
+error 145: expected expression
diff --git a/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs b/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs
new file mode 100644
index 0000000000..173103b2e3
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs
@@ -0,0 +1,11 @@
+fn foo() {
+ match () {
+ _ => (),,
+ _ => ,
+ _ => (),
+ => (),
+ if true => (),
+ _ => (),
+ () if => (),
+ }
+}