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
```
This commit is contained in:
Esteban Küber 2018-02-18 14:36:35 -08:00
parent 29f5c699b1
commit 0c9afa87ba
3 changed files with 68 additions and 2 deletions

View file

@ -3404,14 +3404,48 @@ impl<'a> Parser<'a> {
} else { } else {
None None
}; };
let arrow_span = self.span;
self.expect(&token::FatArrow)?; self.expect(&token::FatArrow)?;
let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None)?; let arm_start_span = self.span;
let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None)
.map_err(|mut err| {
err.span_label(arrow_span, "while parsing the match arm starting here");
err
})?;
let require_comma = classify::expr_requires_semi_to_be_stmt(&expr) let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
&& self.token != token::CloseDelim(token::Brace); && self.token != token::CloseDelim(token::Brace);
if require_comma { if require_comma {
self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])?; let cm = self.sess.codemap();
self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])
.map_err(|mut err| {
err.span_label(arrow_span, "while parsing the match arm starting here");
match (cm.span_to_lines(expr.span), cm.span_to_lines(arm_start_span)) {
(Ok(ref expr_lines), Ok(ref arm_start_lines))
if arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col
&& expr_lines.lines.len() == 2
&& self.token == token::FatArrow => {
// We check wether there's any trailing code in the parse span, if there
// isn't, we very likely have the following:
//
// X | &Y => "y"
// | -- - missing comma
// | |
// | arrow_span
// X | &X => "x"
// | - ^^ self.span
// | |
// | parsed until here as `"y" & X`
err.span_suggestion_short(cm.next_point(arm_start_span),
"missing a comma here to end this match arm",
",".to_owned());
}
_ => {}
}
err
})?;
} else { } else {
self.eat(&token::Comma); self.eat(&token::Comma);
} }

View file

@ -0,0 +1,20 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
match &Some(3) {
&None => 1
&Some(2) => { 3 }
//~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
//~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator here
//~^^^^ NOTE while parsing the match arm starting here
_ => 2
};
}

View file

@ -0,0 +1,12 @@
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
--> $DIR/missing-comma-in-match.rs:14:18
|
13 | &None => 1
| -- - help: missing a comma here to end this match arm
| |
| while parsing the match arm starting here
14 | &Some(2) => { 3 }
| ^^ expected one of `,`, `.`, `?`, `}`, or an operator here
error: aborting due to previous error