Description
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.