Skip to content

Commit 0c9afa8

Browse files
committed
Provide missing comma in match arm suggestion
When finding: ```rust match &Some(3) { &None => 1 &Some(2) => { 3 } _ => 2 } ``` provide the following diagnostic: ``` error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>` --> $DIR/missing-comma-in-match.rs:15:18 | X | &None => 1 | -- - help: missing comma | | | while parsing the match arm starting here X | &Some(2) => { 3 } | ^^ expected one of `,`, `.`, `?`, `}`, or an operator here ```
1 parent 29f5c69 commit 0c9afa8

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,14 +3404,48 @@ impl<'a> Parser<'a> {
34043404
} else {
34053405
None
34063406
};
3407+
let arrow_span = self.span;
34073408
self.expect(&token::FatArrow)?;
3408-
let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None)?;
3409+
let arm_start_span = self.span;
3410+
3411+
let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None)
3412+
.map_err(|mut err| {
3413+
err.span_label(arrow_span, "while parsing the match arm starting here");
3414+
err
3415+
})?;
34093416

34103417
let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
34113418
&& self.token != token::CloseDelim(token::Brace);
34123419

34133420
if require_comma {
3414-
self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])?;
3421+
let cm = self.sess.codemap();
3422+
self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])
3423+
.map_err(|mut err| {
3424+
err.span_label(arrow_span, "while parsing the match arm starting here");
3425+
match (cm.span_to_lines(expr.span), cm.span_to_lines(arm_start_span)) {
3426+
(Ok(ref expr_lines), Ok(ref arm_start_lines))
3427+
if arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col
3428+
&& expr_lines.lines.len() == 2
3429+
&& self.token == token::FatArrow => {
3430+
// We check wether there's any trailing code in the parse span, if there
3431+
// isn't, we very likely have the following:
3432+
//
3433+
// X | &Y => "y"
3434+
// | -- - missing comma
3435+
// | |
3436+
// | arrow_span
3437+
// X | &X => "x"
3438+
// | - ^^ self.span
3439+
// | |
3440+
// | parsed until here as `"y" & X`
3441+
err.span_suggestion_short(cm.next_point(arm_start_span),
3442+
"missing a comma here to end this match arm",
3443+
",".to_owned());
3444+
}
3445+
_ => {}
3446+
}
3447+
err
3448+
})?;
34153449
} else {
34163450
self.eat(&token::Comma);
34173451
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
match &Some(3) {
13+
&None => 1
14+
&Some(2) => { 3 }
15+
//~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
16+
//~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator here
17+
//~^^^^ NOTE while parsing the match arm starting here
18+
_ => 2
19+
};
20+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
2+
--> $DIR/missing-comma-in-match.rs:14:18
3+
|
4+
13 | &None => 1
5+
| -- - help: missing a comma here to end this match arm
6+
| |
7+
| while parsing the match arm starting here
8+
14 | &Some(2) => { 3 }
9+
| ^^ expected one of `,`, `.`, `?`, `}`, or an operator here
10+
11+
error: aborting due to previous error
12+

0 commit comments

Comments
 (0)