From 0e67c0134fbb7764ed7bd1532b0e15f1bfd17044 Mon Sep 17 00:00:00 2001 From: llogiq Date: Mon, 17 Aug 2015 12:06:56 +0200 Subject: [PATCH] make float_cmp check for zero --- src/misc.rs | 5 +++++ tests/compile-fail/float_cmp.rs | 20 ++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/misc.rs b/src/misc.rs index 82ea78d97e1..33c34eb9b84 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -9,6 +9,7 @@ use rustc::middle::ty; 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 @@ -147,6 +148,10 @@ impl LintPass for FloatCmp { 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", diff --git a/tests/compile-fail/float_cmp.rs b/tests/compile-fail/float_cmp.rs index 419e500d0fc..067ec2818bf 100755 --- a/tests/compile-fail/float_cmp.rs +++ b/tests/compile-fail/float_cmp.rs @@ -13,22 +13,30 @@ fn twice(x : T) -> T where T : Add, T : Copy { #[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;