Skip to content

Commit cda13a8

Browse files
committed
Auto merge of #10946 - Centri3:match_same_arms, r=blyxyas,xFrednet
[`match_same_arms`]: don't lint if `non_exhaustive_omitted_patterns` Fixes #10327 changelog: [`match_same_arms`]: Don't lint if `non_exhaustive_omitted_patterns` is `warn` or `deny`
2 parents eee3112 + 27a701a commit cda13a8

File tree

4 files changed

+107
-12
lines changed

4 files changed

+107
-12
lines changed

clippy_lints/src/matches/match_same_arms.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::source::snippet;
3-
use clippy_utils::{path_to_local, search_same, SpanlessEq, SpanlessHash};
3+
use clippy_utils::{is_lint_allowed, path_to_local, search_same, SpanlessEq, SpanlessHash};
44
use core::cmp::Ordering;
55
use core::iter;
66
use core::slice;
@@ -9,6 +9,7 @@ use rustc_ast::ast::LitKind;
99
use rustc_errors::Applicability;
1010
use rustc_hir::def_id::DefId;
1111
use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatKind, RangeEnd};
12+
use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
1213
use rustc_lint::LateContext;
1314
use rustc_middle::ty;
1415
use rustc_span::Symbol;
@@ -103,17 +104,21 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
103104
let indexed_arms: Vec<(usize, &Arm<'_>)> = arms.iter().enumerate().collect();
104105
for (&(i, arm1), &(j, arm2)) in search_same(&indexed_arms, hash, eq) {
105106
if matches!(arm2.pat.kind, PatKind::Wild) {
106-
span_lint_and_then(
107-
cx,
108-
MATCH_SAME_ARMS,
109-
arm1.span,
110-
"this match arm has an identical body to the `_` wildcard arm",
111-
|diag| {
112-
diag.span_suggestion(arm1.span, "try removing the arm", "", Applicability::MaybeIncorrect)
113-
.help("or try changing either arm body")
114-
.span_note(arm2.span, "`_` wildcard arm here");
115-
},
116-
);
107+
if !cx.tcx.features().non_exhaustive_omitted_patterns_lint
108+
|| is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, arm2.hir_id)
109+
{
110+
span_lint_and_then(
111+
cx,
112+
MATCH_SAME_ARMS,
113+
arm1.span,
114+
"this match arm has an identical body to the `_` wildcard arm",
115+
|diag| {
116+
diag.span_suggestion(arm1.span, "try removing the arm", "", Applicability::MaybeIncorrect)
117+
.help("or try changing either arm body")
118+
.span_note(arm2.span, "`_` wildcard arm here");
119+
},
120+
);
121+
}
117122
} else {
118123
let back_block = backwards_blocking_idxs[j];
119124
let (keep_arm, move_arm) = if back_block < i || (back_block == 0 && forwards_blocking_idxs[i] <= j) {

clippy_lints/src/matches/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,9 @@ declare_clippy_lint! {
559559
/// ### What it does
560560
/// Checks for `match` with identical arm bodies.
561561
///
562+
/// Note: Does not lint on wildcards if the `non_exhaustive_omitted_patterns_lint` feature is
563+
/// enabled and disallowed.
564+
///
562565
/// ### Why is this bad?
563566
/// This is probably a copy & paste error. If arm bodies
564567
/// are the same on purpose, you can factor them
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#![feature(non_exhaustive_omitted_patterns_lint)]
2+
#![warn(clippy::match_same_arms)]
3+
#![no_main]
4+
5+
use std::sync::atomic::Ordering; // #[non_exhaustive] enum
6+
7+
pub fn f(x: Ordering) {
8+
match x {
9+
Ordering::Relaxed => println!("relaxed"),
10+
Ordering::Release => println!("release"),
11+
Ordering::Acquire => println!("acquire"),
12+
Ordering::AcqRel | Ordering::SeqCst => panic!(),
13+
#[deny(non_exhaustive_omitted_patterns)]
14+
_ => panic!(),
15+
}
16+
}
17+
18+
mod f {
19+
#![deny(non_exhaustive_omitted_patterns)]
20+
21+
use super::*;
22+
23+
pub fn f(x: Ordering) {
24+
match x {
25+
Ordering::Relaxed => println!("relaxed"),
26+
Ordering::Release => println!("release"),
27+
Ordering::Acquire => println!("acquire"),
28+
Ordering::AcqRel | Ordering::SeqCst => panic!(),
29+
_ => panic!(),
30+
}
31+
}
32+
}
33+
34+
// Below should still lint
35+
36+
pub fn g(x: Ordering) {
37+
match x {
38+
Ordering::Relaxed => println!("relaxed"),
39+
Ordering::Release => println!("release"),
40+
Ordering::Acquire => println!("acquire"),
41+
Ordering::AcqRel | Ordering::SeqCst => panic!(),
42+
_ => panic!(),
43+
}
44+
}
45+
46+
mod g {
47+
use super::*;
48+
49+
pub fn g(x: Ordering) {
50+
match x {
51+
Ordering::Relaxed => println!("relaxed"),
52+
Ordering::Release => println!("release"),
53+
Ordering::Acquire => println!("acquire"),
54+
Ordering::AcqRel | Ordering::SeqCst => panic!(),
55+
_ => panic!(),
56+
}
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error: this match arm has an identical body to the `_` wildcard arm
2+
--> $DIR/match_same_arms_non_exhaustive.rs:41:9
3+
|
4+
LL | Ordering::AcqRel | Ordering::SeqCst => panic!(),
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
6+
|
7+
= help: or try changing either arm body
8+
note: `_` wildcard arm here
9+
--> $DIR/match_same_arms_non_exhaustive.rs:42:9
10+
|
11+
LL | _ => panic!(),
12+
| ^^^^^^^^^^^^^
13+
= note: `-D clippy::match-same-arms` implied by `-D warnings`
14+
15+
error: this match arm has an identical body to the `_` wildcard arm
16+
--> $DIR/match_same_arms_non_exhaustive.rs:54:13
17+
|
18+
LL | Ordering::AcqRel | Ordering::SeqCst => panic!(),
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
20+
|
21+
= help: or try changing either arm body
22+
note: `_` wildcard arm here
23+
--> $DIR/match_same_arms_non_exhaustive.rs:55:13
24+
|
25+
LL | _ => panic!(),
26+
| ^^^^^^^^^^^^^
27+
28+
error: aborting due to 2 previous errors
29+

0 commit comments

Comments
 (0)