Auto merge of #16885 - Veykril:match-recovery, r=Veykril
fix: Improve error recovery for match arms This should make use of the recovery token sets, but I think it'd be better to fix that as a whole while fixing the other places for these adhoc recovery checks.
This commit is contained in:
commit
054ebf9482
@ -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,
|
||||
};
|
||||
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 `,`");
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -0,0 +1,11 @@
|
||||
fn foo() {
|
||||
match () {
|
||||
_ => (),,
|
||||
_ => ,
|
||||
_ => (),
|
||||
=> (),
|
||||
if true => (),
|
||||
_ => (),
|
||||
() if => (),
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user