As suggested in the non_exhaustive RFC, when using non-exhaustive enums and structs in patterns, the lint would warn the user for missing variants or fields despite having a wildcard arm or a rest pattern.
This can be useful when new fields/variants are added by the upstream crate so that they don't go unnoticed.
Given the following definition
#[non_exhaustive]
pub enum E {
First,
Second,
Third,
}
The following use should be linted:
match e {
E::First => {}
E::Second => {}
_ => {}
}
Given the following definition
#[derive(Default)]
#[non_exhaustive]
pub struct S {
pub a: i32,
pub b: i32,
pub c: i32,
}
The following cases should be linted
let S { a: _, b: _, .. } = S::default();
match S::default() {
S { a: 42, b: 21, .. } => {}
S { a: _, b: _, .. } => {}
}
if let S { a: 42, b: _, .. } = S::default() {}
while let S { a: 42, b: _, .. } = S::default() {
break;
}
let v = vec![S::default()];
for S { a: _, b: _, .. } in v {}
In addition to let destructuring in function parameters
pub fn take_s(S { a, b, .. }: S) -> (i32, i32) {
(a, b)
}
A struct variant of an enum should be linted in the same cases if it's the only variant of the enum. If it's not the only member, it can be linted only in the match, if let and while let cases.
Tuple structs can't be used in patterns if there are private fields using the T() syntax, but the T{0: _, 1: _} syntax can be used an so it should be linted like with structs.
Given the following definition
#[derive(Default)]
#[non_exhaustive]
pub struct T(pub i32, pub i32, pub i32);
The following cases should be linted
let T { 0: _, 1: _, .. } = T::default();
match T::default() {
T { 0: 42, 1: 21, .. } => {}
T { 0: _, 1: _, .. } => {}
}
if let T { 0: 42, 1: _, .. } = T::default() {}
while let T { 0: 42, 1: _, .. } = T::default() {
break;
}
let v = vec![T::default()];
for T { 0: _, 1: _, .. } in v {}
In addition to let destructuring in function parameters
pub fn take_t(T { 0: a, 1: b, .. }: T) -> (i32, i32) {
(a, b)
}
I've updated the description with some details to make it clearer.
Hi, is this issue already resolved? If so, it would be better to close this.
Nope, this issue is still relevant
I'd like to give this issue a shot
Added a new lint called not_exhaustive_enough.
Opening a WIP PR now
Most helpful comment
I'd like to give this issue a shot