diff options
| author | bors <bors@rust-lang.org> | 2019-12-23 17:00:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-12-23 17:00:38 +0000 |
| commit | 37b7970a7ce1b44f1cbd485af8d9e0362cf01bfe (patch) | |
| tree | d4871bd3a03725a23d7c05e8399a1d69ee9d6404 | |
| parent | 143ad5e2d10582d2cd1c74d3bee20b14c04af02e (diff) | |
| parent | 4f4444c429a49c52461c528ba0b2f2be01f8ae04 (diff) | |
| download | rust-37b7970a7ce1b44f1cbd485af8d9e0362cf01bfe.tar.gz rust-37b7970a7ce1b44f1cbd485af8d9e0362cf01bfe.zip | |
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
| -rw-r--r-- | clippy_lints/src/matches.rs | 13 | ||||
| -rw-r--r-- | tests/ui/wildcard_enum_match_arm.fixed | 32 | ||||
| -rw-r--r-- | tests/ui/wildcard_enum_match_arm.rs | 32 | ||||
| -rw-r--r-- | tests/ui/wildcard_enum_match_arm.stderr | 24 |
4 files changed, 88 insertions, 13 deletions
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index cf7650d02bf..fc265c5231b 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -522,7 +522,7 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) { } } - let suggestion: Vec<String> = missing_variants + let mut suggestion: Vec<String> = missing_variants .iter() .map(|v| { let suffix = match v.ctor_kind { @@ -543,11 +543,20 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) { return; } + let mut message = "wildcard match will miss any future added variants"; + + if let ty::Adt(def, _) = ty.kind { + if def.is_variant_list_non_exhaustive() { + message = "match on non-exhaustive enum doesn't explicitly match all known variants"; + suggestion.push(String::from("_")); + } + } + span_lint_and_sugg( cx, WILDCARD_ENUM_MATCH_ARM, wildcard_span, - "wildcard match will miss any future added variants.", + message, "try this", suggestion.join(" | "), Applicability::MachineApplicable, diff --git a/tests/ui/wildcard_enum_match_arm.fixed b/tests/ui/wildcard_enum_match_arm.fixed index af67f326f85..1da2833e260 100644 --- a/tests/ui/wildcard_enum_match_arm.fixed +++ b/tests/ui/wildcard_enum_match_arm.fixed @@ -1,7 +1,9 @@ // run-rustfix #![deny(clippy::wildcard_enum_match_arm)] -#![allow(unreachable_code, unused_variables, dead_code)] +#![allow(unreachable_code, unused_variables, dead_code, clippy::single_match)] + +use std::io::ErrorKind; #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Color { @@ -62,4 +64,32 @@ fn main() { 140 => {}, _ => {}, }; + // We need to use an enum not defined in this test because non_exhaustive is ignored for the + // purposes of dead code analysis within a crate. + let error_kind = ErrorKind::NotFound; + match error_kind { + ErrorKind::NotFound => {}, + 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 | _ => {}, + } + match error_kind { + ErrorKind::NotFound => {}, + ErrorKind::PermissionDenied => {}, + ErrorKind::ConnectionRefused => {}, + ErrorKind::ConnectionReset => {}, + ErrorKind::ConnectionAborted => {}, + ErrorKind::NotConnected => {}, + ErrorKind::AddrInUse => {}, + ErrorKind::AddrNotAvailable => {}, + ErrorKind::BrokenPipe => {}, + ErrorKind::AlreadyExists => {}, + ErrorKind::WouldBlock => {}, + ErrorKind::InvalidInput => {}, + ErrorKind::InvalidData => {}, + ErrorKind::TimedOut => {}, + ErrorKind::WriteZero => {}, + ErrorKind::Interrupted => {}, + ErrorKind::Other => {}, + ErrorKind::UnexpectedEof => {}, + _ => {}, + } } diff --git a/tests/ui/wildcard_enum_match_arm.rs b/tests/ui/wildcard_enum_match_arm.rs index 049596d342e..c2eb4b30802 100644 --- a/tests/ui/wildcard_enum_match_arm.rs +++ b/tests/ui/wildcard_enum_match_arm.rs @@ -1,7 +1,9 @@ // run-rustfix #![deny(clippy::wildcard_enum_match_arm)] -#![allow(unreachable_code, unused_variables, dead_code)] +#![allow(unreachable_code, unused_variables, dead_code, clippy::single_match)] + +use std::io::ErrorKind; #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Color { @@ -62,4 +64,32 @@ fn main() { 140 => {}, _ => {}, }; + // We need to use an enum not defined in this test because non_exhaustive is ignored for the + // purposes of dead code analysis within a crate. + let error_kind = ErrorKind::NotFound; + match error_kind { + ErrorKind::NotFound => {}, + _ => {}, + } + match error_kind { + ErrorKind::NotFound => {}, + ErrorKind::PermissionDenied => {}, + ErrorKind::ConnectionRefused => {}, + ErrorKind::ConnectionReset => {}, + ErrorKind::ConnectionAborted => {}, + ErrorKind::NotConnected => {}, + ErrorKind::AddrInUse => {}, + ErrorKind::AddrNotAvailable => {}, + ErrorKind::BrokenPipe => {}, + ErrorKind::AlreadyExists => {}, + ErrorKind::WouldBlock => {}, + ErrorKind::InvalidInput => {}, + ErrorKind::InvalidData => {}, + ErrorKind::TimedOut => {}, + ErrorKind::WriteZero => {}, + ErrorKind::Interrupted => {}, + ErrorKind::Other => {}, + ErrorKind::UnexpectedEof => {}, + _ => {}, + } } diff --git a/tests/ui/wildcard_enum_match_arm.stderr b/tests/ui/wildcard_enum_match_arm.stderr index df90bad15ce..735f610b7e5 100644 --- a/tests/ui/wildcard_enum_match_arm.stderr +++ b/tests/ui/wildcard_enum_match_arm.stderr @@ -1,5 +1,5 @@ -error: wildcard match will miss any future added variants. - --> $DIR/wildcard_enum_match_arm.rs:29:9 +error: wildcard match will miss any future added variants + --> $DIR/wildcard_enum_match_arm.rs:31:9 | LL | _ => eprintln!("Not red"), | ^ help: try this: `Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan` @@ -10,23 +10,29 @@ note: lint level defined here LL | #![deny(clippy::wildcard_enum_match_arm)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: wildcard match will miss any future added variants. - --> $DIR/wildcard_enum_match_arm.rs:33:9 +error: wildcard match will miss any future added variants + --> $DIR/wildcard_enum_match_arm.rs:35:9 | LL | _not_red => eprintln!("Not red"), | ^^^^^^^^ help: try this: `_not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan` -error: wildcard match will miss any future added variants. - --> $DIR/wildcard_enum_match_arm.rs:37:9 +error: wildcard match will miss any future added variants + --> $DIR/wildcard_enum_match_arm.rs:39:9 | LL | not_red => format!("{:?}", not_red), | ^^^^^^^ help: try this: `not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan` -error: wildcard match will miss any future added variants. - --> $DIR/wildcard_enum_match_arm.rs:53:9 +error: wildcard match will miss any future added variants + --> $DIR/wildcard_enum_match_arm.rs:55:9 | LL | _ => "No red", | ^ help: try this: `Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan` -error: aborting due to 4 previous errors +error: match on non-exhaustive enum doesn't explicitly match all known variants + --> $DIR/wildcard_enum_match_arm.rs:72:9 + | +LL | _ => {}, + | ^ 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 | _` + +error: aborting due to 5 previous errors |
