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:
commit
cda13a8b26
@ -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) {
|
||||
|
@ -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
|
||||
|
58
tests/ui/match_same_arms_non_exhaustive.rs
Normal file
58
tests/ui/match_same_arms_non_exhaustive.rs
Normal 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!(),
|
||||
}
|
||||
}
|
||||
}
|
29
tests/ui/match_same_arms_non_exhaustive.stderr
Normal file
29
tests/ui/match_same_arms_non_exhaustive.stderr
Normal 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user