Skip to content

missing fields in a struct pattern for a tuple variant syntax produces a flawed error #108284

New issue

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

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

Already on GitHub? Sign in to your account

Closed
oftheforest opened this issue Feb 20, 2023 · 0 comments · Fixed by #109760
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@oftheforest
Copy link

Suppose you have an enum with a tuple variant, and you try to match it with a struct pattern using field indices instead of names, but you forget some of the fields. Besides the missing fields, this is valid, but the error just tells you to switch to tuple variant syntax. (playground)

pub enum Foo {
    Bar(i32, i32),
}

impl Foo {
    pub fn qux(&self) {
        match self {
            Foo::Bar { 0: _ } => unimplemented!(),
        }
    }
}
error[E0769]: tuple variant `Foo::Bar` written as struct variant
 --> src/lib.rs:8:13
  |
8 |             Foo::Bar { 0: _ } => unimplemented!(),
  |             ^^^^^^^^^^^^^^^^^
  |
help: use the tuple variant pattern syntax instead
  |
8 |             Foo::Bar(_, _) => unimplemented!(),
  |                     ~~~~~~

The error message you would have gotten if you had used tuple variant syntax is nicer (playground):

pub enum Foo {
    Bar(i32, i32),
}

impl Foo {
    pub fn qux(&self) {
        match self {
            Foo::Bar(_) => unimplemented!(),
            //      ^^^ changed
        }
    }
}
error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
 --> src/lib.rs:8:22
  |
2 |     Bar(i32, i32),
  |         ---  --- tuple variant has 2 fields
...
8 |             Foo::Bar(_) => unimplemented!(),
  |                      ^ expected 2 fields, found 1
  |
help: use `_` to explicitly ignore each field
  |
8 |             Foo::Bar(_, _) => unimplemented!(),
  |                       +++
help: use `..` to ignore all fields
  |
8 |             Foo::Bar(..) => unimplemented!(),
  |                      ~~

It might be nice to change the first error to be more like the second. Something like:

error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
 --> src/lib.rs:8:22
  |
2 |     Bar(i32, i32),
  |         ---  --- tuple variant has 2 fields
...
8 |             Foo::Bar { 0: _ } => unimplemented!(),
  |                        ^^^^ expected 2 fields, found 1
  |
help: use `_` to explicitly ignore each field
  |
8 |             Foo::Bar { 0: _, 1: _ } => unimplemented!(),
  |                            ++++++
help: use `..` to ignore all fields
  |
8 |             Foo::Bar { .. } => unimplemented!(),
  |                        ~~

On the other hand, we might not want to do this: it risks being confusing to beginners, and unless you're writing a macro, you probably shouldn't use struct variant syntax to match a tuple variant.

We could add yet another note explaining that:

note: since `Foo::Bar` is a tuple variant, using the tuple variant pattern syntax would be more idiomatic
  |
8 |             Foo::Bar(_, _) => unimplemented!(),
  |                     ~~~~~~

but that might be too much.

Tested in today's playground (1.69.0-nightly 2023-02-17 7aa413d).

Somewhat related to/may interact with #79652.

@Noratrieb Noratrieb added A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 23, 2023
@bors bors closed this as completed in 696aaad Apr 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. 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.

2 participants