Skip to content

Commit

Permalink
Rollup merge of #72534 - chrissimpkins:fix-72373, r=estebank
Browse files Browse the repository at this point in the history
Improve missing `@` in slice binding pattern diagnostics

Closes #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
  • Loading branch information
JohnTitor committed May 29, 2020
2 parents 6786c7d + 593d1ee commit d19b51e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/librustc_parse/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/issues/issue-72373.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}
13 changes: 13 additions & 0 deletions src/test/ui/issues/issue-72373.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit d19b51e

Please sign in to comment.