1 use clippy_utils::diagnostics::span_lint_and_then;
2 use clippy_utils::{match_def_path, paths, sugg};
3 use if_chain::if_chain;
4 use rustc_ast::util::parser::AssocOp;
5 use rustc_errors::Applicability;
6 use rustc_hir::def::{DefKind, Res};
7 use rustc_hir::{BinOpKind, Expr, ExprKind};
8 use rustc_lint::LateContext;
10 use rustc_span::source_map::Spanned;
12 use super::FLOAT_EQUALITY_WITHOUT_ABS;
14 pub(crate) fn check<'tcx>(
15 cx: &LateContext<'tcx>,
21 let (lhs, rhs) = match op {
22 BinOpKind::Lt => (lhs, rhs),
23 BinOpKind::Gt => (rhs, lhs),
28 // left hand side is a subtraction
29 if let ExprKind::Binary(
38 // right hand side matches either f32::EPSILON or f64::EPSILON
39 if let ExprKind::Path(ref epsilon_path) = rhs.kind;
40 if let Res::Def(DefKind::AssocConst, def_id) = cx.qpath_res(epsilon_path, rhs.hir_id);
41 if match_def_path(cx, def_id, &paths::F32_EPSILON) || match_def_path(cx, def_id, &paths::F64_EPSILON);
43 // values of the subtractions on the left hand side are of the type float
44 let t_val_l = cx.typeck_results().expr_ty(val_l);
45 let t_val_r = cx.typeck_results().expr_ty(val_r);
46 if let ty::Float(_) = t_val_l.kind();
47 if let ty::Float(_) = t_val_r.kind();
50 let sug_l = sugg::Sugg::hir(cx, val_l, "..");
51 let sug_r = sugg::Sugg::hir(cx, val_r, "..");
52 // format the suggestion
53 let suggestion = format!("{}.abs()", sugg::make_assoc(AssocOp::Subtract, &sug_l, &sug_r).maybe_par());
57 FLOAT_EQUALITY_WITHOUT_ABS,
59 "float equality check without `.abs()`",
65 Applicability::MaybeIncorrect,