about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCentri3 <114838443+Centri3@users.noreply.github.com>2023-06-13 13:08:03 -0500
committerCentri3 <114838443+Centri3@users.noreply.github.com>2023-06-14 08:36:09 -0500
commit27a701a670c5e14b632e205a818d8e32ffdcda44 (patch)
tree5d62a227d6338104317b7a9cc3578315ab3cda01
parent72332b2598b3077ef6241eadcb807d1f89175af0 (diff)
downloadrust-27a701a670c5e14b632e205a818d8e32ffdcda44.tar.gz
rust-27a701a670c5e14b632e205a818d8e32ffdcda44.zip
[`match_same_arms`]: don't lint if `non_exhaustive_omitted_patterns`
formatting :/
-rw-r--r--clippy_lints/src/matches/match_same_arms.rs29
-rw-r--r--clippy_lints/src/matches/mod.rs3
-rw-r--r--tests/ui/match_same_arms_non_exhaustive.rs58
-rw-r--r--tests/ui/match_same_arms_non_exhaustive.stderr29
4 files changed, 107 insertions, 12 deletions
diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs
index ae8262ace96..3d2fbea63f5 100644
--- a/clippy_lints/src/matches/match_same_arms.rs
+++ b/clippy_lints/src/matches/match_same_arms.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
-use clippy_utils::{path_to_local, search_same, SpanlessEq, SpanlessHash};
+use clippy_utils::{is_lint_allowed, path_to_local, search_same, SpanlessEq, SpanlessHash};
 use core::cmp::Ordering;
 use core::iter;
 use core::slice;
@@ -9,6 +9,7 @@ use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatKind, RangeEnd};
+use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_span::Symbol;
@@ -103,17 +104,21 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
     let indexed_arms: Vec<(usize, &Arm<'_>)> = arms.iter().enumerate().collect();
     for (&(i, arm1), &(j, arm2)) in search_same(&indexed_arms, hash, eq) {
         if matches!(arm2.pat.kind, PatKind::Wild) {
-            span_lint_and_then(
-                cx,
-                MATCH_SAME_ARMS,
-                arm1.span,
-                "this match arm has an identical body to the `_` wildcard arm",
-                |diag| {
-                    diag.span_suggestion(arm1.span, "try removing the arm", "", Applicability::MaybeIncorrect)
-                        .help("or try changing either arm body")
-                        .span_note(arm2.span, "`_` wildcard arm here");
-                },
-            );
+            if !cx.tcx.features().non_exhaustive_omitted_patterns_lint
+                || is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, arm2.hir_id)
+            {
+                span_lint_and_then(
+                    cx,
+                    MATCH_SAME_ARMS,
+                    arm1.span,
+                    "this match arm has an identical body to the `_` wildcard arm",
+                    |diag| {
+                        diag.span_suggestion(arm1.span, "try removing the arm", "", Applicability::MaybeIncorrect)
+                            .help("or try changing either arm body")
+                            .span_note(arm2.span, "`_` wildcard arm here");
+                    },
+                );
+            }
         } else {
             let back_block = backwards_blocking_idxs[j];
             let (keep_arm, move_arm) = if back_block < i || (back_block == 0 && forwards_blocking_idxs[i] <= j) {
diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs
index 2d27be499f9..3fbd0867ea9 100644
--- a/clippy_lints/src/matches/mod.rs
+++ b/clippy_lints/src/matches/mod.rs
@@ -559,6 +559,9 @@ declare_clippy_lint! {
     /// ### What it does
     /// Checks for `match` with identical arm bodies.
     ///
+    /// Note: Does not lint on wildcards if the `non_exhaustive_omitted_patterns_lint` feature is
+    /// enabled and disallowed.
+    ///
     /// ### Why is this bad?
     /// This is probably a copy & paste error. If arm bodies
     /// are the same on purpose, you can factor them
diff --git a/tests/ui/match_same_arms_non_exhaustive.rs b/tests/ui/match_same_arms_non_exhaustive.rs
new file mode 100644
index 00000000000..07421173a33
--- /dev/null
+++ b/tests/ui/match_same_arms_non_exhaustive.rs
@@ -0,0 +1,58 @@
+#![feature(non_exhaustive_omitted_patterns_lint)]
+#![warn(clippy::match_same_arms)]
+#![no_main]
+
+use std::sync::atomic::Ordering; // #[non_exhaustive] enum
+
+pub fn f(x: Ordering) {
+    match x {
+        Ordering::Relaxed => println!("relaxed"),
+        Ordering::Release => println!("release"),
+        Ordering::Acquire => println!("acquire"),
+        Ordering::AcqRel | Ordering::SeqCst => panic!(),
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => panic!(),
+    }
+}
+
+mod f {
+    #![deny(non_exhaustive_omitted_patterns)]
+
+    use super::*;
+
+    pub fn f(x: Ordering) {
+        match x {
+            Ordering::Relaxed => println!("relaxed"),
+            Ordering::Release => println!("release"),
+            Ordering::Acquire => println!("acquire"),
+            Ordering::AcqRel | Ordering::SeqCst => panic!(),
+            _ => panic!(),
+        }
+    }
+}
+
+// Below should still lint
+
+pub fn g(x: Ordering) {
+    match x {
+        Ordering::Relaxed => println!("relaxed"),
+        Ordering::Release => println!("release"),
+        Ordering::Acquire => println!("acquire"),
+        Ordering::AcqRel | Ordering::SeqCst => panic!(),
+        _ => panic!(),
+    }
+}
+
+mod g {
+    use super::*;
+
+    pub fn g(x: Ordering) {
+        match x {
+            Ordering::Relaxed => println!("relaxed"),
+            Ordering::Release => println!("release"),
+            Ordering::Acquire => println!("acquire"),
+            Ordering::AcqRel | Ordering::SeqCst => panic!(),
+            _ => panic!(),
+        }
+    }
+}
diff --git a/tests/ui/match_same_arms_non_exhaustive.stderr b/tests/ui/match_same_arms_non_exhaustive.stderr
new file mode 100644
index 00000000000..088f7d5c062
--- /dev/null
+++ b/tests/ui/match_same_arms_non_exhaustive.stderr
@@ -0,0 +1,29 @@
+error: this match arm has an identical body to the `_` wildcard arm
+  --> $DIR/match_same_arms_non_exhaustive.rs:41:9
+   |
+LL |         Ordering::AcqRel | Ordering::SeqCst => panic!(),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
+   |
+   = help: or try changing either arm body
+note: `_` wildcard arm here
+  --> $DIR/match_same_arms_non_exhaustive.rs:42:9
+   |
+LL |         _ => panic!(),
+   |         ^^^^^^^^^^^^^
+   = note: `-D clippy::match-same-arms` implied by `-D warnings`
+
+error: this match arm has an identical body to the `_` wildcard arm
+  --> $DIR/match_same_arms_non_exhaustive.rs:54:13
+   |
+LL |             Ordering::AcqRel | Ordering::SeqCst => panic!(),
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
+   |
+   = help: or try changing either arm body
+note: `_` wildcard arm here
+  --> $DIR/match_same_arms_non_exhaustive.rs:55:13
+   |
+LL |             _ => panic!(),
+   |             ^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+