Skip to content

Commit 37b7970

Browse files
committed
Auto merge of #4934 - illicitonion:exhaustive_match, r=flip1995
Update wildcard enum match lint for non_exhaustive enums changelog: wildcard_enum_match_arm gives better suggestions for non_exhaustive enums
2 parents 143ad5e + 4f4444c commit 37b7970

File tree

4 files changed

+88
-13
lines changed

4 files changed

+88
-13
lines changed

clippy_lints/src/matches.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
522522
}
523523
}
524524

525-
let suggestion: Vec<String> = missing_variants
525+
let mut suggestion: Vec<String> = missing_variants
526526
.iter()
527527
.map(|v| {
528528
let suffix = match v.ctor_kind {
@@ -543,11 +543,20 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
543543
return;
544544
}
545545

546+
let mut message = "wildcard match will miss any future added variants";
547+
548+
if let ty::Adt(def, _) = ty.kind {
549+
if def.is_variant_list_non_exhaustive() {
550+
message = "match on non-exhaustive enum doesn't explicitly match all known variants";
551+
suggestion.push(String::from("_"));
552+
}
553+
}
554+
546555
span_lint_and_sugg(
547556
cx,
548557
WILDCARD_ENUM_MATCH_ARM,
549558
wildcard_span,
550-
"wildcard match will miss any future added variants.",
559+
message,
551560
"try this",
552561
suggestion.join(" | "),
553562
Applicability::MachineApplicable,

tests/ui/wildcard_enum_match_arm.fixed

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// run-rustfix
22

33
#![deny(clippy::wildcard_enum_match_arm)]
4-
#![allow(unreachable_code, unused_variables, dead_code)]
4+
#![allow(unreachable_code, unused_variables, dead_code, clippy::single_match)]
5+
6+
use std::io::ErrorKind;
57

68
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
79
enum Color {
@@ -62,4 +64,32 @@ fn main() {
6264
140 => {},
6365
_ => {},
6466
};
67+
// We need to use an enum not defined in this test because non_exhaustive is ignored for the
68+
// purposes of dead code analysis within a crate.
69+
let error_kind = ErrorKind::NotFound;
70+
match error_kind {
71+
ErrorKind::NotFound => {},
72+
std::io::ErrorKind::PermissionDenied | std::io::ErrorKind::ConnectionRefused | std::io::ErrorKind::ConnectionReset | std::io::ErrorKind::ConnectionAborted | std::io::ErrorKind::NotConnected | std::io::ErrorKind::AddrInUse | std::io::ErrorKind::AddrNotAvailable | std::io::ErrorKind::BrokenPipe | std::io::ErrorKind::AlreadyExists | std::io::ErrorKind::WouldBlock | std::io::ErrorKind::InvalidInput | std::io::ErrorKind::InvalidData | std::io::ErrorKind::TimedOut | std::io::ErrorKind::WriteZero | std::io::ErrorKind::Interrupted | std::io::ErrorKind::Other | std::io::ErrorKind::UnexpectedEof | _ => {},
73+
}
74+
match error_kind {
75+
ErrorKind::NotFound => {},
76+
ErrorKind::PermissionDenied => {},
77+
ErrorKind::ConnectionRefused => {},
78+
ErrorKind::ConnectionReset => {},
79+
ErrorKind::ConnectionAborted => {},
80+
ErrorKind::NotConnected => {},
81+
ErrorKind::AddrInUse => {},
82+
ErrorKind::AddrNotAvailable => {},
83+
ErrorKind::BrokenPipe => {},
84+
ErrorKind::AlreadyExists => {},
85+
ErrorKind::WouldBlock => {},
86+
ErrorKind::InvalidInput => {},
87+
ErrorKind::InvalidData => {},
88+
ErrorKind::TimedOut => {},
89+
ErrorKind::WriteZero => {},
90+
ErrorKind::Interrupted => {},
91+
ErrorKind::Other => {},
92+
ErrorKind::UnexpectedEof => {},
93+
_ => {},
94+
}
6595
}

tests/ui/wildcard_enum_match_arm.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// run-rustfix
22

33
#![deny(clippy::wildcard_enum_match_arm)]
4-
#![allow(unreachable_code, unused_variables, dead_code)]
4+
#![allow(unreachable_code, unused_variables, dead_code, clippy::single_match)]
5+
6+
use std::io::ErrorKind;
57

68
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
79
enum Color {
@@ -62,4 +64,32 @@ fn main() {
6264
140 => {},
6365
_ => {},
6466
};
67+
// We need to use an enum not defined in this test because non_exhaustive is ignored for the
68+
// purposes of dead code analysis within a crate.
69+
let error_kind = ErrorKind::NotFound;
70+
match error_kind {
71+
ErrorKind::NotFound => {},
72+
_ => {},
73+
}
74+
match error_kind {
75+
ErrorKind::NotFound => {},
76+
ErrorKind::PermissionDenied => {},
77+
ErrorKind::ConnectionRefused => {},
78+
ErrorKind::ConnectionReset => {},
79+
ErrorKind::ConnectionAborted => {},
80+
ErrorKind::NotConnected => {},
81+
ErrorKind::AddrInUse => {},
82+
ErrorKind::AddrNotAvailable => {},
83+
ErrorKind::BrokenPipe => {},
84+
ErrorKind::AlreadyExists => {},
85+
ErrorKind::WouldBlock => {},
86+
ErrorKind::InvalidInput => {},
87+
ErrorKind::InvalidData => {},
88+
ErrorKind::TimedOut => {},
89+
ErrorKind::WriteZero => {},
90+
ErrorKind::Interrupted => {},
91+
ErrorKind::Other => {},
92+
ErrorKind::UnexpectedEof => {},
93+
_ => {},
94+
}
6595
}
Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
error: wildcard match will miss any future added variants.
2-
--> $DIR/wildcard_enum_match_arm.rs:29:9
1+
error: wildcard match will miss any future added variants
2+
--> $DIR/wildcard_enum_match_arm.rs:31:9
33
|
44
LL | _ => eprintln!("Not red"),
55
| ^ help: try this: `Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan`
@@ -10,23 +10,29 @@ note: lint level defined here
1010
LL | #![deny(clippy::wildcard_enum_match_arm)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

13-
error: wildcard match will miss any future added variants.
14-
--> $DIR/wildcard_enum_match_arm.rs:33:9
13+
error: wildcard match will miss any future added variants
14+
--> $DIR/wildcard_enum_match_arm.rs:35:9
1515
|
1616
LL | _not_red => eprintln!("Not red"),
1717
| ^^^^^^^^ help: try this: `_not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan`
1818

19-
error: wildcard match will miss any future added variants.
20-
--> $DIR/wildcard_enum_match_arm.rs:37:9
19+
error: wildcard match will miss any future added variants
20+
--> $DIR/wildcard_enum_match_arm.rs:39:9
2121
|
2222
LL | not_red => format!("{:?}", not_red),
2323
| ^^^^^^^ help: try this: `not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan`
2424

25-
error: wildcard match will miss any future added variants.
26-
--> $DIR/wildcard_enum_match_arm.rs:53:9
25+
error: wildcard match will miss any future added variants
26+
--> $DIR/wildcard_enum_match_arm.rs:55:9
2727
|
2828
LL | _ => "No red",
2929
| ^ help: try this: `Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan`
3030

31-
error: aborting due to 4 previous errors
31+
error: match on non-exhaustive enum doesn't explicitly match all known variants
32+
--> $DIR/wildcard_enum_match_arm.rs:72:9
33+
|
34+
LL | _ => {},
35+
| ^ help: try this: `std::io::ErrorKind::PermissionDenied | std::io::ErrorKind::ConnectionRefused | std::io::ErrorKind::ConnectionReset | std::io::ErrorKind::ConnectionAborted | std::io::ErrorKind::NotConnected | std::io::ErrorKind::AddrInUse | std::io::ErrorKind::AddrNotAvailable | std::io::ErrorKind::BrokenPipe | std::io::ErrorKind::AlreadyExists | std::io::ErrorKind::WouldBlock | std::io::ErrorKind::InvalidInput | std::io::ErrorKind::InvalidData | std::io::ErrorKind::TimedOut | std::io::ErrorKind::WriteZero | std::io::ErrorKind::Interrupted | std::io::ErrorKind::Other | std::io::ErrorKind::UnexpectedEof | _`
36+
37+
error: aborting due to 5 previous errors
3238

0 commit comments

Comments
 (0)