247 lines
4.5 KiB
Rust
247 lines
4.5 KiB
Rust
#![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() {}
|