| #![warn(clippy::if_same_then_else)] |
| #![allow( |
| clippy::disallowed_names, |
| clippy::eq_op, |
| clippy::never_loop, |
| clippy::no_effect, |
| clippy::unused_unit, |
| clippy::zero_divided_by_zero, |
| clippy::branches_sharing_code, |
| dead_code, |
| unreachable_code |
| )] |
| |
| struct Foo { |
| bar: u8, |
| } |
| |
| fn foo() -> bool { |
| unimplemented!() |
| } |
| |
| fn if_same_then_else() { |
| if true { |
| Foo { bar: 42 }; |
| 0..10; |
| ..; |
| 0..; |
| ..10; |
| 0..=10; |
| foo(); |
| } else { |
| Foo { bar: 42 }; |
| 0..10; |
| ..; |
| 0..; |
| ..10; |
| 0..=10; |
| foo(); |
| } |
| //~^^^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks |
| |
| if true { |
| Foo { bar: 42 }; |
| } else { |
| Foo { bar: 43 }; |
| } |
| |
| if true { |
| (); |
| } else { |
| () |
| } |
| |
| if true { |
| 0..10; |
| } else { |
| 0..=10; |
| } |
| |
| if true { |
| foo(); |
| foo(); |
| } else { |
| foo(); |
| } |
| |
| let _ = if true { 0.0 } else { 0.0 }; |
| //~^ ERROR: this `if` has identical blocks |
| |
| let _ = if true { -0.0 } else { -0.0 }; |
| //~^ ERROR: this `if` has identical blocks |
| |
| let _ = if true { 0.0 } else { -0.0 }; |
| |
| // Different NaNs |
| let _ = if true { 0.0 / 0.0 } else { f32::NAN }; |
| |
| if true { |
| foo(); |
| } |
| |
| let _ = if true { 42 } else { 42 }; |
| //~^ ERROR: this `if` has identical blocks |
| |
| if true { |
| let bar = if true { 42 } else { 43 }; |
| |
| while foo() { |
| break; |
| } |
| bar + 1; |
| } else { |
| let bar = if true { 42 } else { 43 }; |
| |
| while foo() { |
| break; |
| } |
| bar + 1; |
| } |
| //~^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks |
| |
| if true { |
| let _ = match 42 { |
| 42 => 1, |
| a if a > 0 => 2, |
| 10..=15 => 3, |
| _ => 4, |
| }; |
| } else if false { |
| foo(); |
| } else if foo() { |
| let _ = match 42 { |
| 42 => 1, |
| a if a > 0 => 2, |
| 10..=15 => 3, |
| _ => 4, |
| }; |
| } |
| } |
| |
| // Issue #2423. This was causing an ICE. |
| fn func() { |
| if true { |
| f(&[0; 62]); |
| f(&[0; 4]); |
| f(&[0; 3]); |
| } else { |
| f(&[0; 62]); |
| f(&[0; 6]); |
| f(&[0; 6]); |
| } |
| } |
| |
| fn f(val: &[u8]) {} |
| |
| mod issue_5698 { |
| fn mul_not_always_commutative(x: i32, y: i32) -> i32 { |
| if x == 42 { |
| x * y |
| } else if x == 21 { |
| y * x |
| } else { |
| 0 |
| } |
| } |
| } |
| |
| mod issue_8836 { |
| fn do_not_lint() { |
| if true { |
| todo!() |
| } else { |
| todo!() |
| } |
| if true { |
| todo!(); |
| } else { |
| todo!(); |
| } |
| if true { |
| unimplemented!() |
| } else { |
| unimplemented!() |
| } |
| if true { |
| unimplemented!(); |
| } else { |
| unimplemented!(); |
| } |
| |
| if true { |
| println!("FOO"); |
| todo!(); |
| } else { |
| println!("FOO"); |
| todo!(); |
| } |
| |
| if true { |
| println!("FOO"); |
| unimplemented!(); |
| } else { |
| println!("FOO"); |
| unimplemented!(); |
| } |
| |
| if true { |
| println!("FOO"); |
| todo!() |
| } else { |
| println!("FOO"); |
| todo!() |
| } |
| |
| if true { |
| println!("FOO"); |
| unimplemented!() |
| } else { |
| println!("FOO"); |
| unimplemented!() |
| } |
| } |
| } |
| |
| mod issue_11213 { |
| fn reproducer(x: bool) -> bool { |
| if x { |
| 0_u8.is_power_of_two() |
| } else { |
| 0_u16.is_power_of_two() |
| } |
| } |
| |
| // a more obvious reproducer that shows |
| // why the code above is problematic: |
| fn v2(x: bool) -> bool { |
| trait Helper { |
| fn is_u8(&self) -> bool; |
| } |
| impl Helper for u8 { |
| fn is_u8(&self) -> bool { |
| true |
| } |
| } |
| impl Helper for u16 { |
| fn is_u8(&self) -> bool { |
| false |
| } |
| } |
| |
| // this is certainly not the same code in both branches |
| // it returns a different bool depending on the branch. |
| if x { 0_u8.is_u8() } else { 0_u16.is_u8() } |
| } |
| |
| fn do_lint(x: bool) -> bool { |
| // but do lint if the type of the literal is the same |
| if x { |
| 0_u8.is_power_of_two() |
| } else { |
| 0_u8.is_power_of_two() |
| } |
| } |
| } |
| |
| fn main() {} |