From 5461ed670eecedad74c82dd91ba532249d2073fb Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sun, 16 Jan 2022 09:46:02 -0500 Subject: [PATCH] Don't lint `if_same_then_else` with `if let` conditions --- clippy_lints/src/copies.rs | 29 +++++++++++++++++------------ tests/ui/if_same_then_else2.rs | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 73ce656ad151..f44d370a8fd0 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -183,7 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for CopyAndPaste { lint_same_cond(cx, &conds); lint_same_fns_in_if_cond(cx, &conds); // Block duplication - lint_same_then_else(cx, &blocks, conds.len() == blocks.len(), expr); + lint_same_then_else(cx, &conds, &blocks, conds.len() == blocks.len(), expr); } } } @@ -192,6 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for CopyAndPaste { /// Implementation of `BRANCHES_SHARING_CODE` and `IF_SAME_THEN_ELSE` if the blocks are equal. fn lint_same_then_else<'tcx>( cx: &LateContext<'tcx>, + conds: &[&'tcx Expr<'_>], blocks: &[&Block<'tcx>], has_conditional_else: bool, expr: &'tcx Expr<'_>, @@ -204,7 +205,7 @@ fn lint_same_then_else<'tcx>( // Check if each block has shared code let has_expr = blocks[0].expr.is_some(); - let (start_eq, mut end_eq, expr_eq) = if let Some(block_eq) = scan_block_for_eq(cx, blocks) { + let (start_eq, mut end_eq, expr_eq) = if let Some(block_eq) = scan_block_for_eq(cx, conds, blocks) { (block_eq.start_eq, block_eq.end_eq, block_eq.expr_eq) } else { return; @@ -316,14 +317,14 @@ struct BlockEqual { /// This function can also trigger the `IF_SAME_THEN_ELSE` in which case it'll return `None` to /// abort any further processing and avoid duplicate lint triggers. -fn scan_block_for_eq(cx: &LateContext<'_>, blocks: &[&Block<'_>]) -> Option { +fn scan_block_for_eq(cx: &LateContext<'_>, conds: &[&Expr<'_>], blocks: &[&Block<'_>]) -> Option { let mut start_eq = usize::MAX; let mut end_eq = usize::MAX; let mut expr_eq = true; - let mut iter = blocks.windows(2); - while let Some(&[win0, win1]) = iter.next() { - let l_stmts = win0.stmts; - let r_stmts = win1.stmts; + let mut iter = blocks.windows(2).enumerate(); + while let Some((i, &[block0, block1])) = iter.next() { + let l_stmts = block0.stmts; + let r_stmts = block1.stmts; // `SpanlessEq` now keeps track of the locals and is therefore context sensitive clippy#6752. // The comparison therefore needs to be done in a way that builds the correct context. @@ -340,22 +341,26 @@ fn scan_block_for_eq(cx: &LateContext<'_>, blocks: &[&Block<'_>]) -> Option Result<&'static str, ()> { let (y, x) = (1, 2); return Ok(&foo[x..y]); } + + // Issue #7579 + let _ = if let Some(0) = None { 0 } else { 0 }; + + if true { + return Err(()); + } else if let Some(0) = None { + return Err(()); + } + + let _ = if let Some(0) = None { + 0 + } else if let Some(1) = None { + 0 + } else { + 0 + }; } fn main() {}