diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 181158a5f175..d41ea5849a88 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -134,15 +134,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste { /// Implementation of `IF_SAME_THEN_ELSE`. fn lint_same_then_else(cx: &LateContext, blocks: &[&Block]) { - let hash: &Fn(&&Block) -> u64 = &|block| -> u64 { - let mut h = SpanlessHash::new(cx); - h.hash_block(block); - h.finish() - }; - let eq: &Fn(&&Block, &&Block) -> bool = &|&lhs, &rhs| -> bool { SpanlessEq::new(cx).eq_block(lhs, rhs) }; - if let Some((i, j)) = search_same(blocks, hash, eq) { + if let Some((i, j)) = search_same_sequenced(blocks, eq) { span_note_and_lint( cx, IF_SAME_THEN_ELSE, @@ -309,6 +303,19 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap(exprs: &[T], eq: Eq) -> Option<(&T, &T)> +where + Eq: Fn(&T, &T) -> bool, +{ + for win in exprs.windows(2) { + if eq(&win[0], &win[1]) { + return Some((&win[0], &win[1])); + } + } + None +} + fn search_same(exprs: &[T], hash: Hash, eq: Eq) -> Option<(&T, &T)> where Hash: Fn(&T) -> u64, diff --git a/tests/run-pass/if_same_then_else.rs b/tests/run-pass/if_same_then_else.rs new file mode 100644 index 000000000000..eb14ce807564 --- /dev/null +++ b/tests/run-pass/if_same_then_else.rs @@ -0,0 +1,13 @@ +#![deny(if_same_then_else)] + +fn main() {} + +pub fn foo(a: i32, b: i32) -> Option<&'static str> { + if a == b { + None + } else if a > b { + Some("a pfeil b") + } else { + None + } +} diff --git a/tests/ui/copies.rs b/tests/ui/copies.rs index e5f5810795d2..0588c141103f 100644 --- a/tests/ui/copies.rs +++ b/tests/ui/copies.rs @@ -160,7 +160,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { else if false { foo(); } - else if foo() { //~ ERROR same body as `if` block + else if foo() { let _ = match 42 { 42 => 1, a if a > 0 => 2, @@ -336,7 +336,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { let foo = "bar"; return Ok(&foo[0..]); } - else { //~ ERROR same body as `if` block + else { let foo = ""; return Ok(&foo[0..]); } diff --git a/tests/ui/copies.stderr b/tests/ui/copies.stderr index c6034a199065..5faf41b51e33 100644 --- a/tests/ui/copies.stderr +++ b/tests/ui/copies.stderr @@ -151,32 +151,6 @@ note: same as this 139 | | } | |_____^ -error: this `if` has identical blocks - --> $DIR/copies.rs:163:19 - | -163 | else if foo() { //~ ERROR same body as `if` block - | ___________________^ -164 | | let _ = match 42 { -165 | | 42 => 1, -166 | | a if a > 0 => 2, -... | -169 | | }; -170 | | } - | |_____^ - | -note: same as this - --> $DIR/copies.rs:152:13 - | -152 | if true { - | _____________^ -153 | | let _ = match 42 { -154 | | 42 => 1, -155 | | a if a > 0 => 2, -... | -158 | | }; -159 | | } - | |_____^ - error: this `if` has identical blocks --> $DIR/copies.rs:175:10 | @@ -370,26 +344,6 @@ note: same as this 326 | | } | |_____^ -error: this `if` has identical blocks - --> $DIR/copies.rs:339:10 - | -339 | else { //~ ERROR same body as `if` block - | __________^ -340 | | let foo = ""; -341 | | return Ok(&foo[0..]); -342 | | } - | |_____^ - | -note: same as this - --> $DIR/copies.rs:331:13 - | -331 | if true { - | _____________^ -332 | | let foo = ""; -333 | | return Ok(&foo[0..]); -334 | | } - | |_____^ - error: this `if` has the same condition as a previous if --> $DIR/copies.rs:353:13 | @@ -427,5 +381,5 @@ note: same as this 361 | if 2*a == 1 { | ^^^^^^^^ -error: aborting due to 22 previous errors +error: aborting due to 20 previous errors