make float_cmp check for zero

This commit is contained in:
llogiq 2015-08-17 12:06:56 +02:00
parent e354fdc3e8
commit 0e67c0134f
2 changed files with 19 additions and 6 deletions

View File

@ -9,6 +9,7 @@ use rustc::middle::ty;
use std::borrow::Cow; use std::borrow::Cow;
use utils::{match_path, snippet, snippet_block, span_lint, span_help_and_lint, walk_ptrs_ty}; use utils::{match_path, snippet, snippet_block, span_lint, span_help_and_lint, walk_ptrs_ty};
use consts::constant;
/// Handles uncategorized lints /// Handles uncategorized lints
/// Currently handles linting of if-let-able matches /// 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 { if let ExprBinary(ref cmp, ref left, ref right) = expr.node {
let op = cmp.node; let op = cmp.node;
if (op == BiEq || op == BiNe) && (is_float(cx, left) || is_float(cx, right)) { 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!( span_lint(cx, FLOAT_CMP, expr.span, &format!(
"{}-comparison of f32 or f64 detected. Consider changing this to \ "{}-comparison of f32 or f64 detected. Consider changing this to \
`abs({} - {}) < epsilon` for some suitable value of epsilon", `abs({} - {}) < epsilon` for some suitable value of epsilon",

View File

@ -13,22 +13,30 @@ fn twice<T>(x : T) -> T where T : Add<T, Output = T>, T : Copy {
#[deny(float_cmp)] #[deny(float_cmp)]
#[allow(unused)] #[allow(unused)]
fn main() { fn main() {
ZERO == 0f32; //~ERROR ==-comparison of f32 or f64 ZERO == 0f32; //no error, comparison with zero is ok
ZERO == 0.0; //~ERROR ==-comparison of f32 or f64 ZERO == 0.0; //no error, comparison with zero is ok
ZERO + ZERO != 1.0; //~ERROR !=-comparison of f32 or f64 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 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; let x : f64 = 1.0;
x == 1.0; //~ERROR ==-comparison of f32 or f64 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 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; x <= 0.0;
x >= 0.0; x >= 0.0;