Rollup merge of #72534 - chrissimpkins:fix-72373, r=estebank

Improve missing `@` in slice binding pattern diagnostics

Closes https://github.com/rust-lang/rust/issues/72373

Includes a new suggestion with `Applicability::MaybeIncorrect` confidence level.

Before:

```
 --> src/main.rs:5:19
  |
5 |         [h, ref ts..] => foo(c, n - h) + foo(ts, n),
  |                   -^
  |                   |
  |                   expected one of `,`, `@`, `]`, or `|`
  |                   help: missing `,`

error[E0308]: mismatched types
 --> src/main.rs:5:46
  |
5 |         [h, ref ts..] => foo(c, n - h) + foo(ts, n),
  |                                              ^^ expected slice `[u32]`, found `u32`
  |
  = note: expected reference `&[u32]`
             found reference `&u32`

error: aborting due to 2 previous errors
```

After:

```
error: expected one of `,`, `@`, `]`, or `|`, found `..`
 --> src/main.rs:5:20
  |
5 |         [h, ref ts..] => foo(c, n - h) + foo(ts, n),
  |                    ^^ expected one of `,`, `@`, `]`, or `|`
  |
help: if you meant to bind the contents of the rest of the array pattern into `ts`, use `@`
  |
5 |         [h, ref ts @ ..] => foo(c, n - h) + foo(ts, n),
  |                    ^

error: aborting due to previous error
```

r? @estebank
This commit is contained in:
Yuki Okushi 2020-05-29 15:07:04 +09:00 committed by GitHub
commit d19b51e441
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 0 deletions

View file

@ -672,6 +672,26 @@ impl<'a> Parser<'a> {
}
}
// If this was a missing `@` in a binding pattern
// bail with a suggestion
// https://github.com/rust-lang/rust/issues/72373
if self.prev_token.is_ident() && &self.token.kind == &token::DotDot {
let msg = format!(
"if you meant to bind the contents of \
the rest of the array pattern into `{}`, use `@`",
pprust::token_to_string(&self.prev_token)
);
expect_err
.span_suggestion_verbose(
self.prev_token.span.shrink_to_hi().until(self.token.span),
&msg,
" @ ".to_string(),
Applicability::MaybeIncorrect,
)
.emit();
break;
}
// Attempt to keep parsing if it was an omitted separator.
match f(self) {
Ok(t) => {

View file

@ -0,0 +1,9 @@
fn foo(c: &[u32], n: u32) -> u32 {
match *c {
[h, ..] if h > n => 0,
[h, ..] if h == n => 1,
[h, ref ts..] => foo(c, n - h) + foo(ts, n),
//~^ ERROR expected one of `,`, `@`, `]`, or `|`, found `..`
[] => 0,
}
}

View file

@ -0,0 +1,13 @@
error: expected one of `,`, `@`, `]`, or `|`, found `..`
--> $DIR/issue-72373.rs:5:19
|
LL | [h, ref ts..] => foo(c, n - h) + foo(ts, n),
| ^^ expected one of `,`, `@`, `]`, or `|`
|
help: if you meant to bind the contents of the rest of the array pattern into `ts`, use `@`
|
LL | [h, ref ts @ ..] => foo(c, n - h) + foo(ts, n),
| ^
error: aborting due to previous error