Skip to content

Commit a90c5a3

Browse files
authored
Rollup merge of rust-lang#97823 - compiler-errors:missing-comma-match-arm, r=estebank
Recover missing comma after match arm If we're missing a comma after a match arm expression, try parsing another pattern and a following `=>`. If we find both of those, then recover by suggesting to insert a `,`. Fixes rust-lang#80112
2 parents a64a982 + b13eb61 commit a90c5a3

File tree

3 files changed

+44
-23
lines changed

3 files changed

+44
-23
lines changed

compiler/rustc_parse/src/parser/expr.rs

+38-13
Original file line numberDiff line numberDiff line change
@@ -2718,13 +2718,12 @@ impl<'a> Parser<'a> {
27182718
));
27192719
}
27202720
this.expect_one_of(&[token::Comma], &[token::CloseDelim(Delimiter::Brace)])
2721-
.map_err(|mut err| {
2722-
match (sm.span_to_lines(expr.span), sm.span_to_lines(arm_start_span)) {
2723-
(Ok(ref expr_lines), Ok(ref arm_start_lines))
2724-
if arm_start_lines.lines[0].end_col
2725-
== expr_lines.lines[0].end_col
2726-
&& expr_lines.lines.len() == 2
2727-
&& this.token == token::FatArrow =>
2721+
.or_else(|mut err| {
2722+
if this.token == token::FatArrow {
2723+
if let Ok(expr_lines) = sm.span_to_lines(expr.span)
2724+
&& let Ok(arm_start_lines) = sm.span_to_lines(arm_start_span)
2725+
&& arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col
2726+
&& expr_lines.lines.len() == 2
27282727
{
27292728
// We check whether there's any trailing code in the parse span,
27302729
// if there isn't, we very likely have the following:
@@ -2743,15 +2742,41 @@ impl<'a> Parser<'a> {
27432742
",".to_owned(),
27442743
Applicability::MachineApplicable,
27452744
);
2745+
return Err(err);
27462746
}
2747-
_ => {
2748-
err.span_label(
2749-
arrow_span,
2750-
"while parsing the `match` arm starting here",
2751-
);
2747+
} else {
2748+
// FIXME(compiler-errors): We could also recover `; PAT =>` here
2749+
2750+
// Try to parse a following `PAT =>`, if successful
2751+
// then we should recover.
2752+
let mut snapshot = this.create_snapshot_for_diagnostic();
2753+
let pattern_follows = snapshot
2754+
.parse_pat_allow_top_alt(
2755+
None,
2756+
RecoverComma::Yes,
2757+
RecoverColon::Yes,
2758+
CommaRecoveryMode::EitherTupleOrPipe,
2759+
)
2760+
.map_err(|err| err.cancel())
2761+
.is_ok();
2762+
if pattern_follows && snapshot.check(&TokenKind::FatArrow) {
2763+
err.cancel();
2764+
this.struct_span_err(
2765+
hi.shrink_to_hi(),
2766+
"expected `,` following `match` arm",
2767+
)
2768+
.span_suggestion(
2769+
hi.shrink_to_hi(),
2770+
"missing a comma here to end this `match` arm",
2771+
",".to_owned(),
2772+
Applicability::MachineApplicable,
2773+
)
2774+
.emit();
2775+
return Ok(true);
27522776
}
27532777
}
2754-
err
2778+
err.span_label(arrow_span, "while parsing the `match` arm starting here");
2779+
Err(err)
27552780
})?;
27562781
} else {
27572782
this.eat(&token::Comma);

src/test/ui/parser/match-arm-without-braces.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ fn main() {
4545
15;
4646
}
4747
match S::get(16) {
48-
Some(Val::Foo) => 17
49-
_ => 18, //~ ERROR expected one of
50-
}
48+
Some(Val::Foo) => 17 //~ ERROR expected `,` following `match` arm
49+
_ => 18,
50+
};
5151
match S::get(19) {
5252
Some(Val::Foo) =>
5353
20; //~ ERROR `match` arm body without braces

src/test/ui/parser/match-arm-without-braces.stderr

+3-7
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,11 @@ LL ~ { 14;
5252
LL ~ 15; }
5353
|
5454

55-
error: expected one of `,`, `.`, `?`, `}`, or an operator, found reserved identifier `_`
56-
--> $DIR/match-arm-without-braces.rs:49:9
55+
error: expected `,` following `match` arm
56+
--> $DIR/match-arm-without-braces.rs:48:29
5757
|
5858
LL | Some(Val::Foo) => 17
59-
| -- - expected one of `,`, `.`, `?`, `}`, or an operator
60-
| |
61-
| while parsing the `match` arm starting here
62-
LL | _ => 18,
63-
| ^ unexpected token
59+
| ^ help: missing a comma here to end this `match` arm: `,`
6460

6561
error: `match` arm body without braces
6662
--> $DIR/match-arm-without-braces.rs:53:11

0 commit comments

Comments
 (0)