rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
95.24k stars 12.28k forks source link

Suggest adding `{ .. }` on accidental usage of unit variant pattern for a struct variant #126243

Open carols10cents opened 1 month ago

carols10cents commented 1 month ago

Code

pub enum Error {
    NotFound,

    PreconditionFailed {
        description: String,
    }
}

pub fn demonstration(error: Error) {
    match error {
        Error::NotFound => println!("gone fishin"),
        Error::PreconditionFailed => println!("you're missing something"),
        _ => println!("i literally have no idea"),
    }
}

Current output

error[E0533]: expected unit struct, unit variant or constant, found struct variant `Error::PreconditionFailed`
  --> src/lib.rs:12:9
   |
12 |         Error::PreconditionFailed => println!("you're missing something"),
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant

Desired output

error[E0533]: expected unit struct, unit variant or constant, found struct variant `Error::PreconditionFailed`
  --> src/lib.rs:12:9
   |
12 |         Error::PreconditionFailed => println!("you're missing something"),
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
help: if you don't care about the variant's fields, ignore them with `{ .. }`
   |
12 |         Error::PreconditionFailed { .. } => println!("you're missing something"),
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Rationale and extra context

playground

I wrote code that looked like this while not having my brain turned on 100%. Due to said brain not functioning, it took me a while to understand what rustc was trying to tell me with the message pointing to the Error::PreconditionFailed pattern with the text not a unit struct, unit variant or constant. Error::PreconditionFailed sure looked like a unit variant to me!

What rustc was trying to tell me was that the definition of the Error::PreconditionFailed variant was a struct variant ("found struct variant") and my pattern wasn't matching the definition ("this pattern you specified looks like it's trying to match a variant that is not a unit struct, unit variant or constant").

The change I needed to make was adding { .. } to my pattern, because I was trying to distinguish different variants from each other, not use pieces within the variants. Suggesting { .. } seems like a decent starting point to me, but there could definitely be cases I'm not considering here and I'm totally open to hearing that ❤️

Other cases

No response

Rust Version

$ rustc --version --verbose
rustc 1.78.0 (9b00956e5 2024-04-29)
binary: rustc
commit-hash: 9b00956e56009bab2aa15d7bff10916599e3d6d6
commit-date: 2024-04-29
host: aarch64-apple-darwin
release: 1.78.0
LLVM version: 18.1.2

Anything else?

No response

carols10cents commented 1 month ago

WEIRD this PR looks like it implements what I wish rustc did: https://github.com/rust-lang/rust/pull/64660

but the test files in that PR say they're for error[E0532] and I'm getting error[E0533]

carols10cents commented 1 month ago

Aha ok this test shows that for tuple variants, rustc will suggest adding (_): https://github.com/rust-lang/rust/blob/a3167859f2fd8ff2241295469876a2b687280bdc/tests/ui/issues/issue-63983.stderr#L8

and that test also shows that rustc isn't suggesting anything for struct variants!

carols10cents commented 1 month ago

Aha and it looks like adding struct fields was more complex so that's why it wasn't done? https://github.com/rust-lang/rust/issues/63983#issuecomment-533807637