Skip to content

Commit

Permalink
[match_same_arms]: don't lint if non_exhaustive_omitted_patterns
Browse files Browse the repository at this point in the history
formatting :/
  • Loading branch information
Centri3 committed Jun 14, 2023
1 parent 72332b2 commit 27a701a
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 12 deletions.
29 changes: 17 additions & 12 deletions clippy_lints/src/matches/match_same_arms.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions clippy_lints/src/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
58 changes: 58 additions & 0 deletions tests/ui/match_same_arms_non_exhaustive.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 29 additions & 0 deletions tests/ui/match_same_arms_non_exhaustive.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 27a701a

Please sign in to comment.