Skip to content

Commit

Permalink
Auto merge of #11385 - markhuang1212:master, r=blyxyas
Browse files Browse the repository at this point in the history
skip float_cmp check if lhs is a custom type

*Please write a short comment explaining your change (or "none" for internal only changes)*

changelog: [`float_cmp`]: allow float eq comparison when lhs is a custom type that implements PartialEq<f32/f64>

If the lhs of a comparison is not float, it means there is a user implemented PartialEq, and the caller is invoking that custom version of `==`, instead of the default floating point equal comparison.

People may wrap f32 with a struct (say `MyF32`) and implement its PartialEq that will do the `is_close()` check, so that `MyF32` can be compared with either f32 or `MyF32`.
  • Loading branch information
bors committed Aug 28, 2023
2 parents 4118738 + e43c234 commit 5cc5f27
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
2 changes: 1 addition & 1 deletion clippy_lints/src/operators/float_cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub(crate) fn check<'tcx>(
left: &'tcx Expr<'_>,
right: &'tcx Expr<'_>,
) {
if (op == BinOpKind::Eq || op == BinOpKind::Ne) && (is_float(cx, left) || is_float(cx, right)) {
if (op == BinOpKind::Eq || op == BinOpKind::Ne) && is_float(cx, left) {
let left_is_local = match constant_with_source(cx, cx.typeck_results(), left) {
Some((c, s)) if !is_allowed(&c) => s.is_local(),
Some(_) => return,
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/float_cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,26 @@ impl PartialEq for X {
}
}

impl PartialEq<f32> for X {
fn eq(&self, o: &f32) -> bool {
if self.val.is_nan() {
o.is_nan()
} else {
self.val == *o // no error, inside "eq" fn
}
}
}

fn main() {
ZERO == 0f32; //no error, comparison with zero is ok
1.0f32 != f32::INFINITY; // also comparison with infinity
1.0f32 != f32::NEG_INFINITY; // and negative infinity
ZERO == 0.0; //no error, comparison with zero is ok
ZERO + ZERO != 1.0; //no error, comparison with zero is ok

let x = X { val: 1.0 };
x == 1.0; // no error, custom type that implement PartialOrder for float is not checked

ONE == 1f32;
ONE == 1.0 + 0.0;
ONE + ONE == ZERO + ONE + ONE;
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/float_cmp.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: strict comparison of `f32` or `f64`
--> $DIR/float_cmp.rs:57:5
--> $DIR/float_cmp.rs:70:5
|
LL | ONE as f64 != 2.0;
| ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin`
Expand All @@ -8,39 +8,39 @@ LL | ONE as f64 != 2.0;
= note: `-D clippy::float-cmp` implied by `-D warnings`

error: strict comparison of `f32` or `f64`
--> $DIR/float_cmp.rs:64:5
--> $DIR/float_cmp.rs:77:5
|
LL | x == 1.0;
| ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin`
|
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`

error: strict comparison of `f32` or `f64`
--> $DIR/float_cmp.rs:69:5
--> $DIR/float_cmp.rs:82:5
|
LL | twice(x) != twice(ONE as f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin`
|
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`

error: strict comparison of `f32` or `f64`
--> $DIR/float_cmp.rs:91:5
--> $DIR/float_cmp.rs:104:5
|
LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin`
|
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`

error: strict comparison of `f32` or `f64` arrays
--> $DIR/float_cmp.rs:98:5
--> $DIR/float_cmp.rs:111:5
|
LL | a1 == a2;
| ^^^^^^^^
|
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`

error: strict comparison of `f32` or `f64`
--> $DIR/float_cmp.rs:101:5
--> $DIR/float_cmp.rs:114:5
|
LL | a1[0] == a2[0];
| ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin`
Expand Down

0 comments on commit 5cc5f27

Please sign in to comment.