Skip to content

Sub-optional error message with slice rest syntax in patterns #72373

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
leonardo-m opened this issue May 20, 2020 · 4 comments · Fixed by #72534
Closed

Sub-optional error message with slice rest syntax in patterns #72373

leonardo-m opened this issue May 20, 2020 · 4 comments · Fixed by #72534
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST A-patterns Relating to patterns and pattern matching A-slice-patterns Area: Slice patterns, https://github.com/rust-lang/rust/issues/23121 C-enhancement Category: An issue proposing an enhancement or a PR with one. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@leonardo-m
Copy link

leonardo-m commented May 20, 2020

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), // OK
        [h, ref ts..] => foo(c, n - h) + foo(ts, n), // Wrong
        [] => 0,
    }
}
fn main() {}

Gives:

error: expected one of `,`, `@`, `]`, or `|`, found `..`
 --> ...\test.rs:6:19
  |
6 |         [h, ref ts..] => foo(c, n - h) + foo(ts, n),
  |                   -^
  |                   |
  |                   expected one of `,`, `@`, `]`, or `|`
  |                   help: missing `,`

error[E0308]: mismatched types
 --> ...\test.rs:6:46
  |
6 |         [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

I think a better error message should suggest the usage of ref ts @...

@jonas-schievink jonas-schievink added A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 20, 2020
@estebank estebank added A-parser Area: The parsing of Rust source code to an AST A-patterns Relating to patterns and pattern matching A-slice-patterns Area: Slice patterns, https://github.com/rust-lang/rust/issues/23121 D-papercut Diagnostics: An error or lint that needs small tweaks. labels May 21, 2020
@chrissimpkins
Copy link
Member

@rustbot claim

@chrissimpkins
Copy link
Member

#72534

This gets us to:

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

error: aborting due to previous error

@chrissimpkins
Copy link
Member

Format and help message revised to:

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

@chrissimpkins
Copy link
Member

Merged. Thanks for the report!

JohnTitor added a commit to JohnTitor/rust that referenced this issue May 30, 2020
Fix diagnostics for `@ ..` binding pattern in tuples and tuple structs

Fixes rust-lang#72574
Associated rust-lang#72534 rust-lang#72373

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

### Before

#### tuple

```
error: `..` patterns are not allowed here
 --> src/main.rs:4:19
  |
4 |         (_a, _x @ ..) => {}
  |                   ^^
  |
  = note: only allowed in tuple, tuple struct, and slice patterns

error[E0308]: mismatched types
 --> src/main.rs:4:9
  |
3 |     match x {
  |           - this expression has type `({integer}, {integer}, {integer})`
4 |         (_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
  |
  = note: expected tuple `({integer}, {integer}, {integer})`
             found tuple `(_, _)`

error: aborting due to 2 previous errors
```

#### tuple struct

```
error: `..` patterns are not allowed here
 --> src/main.rs:6:25
  |
6 |         Binder(_a, _x @ ..) => {}
  |                         ^^
  |
  = note: only allowed in tuple, tuple struct, and slice patterns

error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
 --> src/main.rs:6:9
  |
1 | struct Binder(i32, i32, i32);
  | ----------------------------- tuple struct defined here
...
6 |         Binder(_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2

error: aborting due to 2 previous errors
```

### After

*Note: final output edited during source review discussion, see thread for details*

#### tuple

```
error: `_x @` is not allowed in a tuple
 --> src/main.rs:4:14
  |
4 |         (_a, _x @ ..) => {}
  |              ^^^^^^^ is only allowed in a slice
  |
help: replace with `..` or use a different valid pattern
  |
4 |         (_a, ..) => {}
  |              ^^

error[E0308]: mismatched types
 --> src/main.rs:4:9
  |
3 |     match x {
  |           - this expression has type `({integer}, {integer}, {integer})`
4 |         (_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 1 element
  |
  = note: expected tuple `({integer}, {integer}, {integer})`
             found tuple `(_,)`

error: aborting due to 2 previous errors
```

#### tuple struct

```
error: `_x @` is not allowed in a tuple struct
 --> src/main.rs:6:20
  |
6 |         Binder(_a, _x @ ..) => {}
  |                    ^^^^^^^ is only allowed in a slice
  |
help: replace with `..` or use a different valid pattern
  |
6 |         Binder(_a, ..) => {}
  |                    ^^

error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 fields
 --> src/main.rs:6:9
  |
1 | struct Binder(i32, i32, i32);
  | ----------------------------- tuple struct defined here
...
6 |         Binder(_a, _x @ ..) => {}
  |         ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 1

error: aborting due to 2 previous errors
```

r? @estebank
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST A-patterns Relating to patterns and pattern matching A-slice-patterns Area: Slice patterns, https://github.com/rust-lang/rust/issues/23121 C-enhancement Category: An issue proposing an enhancement or a PR with one. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants