mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-17 14:38:46 +00:00
Merge pull request #1096 from cramertj/1086-negative-zero
Fix #1086-Added sign check on Constant f64 PartialEq implementation
This commit is contained in:
commit
99b1ebbb33
3 changed files with 56 additions and 2 deletions
|
@ -92,7 +92,10 @@ impl PartialEq for Constant {
|
|||
// we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
|
||||
// `Fw32 == Fw64` so don’t compare them
|
||||
match (ls.parse::<f64>(), rs.parse::<f64>()) {
|
||||
(Ok(l), Ok(r)) => l.eq(&r),
|
||||
// mem::transmute is required to catch non-matching 0.0, -0.0, and NaNs
|
||||
(Ok(l), Ok(r)) => unsafe {
|
||||
mem::transmute::<f64, u64>(l) == mem::transmute::<f64, u64>(r)
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +162,11 @@ impl PartialOrd for Constant {
|
|||
(&Constant::Int(l), &Constant::Int(r)) => Some(l.cmp(&r)),
|
||||
(&Constant::Float(ref ls, _), &Constant::Float(ref rs, _)) => {
|
||||
match (ls.parse::<f64>(), rs.parse::<f64>()) {
|
||||
(Ok(ref l), Ok(ref r)) => l.partial_cmp(r),
|
||||
(Ok(ref l), Ok(ref r)) => match (l.partial_cmp(r), l.is_sign_positive() == r.is_sign_positive()) {
|
||||
// Check for comparison of -0.0 and 0.0
|
||||
(Some(Ordering::Equal), false) => None,
|
||||
(x, _) => x
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#![allow(cyclomatic_complexity)]
|
||||
#![allow(blacklisted_name)]
|
||||
#![allow(collapsible_if)]
|
||||
#![allow(zero_divided_by_zero, eq_op)]
|
||||
|
||||
fn bar<T>(_: T) {}
|
||||
fn foo() -> bool { unimplemented!() }
|
||||
|
@ -229,6 +230,46 @@ fn if_same_then_else() -> Result<&'static str, ()> {
|
|||
_ => 0,
|
||||
};
|
||||
|
||||
let _ = if true {
|
||||
//~^NOTE same as this
|
||||
0.0
|
||||
} else { //~ERROR this `if` has identical blocks
|
||||
0.0
|
||||
};
|
||||
|
||||
let _ = if true {
|
||||
//~^NOTE same as this
|
||||
-0.0
|
||||
} else { //~ERROR this `if` has identical blocks
|
||||
-0.0
|
||||
};
|
||||
|
||||
let _ = if true {
|
||||
0.0
|
||||
} else {
|
||||
-0.0
|
||||
};
|
||||
|
||||
// Different NaNs
|
||||
let _ = if true {
|
||||
0.0 / 0.0
|
||||
} else {
|
||||
std::f32::NAN
|
||||
};
|
||||
|
||||
// Same NaNs
|
||||
let _ = if true {
|
||||
//~^NOTE same as this
|
||||
std::f32::NAN
|
||||
} else { //~ERROR this `if` has identical blocks
|
||||
std::f32::NAN
|
||||
};
|
||||
|
||||
let _ = match Some(()) {
|
||||
Some(()) => 0.0,
|
||||
None => -0.0
|
||||
};
|
||||
|
||||
match (Some(42), Some("")) {
|
||||
(Some(a), None) => bar(a),
|
||||
(None, Some(a)) => bar(a), // bindings have different types
|
||||
|
|
|
@ -82,6 +82,12 @@ fn test_ops() {
|
|||
let half_any = Constant::Float("0.5".into(), FloatWidth::Any);
|
||||
let half32 = Constant::Float("0.5".into(), FloatWidth::F32);
|
||||
let half64 = Constant::Float("0.5".into(), FloatWidth::F64);
|
||||
let pos_zero = Constant::Float("0.0".into(), FloatWidth::F64);
|
||||
let neg_zero = Constant::Float("-0.0".into(), FloatWidth::F64);
|
||||
|
||||
assert_eq!(pos_zero, pos_zero);
|
||||
assert_eq!(neg_zero, neg_zero);
|
||||
assert_eq!(None, pos_zero.partial_cmp(&neg_zero));
|
||||
|
||||
assert_eq!(half_any, half32);
|
||||
assert_eq!(half_any, half64);
|
||||
|
|
Loading…
Add table
Reference in a new issue