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)
|
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<'_>) {
|
pub(crate) fn match_arm_list(p: &mut Parser<'_>) {
|
||||||
assert!(p.at(T!['{']));
|
assert!(p.at(T!['{']));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
@ -511,6 +523,10 @@ pub(crate) fn match_arm_list(p: &mut Parser<'_>) {
|
|||||||
error_block(p, "expected match arm");
|
error_block(p, "expected match arm");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if p.at(T![,]) {
|
||||||
|
p.err_and_bump("expected pattern");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
match_arm(p);
|
match_arm(p);
|
||||||
}
|
}
|
||||||
p.expect(T!['}']);
|
p.expect(T!['}']);
|
||||||
@ -544,26 +560,30 @@ fn match_arm(p: &mut Parser<'_>) {
|
|||||||
// }
|
// }
|
||||||
attributes::outer_attrs(p);
|
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]) {
|
if p.at(T![if]) {
|
||||||
match_guard(p);
|
match_guard(p);
|
||||||
}
|
}
|
||||||
p.expect(T![=>]);
|
p.expect(T![=>]);
|
||||||
let blocklike = match expr_stmt(p, None) {
|
if p.eat(T![,]) {
|
||||||
Some((_, blocklike)) => blocklike,
|
p.error("expected expression");
|
||||||
None => BlockLike::NotBlock,
|
} else {
|
||||||
};
|
let blocklike = match expr_stmt(p, None) {
|
||||||
|
Some((_, blocklike)) => blocklike,
|
||||||
|
None => BlockLike::NotBlock,
|
||||||
|
};
|
||||||
|
|
||||||
// test match_arms_commas
|
// test match_arms_commas
|
||||||
// fn foo() {
|
// fn foo() {
|
||||||
// match () {
|
// match () {
|
||||||
// _ => (),
|
// _ => (),
|
||||||
// _ => {}
|
// _ => {}
|
||||||
// _ => ()
|
// _ => ()
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
|
if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
|
||||||
p.error("expected `,`");
|
p.error("expected `,`");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m.complete(p, MATCH_ARM);
|
m.complete(p, MATCH_ARM);
|
||||||
}
|
}
|
||||||
@ -579,7 +599,11 @@ fn match_guard(p: &mut Parser<'_>) -> CompletedMarker {
|
|||||||
assert!(p.at(T![if]));
|
assert!(p.at(T![if]));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
p.bump(T![if]);
|
p.bump(T![if]);
|
||||||
expr(p);
|
if p.at(T![=]) {
|
||||||
|
p.error("expected expression");
|
||||||
|
} else {
|
||||||
|
expr(p);
|
||||||
|
}
|
||||||
m.complete(p, MATCH_GUARD)
|
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