Skip to content

Commit febe549

Browse files
committed
Fix needless_match FP on if-lets
1 parent 1bdc08a commit febe549

File tree

4 files changed

+131
-3
lines changed

4 files changed

+131
-3
lines changed

clippy_lints/src/matches/needless_match.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::source::snippet_with_applicability;
44
use clippy_utils::ty::{is_type_diagnostic_item, same_type_and_consts};
55
use clippy_utils::{
6-
eq_expr_value, get_parent_expr_for_hir, higher, is_else_clause, is_res_lang_ctor, over, path_res,
6+
SpanlessEq, eq_expr_value, get_parent_expr_for_hir, higher, is_else_clause, is_res_lang_ctor, over, path_res,
77
peel_blocks_with_stmt,
88
};
99
use rustc_errors::Applicability;
@@ -90,7 +90,9 @@ fn check_if_let_inner(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool
9090
}
9191

9292
// Recursively check for each `else if let` phrase,
93-
if let Some(ref nested_if_let) = higher::IfLet::hir(cx, if_else) {
93+
if let Some(ref nested_if_let) = higher::IfLet::hir(cx, if_else)
94+
&& SpanlessEq::new(cx).eq_expr(nested_if_let.let_expr, if_let.let_expr)
95+
{
9496
return check_if_let_inner(cx, nested_if_let);
9597
}
9698

tests/ui/needless_match.fixed

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,57 @@ mod issue9084 {
245245
}
246246
}
247247

248+
fn a() -> Option<()> {
249+
Some(())
250+
}
251+
fn b() -> Option<()> {
252+
Some(())
253+
}
254+
fn c() -> Option<()> {
255+
Some(())
256+
}
257+
258+
#[allow(clippy::ifs_same_cond)]
259+
pub fn issue13574() -> Option<()> {
260+
// Do not lint.
261+
// The right hand of all these arms are different functions.
262+
let _ = {
263+
if let Some(a) = a() {
264+
Some(a)
265+
} else if let Some(b) = b() {
266+
Some(b)
267+
} else if let Some(c) = c() {
268+
Some(c)
269+
} else {
270+
None
271+
}
272+
};
273+
274+
const A: Option<()> = Some(());
275+
const B: Option<()> = Some(());
276+
const C: Option<()> = Some(());
277+
const D: Option<()> = Some(());
278+
279+
let _ = {
280+
if let Some(num) = A {
281+
Some(num)
282+
} else if let Some(num) = B {
283+
Some(num)
284+
} else if let Some(num) = C {
285+
Some(num)
286+
} else if let Some(num) = D {
287+
Some(num)
288+
} else {
289+
None
290+
}
291+
};
292+
293+
// Same const, should lint
294+
let _ = {
295+
A
296+
};
297+
298+
None
299+
}
300+
248301
fn main() {}

tests/ui/needless_match.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,65 @@ mod issue9084 {
289289
}
290290
}
291291

292+
fn a() -> Option<()> {
293+
Some(())
294+
}
295+
fn b() -> Option<()> {
296+
Some(())
297+
}
298+
fn c() -> Option<()> {
299+
Some(())
300+
}
301+
302+
#[allow(clippy::ifs_same_cond)]
303+
pub fn issue13574() -> Option<()> {
304+
// Do not lint.
305+
// The right hand of all these arms are different functions.
306+
let _ = {
307+
if let Some(a) = a() {
308+
Some(a)
309+
} else if let Some(b) = b() {
310+
Some(b)
311+
} else if let Some(c) = c() {
312+
Some(c)
313+
} else {
314+
None
315+
}
316+
};
317+
318+
const A: Option<()> = Some(());
319+
const B: Option<()> = Some(());
320+
const C: Option<()> = Some(());
321+
const D: Option<()> = Some(());
322+
323+
let _ = {
324+
if let Some(num) = A {
325+
Some(num)
326+
} else if let Some(num) = B {
327+
Some(num)
328+
} else if let Some(num) = C {
329+
Some(num)
330+
} else if let Some(num) = D {
331+
Some(num)
332+
} else {
333+
None
334+
}
335+
};
336+
337+
// Same const, should lint
338+
let _ = {
339+
if let Some(num) = A {
340+
Some(num)
341+
} else if let Some(num) = A {
342+
Some(num)
343+
} else if let Some(num) = A {
344+
Some(num)
345+
} else {
346+
None
347+
}
348+
};
349+
350+
None
351+
}
352+
292353
fn main() {}

tests/ui/needless_match.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,5 +131,17 @@ LL | | _ => e,
131131
LL | | };
132132
| |_________^ help: replace it with: `e`
133133

134-
error: aborting due to 13 previous errors
134+
error: this if-let expression is unnecessary
135+
--> tests/ui/needless_match.rs:339:9
136+
|
137+
LL | / if let Some(num) = A {
138+
LL | | Some(num)
139+
LL | | } else if let Some(num) = A {
140+
LL | | Some(num)
141+
... |
142+
LL | | None
143+
LL | | }
144+
| |_________^ help: replace it with: `A`
145+
146+
error: aborting due to 14 previous errors
135147

0 commit comments

Comments
 (0)