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`
This commit is contained in:
bors 2023-06-15 18:40:49 +00:00
commit cda13a8b26
4 changed files with 107 additions and 12 deletions

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet; 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::cmp::Ordering;
use core::iter; use core::iter;
use core::slice; use core::slice;
@ -9,6 +9,7 @@ use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatKind, RangeEnd}; 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_lint::LateContext;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::Symbol; 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(); let indexed_arms: Vec<(usize, &Arm<'_>)> = arms.iter().enumerate().collect();
for (&(i, arm1), &(j, arm2)) in search_same(&indexed_arms, hash, eq) { for (&(i, arm1), &(j, arm2)) in search_same(&indexed_arms, hash, eq) {
if matches!(arm2.pat.kind, PatKind::Wild) { if matches!(arm2.pat.kind, PatKind::Wild) {
span_lint_and_then( if !cx.tcx.features().non_exhaustive_omitted_patterns_lint
cx, || is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, arm2.hir_id)
MATCH_SAME_ARMS, {
arm1.span, span_lint_and_then(
"this match arm has an identical body to the `_` wildcard arm", cx,
|diag| { MATCH_SAME_ARMS,
diag.span_suggestion(arm1.span, "try removing the arm", "", Applicability::MaybeIncorrect) arm1.span,
.help("or try changing either arm body") "this match arm has an identical body to the `_` wildcard arm",
.span_note(arm2.span, "`_` wildcard arm here"); |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 { } else {
let back_block = backwards_blocking_idxs[j]; let back_block = backwards_blocking_idxs[j];
let (keep_arm, move_arm) = if back_block < i || (back_block == 0 && forwards_blocking_idxs[i] <= j) { let (keep_arm, move_arm) = if back_block < i || (back_block == 0 && forwards_blocking_idxs[i] <= j) {

View File

@ -559,6 +559,9 @@ declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for `match` with identical arm bodies. /// 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? /// ### Why is this bad?
/// This is probably a copy & paste error. If arm bodies /// This is probably a copy & paste error. If arm bodies
/// are the same on purpose, you can factor them /// are the same on purpose, you can factor them

View File

@ -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!(),
}
}
}

View File

@ -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