I'm working on a rust project that relies heavily on match statements. Rust's exhaustive matching is a big part of the reason that we picked this language to work in, and I'm curious if it's possible to not allow matches against an enum to include a rest condition _ => {}
-- rather, we want to ensure that every single match statement matches against every variant of the enum. This is because the enum variants will grow over time as the project undergoes long-term development, and we want to make sure that every variant is always matched against.
For example:
enum MyEnum {
VariantA,
VariantB,
VariantC,
VariantD,
}
impl MyEnum {
fn some_method(&self) {
match self {
MyEnum::VariantA => todo!(),
MyEnum::VariantB => todo!(),
_ => todo!(), // <-- DON'T ALLOW THIS
}
}
}
Currently, we are simply communicating never to use rest conditions like this, but we're wondering if there's a way to enforce this more thoroughly.
I tried to search for information about macros, VSCode extensions, or other ways of checking for/enforcing that no rest conditions are included in match statements, but couldn't find anything. I also couldn't find a clearly-defined name for these conditions -- I call them "rest conditions" but didn't find official rust vocabulary for such cases. Not knowing a more widely-used term might have also hurt my ability to search.
Yes. You can enforce that by turning on Clippy's wildcard_enum_match_arm lint. For example following code:
#![deny(clippy::wildcard_enum_match_arm)]
enum MyEnum {
VariantA,
VariantB,
VariantC,
VariantD,
}
impl MyEnum {
fn some_method(&self) {
match self {
MyEnum::VariantA => todo!(),
MyEnum::VariantB => todo!(),
_ => todo!(), // <-- DON'T ALLOW THIS
}
}
}
Will fail cargo clippy
check with following error:
error: wildcard match will also match any future added variants
--> src/lib.rs:15:13
|
15 | _ => todo!(), // <-- DON'T ALLOW THIS
| ^ help: try: `MyEnum::VariantC | MyEnum::VariantD`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_enum_match_arm
note: the lint level is defined here
--> src/lib.rs:1:9
|
1 | #![deny(clippy::wildcard_enum_match_arm)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^