Skip to content

check f16 and f128 in float_equality_without_abs #15054

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions clippy_lints/src/operators/float_equality_without_abs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub(crate) fn check<'tcx>(
_ => return,
};

let sym_epsilon = [sym::f16_epsilon, sym::f32_epsilon, sym::f64_epsilon, sym::f128_epsilon];

if let ExprKind::Binary(
// left hand side is a subtraction
Spanned {
Expand All @@ -34,10 +36,10 @@ pub(crate) fn check<'tcx>(
val_r,
) = lhs.kind

// right hand side matches either f32::EPSILON or f64::EPSILON
// right hand side matches _::EPSILON
&& let ExprKind::Path(ref epsilon_path) = rhs.kind
&& let Res::Def(DefKind::AssocConst, def_id) = cx.qpath_res(epsilon_path, rhs.hir_id)
&& ([sym::f32_epsilon, sym::f64_epsilon].into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, def_id)))
&& (sym_epsilon.into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, def_id)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: you can use get_diagnostic_item to avoid a bunch of query overhead, something like

Suggested change
&& (sym_epsilon.into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, def_id)))
&& matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::f16_epsilon | sym::f32_epsilon | sym::f64_epsilon | sym::f128_epsilon))

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's too long so rustfmt complains error[internal]: line formatted, but exceeded maximum width.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can split the line by hand and make rustfmt happy.


// values of the subtractions on the left hand side are of the type float
&& let t_val_l = cx.typeck_results().expr_ty(val_l)
Expand Down
14 changes: 12 additions & 2 deletions tests/ui/float_equality_without_abs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![feature(f128)]
#![feature(f16)]
#![warn(clippy::float_equality_without_abs)]
//@no-rustfix: suggestions cause type ambiguity

// FIXME(f16_f128): add tests for these types when abs is available

pub fn is_roughly_equal(a: f32, b: f32) -> bool {
(a - b) < f32::EPSILON
//~^ float_equality_without_abs
Expand Down Expand Up @@ -44,10 +44,20 @@ pub fn main() {
let _ = f32::EPSILON > 1.0 - 2.0;
//~^ float_equality_without_abs

let _ = (a as f16 - b as f16) < f16::EPSILON;
//~^ float_equality_without_abs

let _ = (a as f128 - b as f128) < f128::EPSILON;
//~^ float_equality_without_abs

// those are correct
let _ = (a as f16 - b as f16).abs() < f16::EPSILON;
let _ = (a - b).abs() < f32::EPSILON;
let _ = (a as f64 - b as f64).abs() < f64::EPSILON;
let _ = (a as f128 - b as f128).abs() < f128::EPSILON;

let _ = f16::EPSILON > (a as f16 - b as f16).abs();
let _ = f32::EPSILON > (a - b).abs();
let _ = f64::EPSILON > (a as f64 - b as f64).abs();
let _ = f128::EPSILON > (a as f128 - b as f128).abs();
}
18 changes: 17 additions & 1 deletion tests/ui/float_equality_without_abs.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,21 @@ LL | let _ = f32::EPSILON > 1.0 - 2.0;
| |
| help: add `.abs()`: `(1.0 - 2.0).abs()`

error: aborting due to 11 previous errors
error: float equality check without `.abs()`
--> tests/ui/float_equality_without_abs.rs:47:13
|
LL | let _ = (a as f16 - b as f16) < f16::EPSILON;
| ---------------------^^^^^^^^^^^^^^^
| |
| help: add `.abs()`: `(a as f16 - b as f16).abs()`

error: float equality check without `.abs()`
--> tests/ui/float_equality_without_abs.rs:50:13
|
LL | let _ = (a as f128 - b as f128) < f128::EPSILON;
| -----------------------^^^^^^^^^^^^^^^^
| |
| help: add `.abs()`: `(a as f128 - b as f128).abs()`

error: aborting due to 13 previous errors