use std::borrow::Cow;
use utils::{match_path, snippet, snippet_block, span_lint, span_help_and_lint, walk_ptrs_ty};
+use consts::constant;
/// Handles uncategorized lints
/// Currently handles linting of if-let-able matches
if let ExprBinary(ref cmp, ref left, ref right) = expr.node {
let op = cmp.node;
if (op == BiEq || op == BiNe) && (is_float(cx, left) || is_float(cx, right)) {
+ if constant(cx, left).or_else(|| constant(cx, right)).map_or(
+ false, |c| c.as_float().map_or(false, |f| f == 0.0)) {
+ return;
+ }
span_lint(cx, FLOAT_CMP, expr.span, &format!(
"{}-comparison of f32 or f64 detected. Consider changing this to \
`abs({} - {}) < epsilon` for some suitable value of epsilon",
#[deny(float_cmp)]
#[allow(unused)]
fn main() {
- ZERO == 0f32; //~ERROR ==-comparison of f32 or f64
- ZERO == 0.0; //~ERROR ==-comparison of f32 or f64
+ ZERO == 0f32; //no error, comparison with zero is ok
+ ZERO == 0.0; //no error, comparison with zero is ok
ZERO + ZERO != 1.0; //~ERROR !=-comparison of f32 or f64
- ONE != 0.0; //~ERROR
+ ONE == 1f32; //~ERROR ==-comparison of f32 or f64
+ ONE == (1.0 + 0.0); //~ERROR ==-comparison of f32 or f64
+
+ ONE + ONE == (ZERO + ONE + ONE); //~ERROR ==-comparison of f32 or f64
+
+ ONE != 2.0; //~ERROR !=-comparison of f32 or f64
+ ONE != 0.0; // no error, comparison with zero is ok
twice(ONE) != ONE; //~ERROR !=-comparison of f32 or f64
- ONE as f64 != 0.0; //~ERROR !=-comparison of f32 or f64
+ ONE as f64 != 2.0; //~ERROR !=-comparison of f32 or f64
+ ONE as f64 != 0.0; // no error, comparison with zero is ok
let x : f64 = 1.0;
x == 1.0; //~ERROR ==-comparison of f32 or f64
- x != 0f64; //~ERROR !=-comparison of f32 or f64
+ x != 0f64; // no error, comparison with zero is ok
twice(x) != twice(ONE as f64); //~ERROR !=-comparison of f32 or f64
- x < 0.0;
+
+ x < 0.0; // no errors, lower or greater comparisons need no fuzzyness
x > 0.0;
x <= 0.0;
x >= 0.0;