match_same_arms, ifs_same_cond: lint once per same arm/condition

This commit is contained in:
Alex Macleod 2025-04-16 21:22:07 +00:00
parent 8eed35023f
commit 39ab00a3a1
18 changed files with 747 additions and 399 deletions

View file

@ -1,5 +1,5 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then};
use clippy_utils::diagnostics::{span_lint, span_lint_and_note, span_lint_and_then};
use clippy_utils::source::{IntoSpan, SpanRangeExt, first_line_of_span, indent_of, reindent_multiline, snippet};
use clippy_utils::ty::{InteriorMut, needs_ordered_drop};
use clippy_utils::visitors::for_each_expr_without_closures;
@ -567,7 +567,7 @@ fn method_caller_is_mutable<'tcx>(
/// Implementation of `IFS_SAME_COND`.
fn lint_same_cond<'tcx>(cx: &LateContext<'tcx>, conds: &[&Expr<'_>], interior_mut: &mut InteriorMut<'tcx>) {
for (i, j) in search_same(
for group in search_same(
conds,
|e| hash_expr(cx, e),
|lhs, rhs| {
@ -584,14 +584,8 @@ fn lint_same_cond<'tcx>(cx: &LateContext<'tcx>, conds: &[&Expr<'_>], interior_mu
}
},
) {
span_lint_and_note(
cx,
IFS_SAME_COND,
j.span,
"this `if` has the same condition as a previous `if`",
Some(i.span),
"same as this",
);
let spans: Vec<_> = group.into_iter().map(|expr| expr.span).collect();
span_lint(cx, IFS_SAME_COND, spans, "these `if` branches have the same condition");
}
}
@ -609,14 +603,13 @@ fn lint_same_fns_in_if_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) {
SpanlessEq::new(cx).eq_expr(lhs, rhs)
};
for (i, j) in search_same(conds, |e| hash_expr(cx, e), eq) {
span_lint_and_note(
for group in search_same(conds, |e| hash_expr(cx, e), eq) {
let spans: Vec<_> = group.into_iter().map(|expr| expr.span).collect();
span_lint(
cx,
SAME_FUNCTIONS_IN_IF_CONDITION,
j.span,
"this `if` has the same function call as a previous `if`",
Some(i.span),
"same as this",
spans,
"these `if` branches have the same function call",
);
}
}

View file

@ -1,8 +1,9 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{SpanlessEq, SpanlessHash, is_lint_allowed, path_to_local, search_same};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::{SpanlessEq, SpanlessHash, fulfill_or_allowed, is_lint_allowed, path_to_local, search_same};
use core::cmp::Ordering;
use core::{iter, slice};
use itertools::Itertools;
use rustc_arena::DroplessArena;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
@ -110,57 +111,68 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
&& check_same_body()
};
let mut appl = Applicability::MaybeIncorrect;
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) {
if !cx.tcx.features().non_exhaustive_omitted_patterns_lint()
|| is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, arm2.hir_id)
{
let arm_span = adjusted_arm_span(cx, arm1.span);
span_lint_hir_and_then(
cx,
MATCH_SAME_ARMS,
arm1.hir_id,
arm_span,
"this match arm has an identical body to the `_` wildcard arm",
|diag| {
diag.span_suggestion(arm_span, "try removing the arm", "", appl)
.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) {
(arm1, arm2)
} else {
(arm2, arm1)
};
for mut group in search_same(&indexed_arms, hash, eq) {
// Filter out (and fulfill) `#[allow]`ed and `#[expect]`ed arms
group.retain(|(_, arm)| !fulfill_or_allowed(cx, MATCH_SAME_ARMS, [arm.hir_id]));
span_lint_hir_and_then(
cx,
MATCH_SAME_ARMS,
keep_arm.hir_id,
keep_arm.span,
"this match arm has an identical body to another arm",
|diag| {
let move_pat_snip = snippet_with_applicability(cx, move_arm.pat.span, "<pat2>", &mut appl);
let keep_pat_snip = snippet_with_applicability(cx, keep_arm.pat.span, "<pat1>", &mut appl);
diag.multipart_suggestion(
"or try merging the arm patterns and removing the obsolete arm",
vec![
(keep_arm.pat.span, format!("{keep_pat_snip} | {move_pat_snip}")),
(adjusted_arm_span(cx, move_arm.span), String::new()),
],
appl,
)
.help("try changing either arm body");
},
);
if group.len() < 2 {
continue;
}
span_lint_and_then(
cx,
MATCH_SAME_ARMS,
group.iter().map(|(_, arm)| arm.span).collect_vec(),
"these match arms have identical bodies",
|diag| {
diag.help("if this is unintentional make the arms return different values");
if let [prev @ .., (_, last)] = group.as_slice()
&& is_wildcard_arm(last.pat)
&& is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, last.hir_id)
{
diag.span_label(last.span, "the wildcard arm");
let s = if prev.len() > 1 { "s" } else { "" };
diag.multipart_suggestion_verbose(
format!("otherwise remove the non-wildcard arm{s}"),
prev.iter()
.map(|(_, arm)| (adjusted_arm_span(cx, arm.span), String::new()))
.collect(),
Applicability::MaybeIncorrect,
);
} else if let &[&(first_idx, _), .., &(last_idx, _)] = group.as_slice() {
let back_block = backwards_blocking_idxs[last_idx];
let split = if back_block < first_idx
|| (back_block == 0 && forwards_blocking_idxs[first_idx] <= last_idx)
{
group.split_first()
} else {
group.split_last()
};
if let Some(((_, dest), src)) = split
&& let Some(pat_snippets) = group
.iter()
.map(|(_, arm)| arm.pat.span.get_source_text(cx))
.collect::<Option<Vec<_>>>()
{
let mut suggs = src
.iter()
.map(|(_, arm)| (adjusted_arm_span(cx, arm.span), String::new()))
.collect_vec();
suggs.push((dest.pat.span, pat_snippets.iter().join(" | ")));
diag.multipart_suggestion_verbose(
"otherwise merge the patterns into a single arm",
suggs,
Applicability::MaybeIncorrect,
);
}
}
},
);
}
}
@ -449,3 +461,11 @@ fn bindings_eq(pat: &Pat<'_>, mut ids: HirIdSet) -> bool {
pat.each_binding_or_first(&mut |_, id, _, _| result &= ids.swap_remove(&id));
result && ids.is_empty()
}
fn is_wildcard_arm(pat: &Pat<'_>) -> bool {
match pat.kind {
PatKind::Wild => true,
PatKind::Or([.., last]) => matches!(last.kind, PatKind::Wild),
_ => false,
}
}

View file

@ -27,6 +27,7 @@
// FIXME: switch to something more ergonomic here, once available.
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
extern crate indexmap;
extern crate rustc_abi;
extern crate rustc_ast;
extern crate rustc_attr_parsing;
@ -85,7 +86,6 @@ pub use self::hir_utils::{
use core::mem;
use core::ops::ControlFlow;
use std::collections::hash_map::Entry;
use std::hash::BuildHasherDefault;
use std::iter::{once, repeat_n};
use std::sync::{Mutex, MutexGuard, OnceLock};
@ -95,7 +95,7 @@ use rustc_ast::ast::{self, LitKind, RangeLimits};
use rustc_attr_parsing::{AttributeKind, find_attr};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::packed::Pu128;
use rustc_data_structures::unhash::UnhashMap;
use rustc_data_structures::unhash::UnindexMap;
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
@ -2486,45 +2486,46 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<S
None
}
/// Returns list of all pairs `(a, b)` where `eq(a, b) == true`
/// and `a` is before `b` in `exprs` for all `a` and `b` in
/// `exprs`
/// Returns a list of groups where elements in each group are equal according to `eq`
///
/// - Within each group the elements are sorted by the order they appear in `exprs`
/// - The groups themselves are sorted by their first element's appearence in `exprs`
///
/// Given functions `eq` and `hash` such that `eq(a, b) == true`
/// implies `hash(a) == hash(b)`
pub fn search_same<T, Hash, Eq>(exprs: &[T], mut hash: Hash, mut eq: Eq) -> Vec<(&T, &T)>
pub fn search_same<T, Hash, Eq>(exprs: &[T], mut hash: Hash, mut eq: Eq) -> Vec<Vec<&T>>
where
Hash: FnMut(&T) -> u64,
Eq: FnMut(&T, &T) -> bool,
{
match exprs {
[a, b] if eq(a, b) => return vec![(a, b)],
[a, b] if eq(a, b) => return vec![vec![a, b]],
_ if exprs.len() <= 2 => return vec![],
_ => {},
}
let mut match_expr_list: Vec<(&T, &T)> = Vec::new();
let mut map: UnhashMap<u64, Vec<&_>> =
UnhashMap::with_capacity_and_hasher(exprs.len(), BuildHasherDefault::default());
let mut buckets: UnindexMap<u64, Vec<Vec<&T>>> = UnindexMap::default();
for expr in exprs {
match map.entry(hash(expr)) {
Entry::Occupied(mut o) => {
for o in o.get() {
if eq(o, expr) {
match_expr_list.push((o, expr));
}
match buckets.entry(hash(expr)) {
indexmap::map::Entry::Occupied(mut o) => {
let bucket = o.get_mut();
match bucket.iter_mut().find(|group| eq(expr, group[0])) {
Some(group) => group.push(expr),
None => bucket.push(vec![expr]),
}
o.get_mut().push(expr);
},
Entry::Vacant(v) => {
v.insert(vec![expr]);
indexmap::map::Entry::Vacant(v) => {
v.insert(vec![vec![expr]]);
},
}
}
match_expr_list
buckets
.into_values()
.flatten()
.filter(|group| group.len() > 1)
.collect()
}
/// Peels off all references on the pattern. Returns the underlying pattern and the number of

View file

@ -11,9 +11,9 @@ fn issue10272() {
// should trigger warning
let x = Cell::new(true);
if x.get() {
//~^ ifs_same_cond
} else if !x.take() {
} else if x.get() {
//~^ ifs_same_cond
} else {
}
}

View file

@ -1,14 +1,12 @@
error: this `if` has the same condition as a previous `if`
--> tests/ui-toml/ifs_same_cond/ifs_same_cond.rs:15:15
|
LL | } else if x.get() {
| ^^^^^^^
|
note: same as this
error: these `if` branches have the same condition
--> tests/ui-toml/ifs_same_cond/ifs_same_cond.rs:13:8
|
LL | if x.get() {
| ^^^^^^^
...
LL | } else if x.get() {
| ^^^^^^^
|
= note: `-D clippy::ifs-same-cond` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]`

View file

@ -6,19 +6,25 @@ fn ifs_same_cond() {
let b = false;
if b {
} else if b {
//~^ ifs_same_cond
} else if b {
}
if b {
//~^ ifs_same_cond
} else if b {
} else if b {
}
if a == 1 {
} else if a == 1 {
//~^ ifs_same_cond
} else if a == 1 {
}
if 2 * a == 1 {
//~^ ifs_same_cond
} else if 2 * a == 2 {
} else if 2 * a == 1 {
//~^ ifs_same_cond
} else if a == 1 {
}
@ -50,8 +56,8 @@ fn ifs_same_cond() {
fn issue10272() {
let a = String::from("ha");
if a.contains("ah") {
} else if a.contains("ah") {
//~^ ifs_same_cond
} else if a.contains("ah") {
// Trigger this lint
} else if a.contains("ha") {

View file

@ -1,52 +1,52 @@
error: this `if` has the same condition as a previous `if`
--> tests/ui/ifs_same_cond.rs:9:15
|
LL | } else if b {
| ^
|
note: same as this
error: these `if` branches have the same condition
--> tests/ui/ifs_same_cond.rs:8:8
|
LL | if b {
| ^
LL |
LL | } else if b {
| ^
|
= note: `-D clippy::ifs-same-cond` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]`
error: this `if` has the same condition as a previous `if`
--> tests/ui/ifs_same_cond.rs:14:15
|
LL | } else if a == 1 {
| ^^^^^^
|
note: same as this
error: these `if` branches have the same condition
--> tests/ui/ifs_same_cond.rs:13:8
|
LL | if b {
| ^
LL |
LL | } else if b {
| ^
LL | } else if b {
| ^
error: these `if` branches have the same condition
--> tests/ui/ifs_same_cond.rs:19:8
|
LL | if a == 1 {
| ^^^^^^
LL |
LL | } else if a == 1 {
| ^^^^^^
error: this `if` has the same condition as a previous `if`
--> tests/ui/ifs_same_cond.rs:20:15
|
LL | } else if 2 * a == 1 {
| ^^^^^^^^^^
|
note: same as this
--> tests/ui/ifs_same_cond.rs:18:8
error: these `if` branches have the same condition
--> tests/ui/ifs_same_cond.rs:24:8
|
LL | if 2 * a == 1 {
| ^^^^^^^^^^
...
LL | } else if 2 * a == 1 {
| ^^^^^^^^^^
error: this `if` has the same condition as a previous `if`
--> tests/ui/ifs_same_cond.rs:53:15
|
LL | } else if a.contains("ah") {
| ^^^^^^^^^^^^^^^^
|
note: same as this
--> tests/ui/ifs_same_cond.rs:52:8
error: these `if` branches have the same condition
--> tests/ui/ifs_same_cond.rs:58:8
|
LL | if a.contains("ah") {
| ^^^^^^^^^^^^^^^^
LL |
LL | } else if a.contains("ah") {
| ^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
error: aborting due to 5 previous errors

View file

@ -0,0 +1,142 @@
#![allow(clippy::manual_range_patterns)]
#![warn(clippy::match_same_arms)]
pub enum Abc {
A,
B,
C,
}
fn match_same_arms() {
let _ = match Abc::A {
Abc::B => 1,
_ => 0,
//~^ match_same_arms
};
match 0 {
1 => 'a',
_ => 'b',
//~^ match_same_arms
};
match (1, 2, 3) {
(1, .., 3) | (.., 3) => 42,
//~^ match_same_arms
_ => 0,
};
let _ = match 42 {
//~^ match_same_arms
42 | 51 => 1,
41 | 52 => 2,
//~^ match_same_arms
_ => 0,
};
let _ = match 42 {
//~^ match_same_arms
1 | 2 | 3 => 2,
4 => 3,
_ => 0,
};
}
mod issue4244 {
#[derive(PartialEq, PartialOrd, Eq, Ord)]
pub enum CommandInfo {
BuiltIn { name: String, about: Option<String> },
External { name: String, path: std::path::PathBuf },
}
impl CommandInfo {
pub fn name(&self) -> String {
match self {
//~^ match_same_arms
CommandInfo::BuiltIn { name, .. } | CommandInfo::External { name, .. } => name.to_string(),
}
}
}
}
macro_rules! m {
(foo) => {};
(bar) => {};
}
macro_rules! foo {
() => {
1
};
}
macro_rules! bar {
() => {
1
};
}
fn main() {
let x = 0;
let _ = match 0 {
0 => {
m!(foo);
x
},
1 => {
m!(bar);
x
},
_ => 1,
};
let _ = match 0 {
0 => {
m!(foo);
0
},
1 => {
m!(bar);
0
},
_ => 1,
};
let _ = match 0 {
0 => {
let mut x = 0;
#[cfg(not_enabled)]
{
x = 5;
}
#[cfg(not(not_enabled))]
{
x = 6;
}
x
},
1 => {
let mut x = 0;
#[cfg(also_not_enabled)]
{
x = 5;
}
#[cfg(not(also_not_enabled))]
{
x = 6;
}
x
},
_ => 0,
};
let _ = match 0 {
0 => foo!(),
1 => bar!(),
_ => 1,
};
let _ = match 0 {
0 => cfg!(not_enabled),
1 => cfg!(also_not_enabled),
_ => false,
};
}

View file

@ -1,4 +1,4 @@
//@no-rustfix: overlapping suggestions
#![allow(clippy::manual_range_patterns)]
#![warn(clippy::match_same_arms)]
pub enum Abc {
@ -10,9 +10,17 @@ pub enum Abc {
fn match_same_arms() {
let _ = match Abc::A {
Abc::A => 0,
//~^ match_same_arms
Abc::B => 1,
_ => 0,
//~^ match_same_arms
};
match 0 {
1 => 'a',
2 => 'b',
3 => 'b',
_ => 'b',
//~^ match_same_arms
};
match (1, 2, 3) {
@ -24,8 +32,8 @@ fn match_same_arms() {
let _ = match 42 {
42 => 1,
51 => 1,
//~^ match_same_arms
51 => 1,
41 => 2,
//~^ match_same_arms
52 => 2,
@ -34,11 +42,9 @@ fn match_same_arms() {
let _ = match 42 {
1 => 2,
//~^ match_same_arms
2 => 2,
//~^ match_same_arms
//~| match_same_arms
3 => 2,
//~^ match_same_arms
4 => 3,
_ => 0,
};
@ -55,8 +61,8 @@ mod issue4244 {
pub fn name(&self) -> String {
match self {
CommandInfo::BuiltIn { name, .. } => name.to_string(),
CommandInfo::External { name, .. } => name.to_string(),
//~^ match_same_arms
CommandInfo::External { name, .. } => name.to_string(),
}
}
}

View file

@ -1,118 +1,121 @@
error: this match arm has an identical body to the `_` wildcard arm
error: these match arms have identical bodies
--> tests/ui/match_same_arms.rs:12:9
|
LL | / Abc::A => 0,
LL | |
| |________^ help: try removing the arm
|
= help: or try changing either arm body
note: `_` wildcard arm here
--> tests/ui/match_same_arms.rs:15:9
|
LL | Abc::A => 0,
| ^^^^^^^^^^^
LL | Abc::B => 1,
LL | _ => 0,
| ^^^^^^
| ^^^^^^ the wildcard arm
|
= help: if this is unintentional make the arms return different values
= note: `-D clippy::match-same-arms` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
help: otherwise remove the non-wildcard arm
|
LL - Abc::A => 0,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms.rs:19:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms.rs:20:9
|
LL | 2 => 'b',
| ^^^^^^^^
LL | 3 => 'b',
| ^^^^^^^^
LL | _ => 'b',
| ^^^^^^^^ the wildcard arm
|
= help: if this is unintentional make the arms return different values
help: otherwise remove the non-wildcard arms
|
LL - 2 => 'b',
LL - 3 => 'b',
LL + _ => 'b',
|
error: these match arms have identical bodies
--> tests/ui/match_same_arms.rs:27:9
|
LL | (1, .., 3) => 42,
| ^^^^^^^^^^^^^^^^
LL |
LL | (.., 3) => 42,
| ^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ (1, .., 3) | (.., 3) => 42,
LL |
LL ~ _ => 0,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms.rs:27:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms.rs:34:9
|
LL | 42 => 1,
| ^^^^^^^
LL |
LL | 51 => 1,
| ^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - 42 => 1,
LL - 51 => 1,
LL + 51 | 42 => 1,
LL ~
LL ~ 42 | 51 => 1,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms.rs:29:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms.rs:37:9
|
LL | 41 => 2,
| ^^^^^^^
LL |
LL | 52 => 2,
| ^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ 41 | 52 => 2,
LL |
LL ~ _ => 0,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms.rs:37:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms.rs:44:9
|
LL | 1 => 2,
| ^^^^^^
LL |
LL | 2 => 2,
| ^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
|
LL - 1 => 2,
LL - 2 => 2,
LL + 2 | 1 => 2,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms.rs:40:9
|
LL | 3 => 2,
| ^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ 2 => 2,
LL |
LL |
LL ~ 3 | 1 => 2,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms.rs:37:9
|
LL | 2 => 2,
| ^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
|
LL ~ 2 | 3 => 2,
LL |
LL |
LL ~
LL ~ 1 | 2 | 3 => 2,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms.rs:58:17
error: these match arms have identical bodies
--> tests/ui/match_same_arms.rs:63:17
|
LL | CommandInfo::BuiltIn { name, .. } => name.to_string(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | CommandInfo::External { name, .. } => name.to_string(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - CommandInfo::BuiltIn { name, .. } => name.to_string(),
LL - CommandInfo::External { name, .. } => name.to_string(),
LL + CommandInfo::External { name, .. } | CommandInfo::BuiltIn { name, .. } => name.to_string(),
LL ~
LL ~ CommandInfo::BuiltIn { name, .. } | CommandInfo::External { name, .. } => name.to_string(),
|
error: aborting due to 8 previous errors
error: aborting due to 7 previous errors

View file

@ -14,7 +14,7 @@ fn foo() -> bool {
fn match_same_arms() {
let _ = match 42 {
//~^^^^^^^^^ match_same_arms
//~v match_same_arms
_ => {
foo();
let mut a = 42 + [23].len() as i32;
@ -27,14 +27,14 @@ fn match_same_arms() {
};
let _ = match 42 {
51 | 42 => foo(),
//~^ match_same_arms
42 | 51 => foo(),
_ => true,
};
let _ = match Some(42) {
None | Some(_) => 24,
//~^ match_same_arms
Some(_) | None => 24,
};
let _ = match Some(42) {
@ -55,8 +55,8 @@ fn match_same_arms() {
};
match (Some(42), Some(42)) {
(None, Some(a)) | (Some(a), None) => bar(a),
//~^ match_same_arms
(Some(a), None) | (None, Some(a)) => bar(a),
_ => (),
}
@ -69,8 +69,8 @@ fn match_same_arms() {
};
let _ = match (Some(42), Some(42)) {
(None, Some(a)) | (Some(a), None) if a == 42 => a,
//~^ match_same_arms
(Some(a), None) | (None, Some(a)) if a == 42 => a,
_ => 0,
};
@ -124,8 +124,8 @@ fn match_same_arms() {
// False negative #2251.
match x {
Ok(_tmp) => println!("ok"),
Ok(_) | Ok(3) => println!("ok"),
//~^ match_same_arms
Ok(3) | Ok(_) => println!("ok"),
Err(_) => {
unreachable!();
},
@ -149,10 +149,10 @@ fn match_same_arms() {
// still lint if the tokens are the same
match 0 {
1 | 0 => {
//~^^^ match_same_arms
0 | 1 => {
empty!(0);
},
//~^^^ match_same_arms
x => {
empty!(x);
},
@ -208,9 +208,9 @@ fn main() {
// Suggest moving `Foo::X(0)` down.
let _ = match Foo::X(0) {
Foo::Y(_) | Foo::Z(0) => 2,
Foo::Z(_) | Foo::X(0) => 1,
//~^ match_same_arms
Foo::Y(_) | Foo::Z(0) => 2,
Foo::X(0) | Foo::Z(_) => 1,
_ => 0,
};
@ -230,10 +230,10 @@ fn main() {
// Lint.
let _ = match None {
//~^ match_same_arms
Some(Bar { y: 10, z: 0, .. }) => 2,
None => 50,
Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1,
//~^ match_same_arms
Some(Bar { x: 0, y: 5, .. }) | Some(Bar { y: 0, x: 5, .. }) => 1,
_ => 200,
};
@ -246,8 +246,8 @@ fn main() {
};
let _ = match 0 {
1 | 0 => cfg!(not_enable),
//~^ match_same_arms
0 | 1 => cfg!(not_enable),
_ => false,
};
}
@ -262,9 +262,34 @@ mod with_lifetime {
impl<'a> MaybeStaticStr<'a> {
fn get(&self) -> &'a str {
match *self {
MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
//~^ match_same_arms
MaybeStaticStr::Static(s) | MaybeStaticStr::Borrowed(s) => s,
}
}
}
}
fn lint_levels() {
match 1 {
0 => "a",
1 => "b",
#[expect(clippy::match_same_arms)]
_ => "b",
};
match 2 {
0 => "a",
1 | 2 => "b",
//~^ match_same_arms
#[allow(clippy::match_same_arms)]
_ => "b",
};
match 3 {
0 => "a",
1 | 2 => "b",
//~^ match_same_arms
#[expect(clippy::match_same_arms)]
_ => "b",
};
}

View file

@ -23,7 +23,7 @@ fn match_same_arms() {
a = -31 - a;
a
},
//~^^^^^^^^^ match_same_arms
//~v match_same_arms
_ => {
foo();
let mut a = 42 + [23].len() as i32;
@ -37,15 +37,15 @@ fn match_same_arms() {
let _ = match 42 {
42 => foo(),
51 => foo(),
//~^ match_same_arms
51 => foo(),
_ => true,
};
let _ = match Some(42) {
Some(_) => 24,
None => 24,
//~^ match_same_arms
None => 24,
};
let _ = match Some(42) {
@ -67,8 +67,8 @@ fn match_same_arms() {
match (Some(42), Some(42)) {
(Some(a), None) => bar(a),
(None, Some(a)) => bar(a),
//~^ match_same_arms
(None, Some(a)) => bar(a),
_ => (),
}
@ -82,8 +82,8 @@ fn match_same_arms() {
let _ = match (Some(42), Some(42)) {
(Some(a), None) if a == 42 => a,
(None, Some(a)) if a == 42 => a,
//~^ match_same_arms
(None, Some(a)) if a == 42 => a,
_ => 0,
};
@ -140,8 +140,8 @@ fn match_same_arms() {
match x {
Ok(_tmp) => println!("ok"),
Ok(3) => println!("ok"),
Ok(_) => println!("ok"),
//~^ match_same_arms
Ok(_) => println!("ok"),
Err(_) => {
unreachable!();
},
@ -168,10 +168,10 @@ fn match_same_arms() {
0 => {
empty!(0);
},
//~^^^ match_same_arms
1 => {
empty!(0);
},
//~^^^ match_same_arms
x => {
empty!(x);
},
@ -229,9 +229,9 @@ fn main() {
// Suggest moving `Foo::X(0)` down.
let _ = match Foo::X(0) {
Foo::X(0) => 1,
//~^ match_same_arms
Foo::Y(_) | Foo::Z(0) => 2,
Foo::Z(_) => 1,
//~^ match_same_arms
_ => 0,
};
@ -252,10 +252,10 @@ fn main() {
// Lint.
let _ = match None {
Some(Bar { x: 0, y: 5, .. }) => 1,
//~^ match_same_arms
Some(Bar { y: 10, z: 0, .. }) => 2,
None => 50,
Some(Bar { y: 0, x: 5, .. }) => 1,
//~^ match_same_arms
_ => 200,
};
@ -269,8 +269,8 @@ fn main() {
let _ = match 0 {
0 => cfg!(not_enable),
1 => cfg!(not_enable),
//~^ match_same_arms
1 => cfg!(not_enable),
_ => false,
};
}
@ -286,9 +286,36 @@ mod with_lifetime {
fn get(&self) -> &'a str {
match *self {
MaybeStaticStr::Static(s) => s,
MaybeStaticStr::Borrowed(s) => s,
//~^ match_same_arms
MaybeStaticStr::Borrowed(s) => s,
}
}
}
}
fn lint_levels() {
match 1 {
0 => "a",
1 => "b",
#[expect(clippy::match_same_arms)]
_ => "b",
};
match 2 {
0 => "a",
1 => "b",
//~^ match_same_arms
2 => "b",
#[allow(clippy::match_same_arms)]
_ => "b",
};
match 3 {
0 => "a",
1 => "b",
//~^ match_same_arms
2 => "b",
#[expect(clippy::match_same_arms)]
_ => "b",
};
}

View file

@ -1,4 +1,4 @@
error: this match arm has an identical body to the `_` wildcard arm
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:17:9
|
LL | / 42 => {
@ -6,14 +6,10 @@ LL | | foo();
LL | | let mut a = 42 + [23].len() as i32;
LL | | if true {
... |
LL | | a
LL | | },
LL | |
| |________^ help: try removing the arm
|
= help: or try changing either arm body
note: `_` wildcard arm here
--> tests/ui/match_same_arms2.rs:27:9
|
| |_________^
LL |
LL | / _ => {
LL | | foo();
LL | | let mut a = 42 + [23].len() as i32;
@ -21,134 +17,169 @@ LL | | if true {
... |
LL | | a
LL | | },
| |_________^
| |_________^ the wildcard arm
|
= help: if this is unintentional make the arms return different values
= note: `-D clippy::match-same-arms` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:40:9
help: otherwise remove the non-wildcard arm
|
LL - 42 => {
LL - foo();
LL - let mut a = 42 + [23].len() as i32;
LL - if true {
LL - a += 7;
LL - }
LL - a = -31 - a;
LL - a
LL - },
|
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:39:9
|
LL | 42 => foo(),
| ^^^^^^^^^^^
LL |
LL | 51 => foo(),
| ^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - 42 => foo(),
LL - 51 => foo(),
LL + 51 | 42 => foo(),
LL ~
LL ~ 42 | 51 => foo(),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:47:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:46:9
|
LL | Some(_) => 24,
| ^^^^^^^^^^^^^
LL |
LL | None => 24,
| ^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - Some(_) => 24,
LL - None => 24,
LL + None | Some(_) => 24,
LL ~
LL ~ Some(_) | None => 24,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:70:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:69:9
|
LL | (Some(a), None) => bar(a),
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | (None, Some(a)) => bar(a),
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - (Some(a), None) => bar(a),
LL - (None, Some(a)) => bar(a),
LL + (None, Some(a)) | (Some(a), None) => bar(a),
LL ~
LL ~ (Some(a), None) | (None, Some(a)) => bar(a),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:85:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:84:9
|
LL | (Some(a), None) if a == 42 => a,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | (None, Some(a)) if a == 42 => a,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - (Some(a), None) if a == 42 => a,
LL - (None, Some(a)) if a == 42 => a,
LL + (None, Some(a)) | (Some(a), None) if a == 42 => a,
LL ~
LL ~ (Some(a), None) | (None, Some(a)) if a == 42 => a,
|
error: this match arm has an identical body to another arm
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:91:9
|
LL | (Some(a), ..) => bar(a),
| ^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | (.., Some(a)) => bar(a),
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ (Some(a), ..) | (.., Some(a)) => bar(a),
LL |
LL ~ _ => (),
|
error: this match arm has an identical body to another arm
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:126:9
|
LL | (Ok(x), Some(_)) => println!("ok {}", x),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | (Ok(_), Some(x)) => println!("ok {}", x),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x),
LL |
LL ~ _ => println!("err"),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:143:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:142:9
|
LL | Ok(3) => println!("ok"),
| ^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | Ok(_) => println!("ok"),
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - Ok(3) => println!("ok"),
LL - Ok(_) => println!("ok"),
LL + Ok(_) | Ok(3) => println!("ok"),
LL ~
LL ~ Ok(3) | Ok(_) => println!("ok"),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:171:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:168:9
|
LL | / 0 => {
LL | | empty!(0);
LL | | },
| |_________^
LL |
LL | / 1 => {
LL | | empty!(0);
LL | | },
| |_________^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - 0 => {
LL - empty!(0);
LL - },
LL - 1 => {
LL + 1 | 0 => {
LL ~
LL ~ 0 | 1 => {
|
error: this match arm has an identical body to another arm
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:222:9
|
LL | Foo::X(0) => 1,
| ^^^^^^^^^^^^^^
...
LL | Foo::Z(_) => 1,
| ^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ Foo::X(0) | Foo::Z(_) => 1,
LL |
@ -156,60 +187,106 @@ LL | Foo::X(_) | Foo::Y(_) => 2,
LL ~ _ => 0,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:233:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:231:9
|
LL | Foo::X(0) => 1,
| ^^^^^^^^^^^^^^
...
LL | Foo::Z(_) => 1,
| ^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ Foo::Y(_) | Foo::Z(0) => 2,
LL ~ Foo::Z(_) | Foo::X(0) => 1,
LL ~
LL | Foo::Y(_) | Foo::Z(0) => 2,
LL ~ Foo::X(0) | Foo::Z(_) => 1,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:257:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:254:9
|
LL | Some(Bar { x: 0, y: 5, .. }) => 1,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | Some(Bar { y: 0, x: 5, .. }) => 1,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ Some(Bar { y: 10, z: 0, .. }) => 2,
LL ~
LL | Some(Bar { y: 10, z: 0, .. }) => 2,
LL | None => 50,
LL ~ Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1,
LL ~ Some(Bar { x: 0, y: 5, .. }) | Some(Bar { y: 0, x: 5, .. }) => 1,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:272:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:271:9
|
LL | 0 => cfg!(not_enable),
| ^^^^^^^^^^^^^^^^^^^^^
LL |
LL | 1 => cfg!(not_enable),
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - 0 => cfg!(not_enable),
LL - 1 => cfg!(not_enable),
LL + 1 | 0 => cfg!(not_enable),
LL ~
LL ~ 0 | 1 => cfg!(not_enable),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:289:17
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:288:17
|
LL | MaybeStaticStr::Static(s) => s,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | MaybeStaticStr::Borrowed(s) => s,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns and removing the obsolete arm
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL - MaybeStaticStr::Static(s) => s,
LL - MaybeStaticStr::Borrowed(s) => s,
LL + MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
LL ~
LL ~ MaybeStaticStr::Static(s) | MaybeStaticStr::Borrowed(s) => s,
|
error: aborting due to 14 previous errors
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:306:9
|
LL | 1 => "b",
| ^^^^^^^^
LL |
LL | 2 => "b",
| ^^^^^^^^
|
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ 1 | 2 => "b",
LL |
LL ~ #[allow(clippy::match_same_arms)]
|
error: these match arms have identical bodies
--> tests/ui/match_same_arms2.rs:315:9
|
LL | 1 => "b",
| ^^^^^^^^
LL |
LL | 2 => "b",
| ^^^^^^^^
|
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~ 1 | 2 => "b",
LL |
LL ~ #[expect(clippy::match_same_arms)]
|
error: aborting due to 16 previous errors

View file

@ -7,14 +7,22 @@ fn repeat() -> ! {
panic!()
}
#[deny(non_exhaustive_omitted_patterns)]
pub fn f(x: Ordering) {
#[deny(non_exhaustive_omitted_patterns)]
match x {
Ordering::Relaxed => println!("relaxed"),
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel | Ordering::SeqCst => repeat(),
_ => repeat(),
//~^ match_same_arms
Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),
}
match x {
Ordering::Relaxed => println!("relaxed"),
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
//~^ match_same_arms
Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),
}
}
@ -28,21 +36,21 @@ mod f {
Ordering::Relaxed => println!("relaxed"),
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel | Ordering::SeqCst => repeat(),
_ => repeat(),
//~^ match_same_arms
Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),
}
}
}
// Below should still lint
// Below can still suggest removing the other patterns
pub fn g(x: Ordering) {
match x {
Ordering::Relaxed => println!("relaxed"),
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
//~^ match_same_arms
_ => repeat(),
//~^ match_same_arms
}
}
@ -54,8 +62,8 @@ mod g {
Ordering::Relaxed => println!("relaxed"),
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
//~^ match_same_arms
_ => repeat(),
//~^ match_same_arms
}
}
}

View file

@ -7,15 +7,25 @@ fn repeat() -> ! {
panic!()
}
#[deny(non_exhaustive_omitted_patterns)]
pub fn f(x: Ordering) {
#[deny(non_exhaustive_omitted_patterns)]
match x {
Ordering::Relaxed => println!("relaxed"),
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel | Ordering::SeqCst => repeat(),
//~^ match_same_arms
_ => repeat(),
}
match x {
Ordering::Relaxed => println!("relaxed"),
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel => repeat(),
//~^ match_same_arms
Ordering::SeqCst | _ => repeat(),
}
}
mod f {
@ -29,12 +39,13 @@ mod f {
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel | Ordering::SeqCst => repeat(),
//~^ match_same_arms
_ => repeat(),
}
}
}
// Below should still lint
// Below can still suggest removing the other patterns
pub fn g(x: Ordering) {
match x {
@ -42,8 +53,8 @@ pub fn g(x: Ordering) {
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel | Ordering::SeqCst => repeat(),
//~^ match_same_arms
_ => repeat(),
//~^ match_same_arms
}
}
@ -56,8 +67,8 @@ mod g {
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel | Ordering::SeqCst => repeat(),
//~^ match_same_arms
_ => repeat(),
//~^ match_same_arms
}
}
}

View file

@ -1,32 +1,80 @@
error: this match arm has an identical body to the `_` wildcard arm
--> tests/ui/match_same_arms_non_exhaustive.rs:44:9
|
LL | / Ordering::AcqRel | Ordering::SeqCst => repeat(),
LL | |
| |________^ help: try removing the arm
|
= help: or try changing either arm body
note: `_` wildcard arm here
--> tests/ui/match_same_arms_non_exhaustive.rs:46:9
error: these match arms have identical bodies
--> tests/ui/match_same_arms_non_exhaustive.rs:16:9
|
LL | Ordering::AcqRel | Ordering::SeqCst => repeat(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | _ => repeat(),
| ^^^^^^^^^^^^^
|
= help: if this is unintentional make the arms return different values
= note: `-D clippy::match-same-arms` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
help: otherwise merge the patterns into a single arm
|
LL ~
LL ~ Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),
|
error: this match arm has an identical body to the `_` wildcard arm
--> tests/ui/match_same_arms_non_exhaustive.rs:58:13
error: these match arms have identical bodies
--> tests/ui/match_same_arms_non_exhaustive.rs:25:9
|
LL | / Ordering::AcqRel | Ordering::SeqCst => repeat(),
LL | |
| |____________^ help: try removing the arm
LL | Ordering::AcqRel => repeat(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | Ordering::SeqCst | _ => repeat(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: or try changing either arm body
note: `_` wildcard arm here
--> tests/ui/match_same_arms_non_exhaustive.rs:60:13
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~
LL ~ Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),
|
error: these match arms have identical bodies
--> tests/ui/match_same_arms_non_exhaustive.rs:41:13
|
LL | Ordering::AcqRel | Ordering::SeqCst => repeat(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | _ => repeat(),
| ^^^^^^^^^^^^^
|
= help: if this is unintentional make the arms return different values
help: otherwise merge the patterns into a single arm
|
LL ~
LL ~ Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),
|
error: aborting due to 2 previous errors
error: these match arms have identical bodies
--> tests/ui/match_same_arms_non_exhaustive.rs:55:9
|
LL | Ordering::AcqRel | Ordering::SeqCst => repeat(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | _ => repeat(),
| ^^^^^^^^^^^^^ the wildcard arm
|
= help: if this is unintentional make the arms return different values
help: otherwise remove the non-wildcard arm
|
LL - Ordering::AcqRel | Ordering::SeqCst => repeat(),
|
error: these match arms have identical bodies
--> tests/ui/match_same_arms_non_exhaustive.rs:69:13
|
LL | Ordering::AcqRel | Ordering::SeqCst => repeat(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | _ => repeat(),
| ^^^^^^^^^^^^^ the wildcard arm
|
= help: if this is unintentional make the arms return different values
help: otherwise remove the non-wildcard arm
|
LL - Ordering::AcqRel | Ordering::SeqCst => repeat(),
|
error: aborting due to 5 previous errors

View file

@ -31,34 +31,34 @@ fn ifs_same_cond_fn() {
let obj = Struct;
if function() {
} else if function() {
//~^ same_functions_in_if_condition
} else if function() {
}
if fn_arg(a) {
} else if fn_arg(a) {
//~^ same_functions_in_if_condition
} else if fn_arg(a) {
}
if obj.method() {
} else if obj.method() {
//~^ same_functions_in_if_condition
} else if obj.method() {
}
if obj.method_arg(a) {
} else if obj.method_arg(a) {
//~^ same_functions_in_if_condition
} else if obj.method_arg(a) {
}
let mut v = vec![1];
if v.pop().is_none() {
} else if v.pop().is_none() {
//~^ same_functions_in_if_condition
} else if v.pop().is_none() {
}
if v.len() == 42 {
} else if v.len() == 42 {
//~^ same_functions_in_if_condition
} else if v.len() == 42 {
}
if v.len() == 1 {

View file

@ -1,79 +1,62 @@
error: this `if` has the same function call as a previous `if`
--> tests/ui/same_functions_in_if_condition.rs:34:15
|
LL | } else if function() {
| ^^^^^^^^^^
|
note: same as this
error: these `if` branches have the same function call
--> tests/ui/same_functions_in_if_condition.rs:33:8
|
LL | if function() {
| ^^^^^^^^^^
LL |
LL | } else if function() {
| ^^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui/same_functions_in_if_condition.rs:2:9
|
LL | #![deny(clippy::same_functions_in_if_condition)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> tests/ui/same_functions_in_if_condition.rs:39:15
|
LL | } else if fn_arg(a) {
| ^^^^^^^^^
|
note: same as this
error: these `if` branches have the same function call
--> tests/ui/same_functions_in_if_condition.rs:38:8
|
LL | if fn_arg(a) {
| ^^^^^^^^^
LL |
LL | } else if fn_arg(a) {
| ^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> tests/ui/same_functions_in_if_condition.rs:44:15
|
LL | } else if obj.method() {
| ^^^^^^^^^^^^
|
note: same as this
error: these `if` branches have the same function call
--> tests/ui/same_functions_in_if_condition.rs:43:8
|
LL | if obj.method() {
| ^^^^^^^^^^^^
LL |
LL | } else if obj.method() {
| ^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> tests/ui/same_functions_in_if_condition.rs:49:15
|
LL | } else if obj.method_arg(a) {
| ^^^^^^^^^^^^^^^^^
|
note: same as this
error: these `if` branches have the same function call
--> tests/ui/same_functions_in_if_condition.rs:48:8
|
LL | if obj.method_arg(a) {
| ^^^^^^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> tests/ui/same_functions_in_if_condition.rs:55:15
|
LL | } else if v.pop().is_none() {
LL |
LL | } else if obj.method_arg(a) {
| ^^^^^^^^^^^^^^^^^
|
note: same as this
error: these `if` branches have the same function call
--> tests/ui/same_functions_in_if_condition.rs:54:8
|
LL | if v.pop().is_none() {
| ^^^^^^^^^^^^^^^^^
LL |
LL | } else if v.pop().is_none() {
| ^^^^^^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> tests/ui/same_functions_in_if_condition.rs:60:15
|
LL | } else if v.len() == 42 {
| ^^^^^^^^^^^^^
|
note: same as this
error: these `if` branches have the same function call
--> tests/ui/same_functions_in_if_condition.rs:59:8
|
LL | if v.len() == 42 {
| ^^^^^^^^^^^^^
LL |
LL | } else if v.len() == 42 {
| ^^^^^^^^^^^^^
error: aborting due to 6 previous errors