about summary refs log tree commit diff
diff options
context:
space:
mode:
authorflip1995 <philipp.krones@embecosm.com>2021-07-01 12:35:16 +0200
committerflip1995 <philipp.krones@embecosm.com>2021-07-01 12:38:30 +0200
commitfae7a09eea5644567ff7239abc3970d1e9a2d159 (patch)
tree98279d9bdb3909ffc426d20c9010d2abfdc149b3
parent0ffba7a68442767cb9ddcc1cc4224d17800f7f63 (diff)
downloadrust-fae7a09eea5644567ff7239abc3970d1e9a2d159.tar.gz
rust-fae7a09eea5644567ff7239abc3970d1e9a2d159.zip
match_wildcard_for_single_variants: don't produce bad suggestion
This fixes a bug where match_wildcard_for_single_variants produced a
bad suggestion where besides the missing variant, one or more hidden
variants were left.

This also adds tests to the ui-tests match_wildcard_for_single_variants
and wildcard_enum_match_arm to make sure that the correct suggestion is
produced.
-rw-r--r--clippy_lints/src/matches.rs5
-rw-r--r--tests/ui/match_wildcard_for_single_variants.fixed7
-rw-r--r--tests/ui/match_wildcard_for_single_variants.rs7
-rw-r--r--tests/ui/wildcard_enum_match_arm.fixed14
-rw-r--r--tests/ui/wildcard_enum_match_arm.rs14
-rw-r--r--tests/ui/wildcard_enum_match_arm.stderr8
6 files changed, 52 insertions, 3 deletions
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index da5ac96e3db..4c90b95a42b 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -1033,6 +1033,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
 
     // Accumulate the variants which should be put in place of the wildcard because they're not
     // already covered.
+    let has_hidden = adt_def.variants.iter().any(|x| is_hidden(cx, x));
     let mut missing_variants: Vec<_> = adt_def.variants.iter().filter(|x| !is_hidden(cx, x)).collect();
 
     let mut path_prefix = CommonPrefixSearcher::None;
@@ -1118,7 +1119,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
 
     match missing_variants.as_slice() {
         [] => (),
-        [x] if !adt_def.is_variant_list_non_exhaustive() => span_lint_and_sugg(
+        [x] if !adt_def.is_variant_list_non_exhaustive() && !has_hidden => span_lint_and_sugg(
             cx,
             MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
             wildcard_span,
@@ -1129,7 +1130,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
         ),
         variants => {
             let mut suggestions: Vec<_> = variants.iter().copied().map(format_suggestion).collect();
-            let message = if adt_def.is_variant_list_non_exhaustive() {
+            let message = if adt_def.is_variant_list_non_exhaustive() || has_hidden {
                 suggestions.push("_".into());
                 "wildcard matches known variants and will also match future added variants"
             } else {
diff --git a/tests/ui/match_wildcard_for_single_variants.fixed b/tests/ui/match_wildcard_for_single_variants.fixed
index 31b743f7a18..e675c183ea7 100644
--- a/tests/ui/match_wildcard_for_single_variants.fixed
+++ b/tests/ui/match_wildcard_for_single_variants.fixed
@@ -115,12 +115,19 @@ fn main() {
         pub enum Enum {
             A,
             B,
+            C,
             #[doc(hidden)]
             __Private,
         }
         match Enum::A {
             Enum::A => (),
             Enum::B => (),
+            Enum::C => (),
+            _ => (),
+        }
+        match Enum::A {
+            Enum::A => (),
+            Enum::B => (),
             _ => (),
         }
     }
diff --git a/tests/ui/match_wildcard_for_single_variants.rs b/tests/ui/match_wildcard_for_single_variants.rs
index d19e6ab7eb2..38c3ffc00c7 100644
--- a/tests/ui/match_wildcard_for_single_variants.rs
+++ b/tests/ui/match_wildcard_for_single_variants.rs
@@ -115,12 +115,19 @@ fn main() {
         pub enum Enum {
             A,
             B,
+            C,
             #[doc(hidden)]
             __Private,
         }
         match Enum::A {
             Enum::A => (),
             Enum::B => (),
+            Enum::C => (),
+            _ => (),
+        }
+        match Enum::A {
+            Enum::A => (),
+            Enum::B => (),
             _ => (),
         }
     }
diff --git a/tests/ui/wildcard_enum_match_arm.fixed b/tests/ui/wildcard_enum_match_arm.fixed
index 64aba68635a..3ee4ab48ac8 100644
--- a/tests/ui/wildcard_enum_match_arm.fixed
+++ b/tests/ui/wildcard_enum_match_arm.fixed
@@ -87,4 +87,18 @@ fn main() {
         ErrorKind::PermissionDenied => {},
         _ => {},
     }
+
+    {
+        #![allow(clippy::manual_non_exhaustive)]
+        pub enum Enum {
+            A,
+            B,
+            #[doc(hidden)]
+            __Private,
+        }
+        match Enum::A {
+            Enum::A => (),
+            Enum::B | _ => (),
+        }
+    }
 }
diff --git a/tests/ui/wildcard_enum_match_arm.rs b/tests/ui/wildcard_enum_match_arm.rs
index 5cafdf59bf5..46886550453 100644
--- a/tests/ui/wildcard_enum_match_arm.rs
+++ b/tests/ui/wildcard_enum_match_arm.rs
@@ -87,4 +87,18 @@ fn main() {
         ErrorKind::PermissionDenied => {},
         _ => {},
     }
+
+    {
+        #![allow(clippy::manual_non_exhaustive)]
+        pub enum Enum {
+            A,
+            B,
+            #[doc(hidden)]
+            __Private,
+        }
+        match Enum::A {
+            Enum::A => (),
+            _ => (),
+        }
+    }
 }
diff --git a/tests/ui/wildcard_enum_match_arm.stderr b/tests/ui/wildcard_enum_match_arm.stderr
index 807947582b0..d63f2090353 100644
--- a/tests/ui/wildcard_enum_match_arm.stderr
+++ b/tests/ui/wildcard_enum_match_arm.stderr
@@ -34,5 +34,11 @@ error: wildcard matches known variants and will also match future added variants
 LL |         _ => {},
    |         ^ help: try this: `ErrorKind::PermissionDenied | _`
 
-error: aborting due to 5 previous errors
+error: wildcard matches known variants and will also match future added variants
+  --> $DIR/wildcard_enum_match_arm.rs:101:13
+   |
+LL |             _ => (),
+   |             ^ help: try this: `Enum::B | _`
+
+error: aborting due to 6 previous errors