check that the types are equal in SpanlessEq::eq_expr

This commit is contained in:
y21 2023-07-23 15:51:11 +02:00
parent 7c5095c502
commit e975d05cde
3 changed files with 67 additions and 8 deletions

View file

@ -252,15 +252,15 @@ impl HirEqInterExpr<'_, '_, '_> {
return false;
}
if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results {
if let (Some(l), Some(r)) = (
if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results
&& typeck_lhs.expr_ty(left) == typeck_rhs.expr_ty(right)
&& let (Some(l), Some(r)) = (
constant_simple(self.inner.cx, typeck_lhs, left),
constant_simple(self.inner.cx, typeck_rhs, right),
) {
if l == r {
return true;
}
}
)
&& l == r
{
return true;
}
let is_eq = match (

View file

@ -214,4 +214,45 @@ mod issue_8836 {
}
}
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() {}

View file

@ -108,5 +108,23 @@ LL | | bar + 1;
LL | | }
| |_____^
error: aborting due to 5 previous errors
error: this `if` has identical blocks
--> $DIR/if_same_then_else.rs:250:14
|
LL | if x {
| ______________^
LL | | 0_u8.is_power_of_two()
LL | | } else {
| |_________^
|
note: same as this
--> $DIR/if_same_then_else.rs:252:16
|
LL | } else {
| ________________^
LL | | 0_u8.is_power_of_two()
LL | | }
| |_________^
error: aborting due to 6 previous errors