From 86bb771a7b1134221f1653a8e5830f9f52ed44dc Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Wed, 6 Dec 2023 01:35:55 -0500 Subject: [PATCH 01/10] Check more constant forms in `float_cmp` --- clippy_lints/src/operators/float_cmp.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 0e5b440c50f2..48dd0142bd53 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -86,13 +86,19 @@ fn get_lint_and_message(is_local: bool, is_comparing_arrays: bool) -> (&'static fn is_allowed(val: &Constant<'_>) -> bool { match val { // FIXME(f16_f128): add when equality check is available on all platforms + Constant::Ref(val) => is_allowed(val), &Constant::F32(f) => f == 0.0 || f.is_infinite(), &Constant::F64(f) => f == 0.0 || f.is_infinite(), - Constant::Vec(vec) => vec.iter().all(|f| match f { - Constant::F32(f) => *f == 0.0 || (*f).is_infinite(), - Constant::F64(f) => *f == 0.0 || (*f).is_infinite(), + Constant::Vec(vec) => vec.iter().all(|f| match *f { + Constant::F32(f) => f == 0.0 || f.is_infinite(), + Constant::F64(f) => f == 0.0 || f.is_infinite(), _ => false, }), + Constant::Repeat(val, _) => match **val { + Constant::F32(f) => f == 0.0 || f.is_infinite(), + Constant::F64(f) => f == 0.0 || f.is_infinite(), + _ => false, + }, _ => false, } } From 23cd0ad2d4f4f675602794c5e33740be59142136 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Tue, 5 Dec 2023 12:11:45 -0500 Subject: [PATCH 02/10] Add config options to ignore constant comparisons and comparisons to constants to `float_cmp` --- clippy_config/src/conf.rs | 29 ++ clippy_lints/src/operators/float_cmp.rs | 83 ++-- clippy_lints/src/operators/mod.rs | 13 +- clippy_utils/src/lib.rs | 10 + .../clippy.toml | 1 + .../float_cmp_constant_comparisons/test.rs | 18 + .../test.stderr | 14 + .../float_cmp_named_constants/clippy.toml | 1 + .../ui-toml/float_cmp_named_constants/test.rs | 18 + .../float_cmp_named_constants/test.stderr | 14 + .../toml_unknown_key/conf_unknown_key.stderr | 6 + tests/ui/float_cmp.rs | 379 ++++++++++++------ tests/ui/float_cmp.stderr | 164 +++++++- tests/ui/float_cmp_const.rs | 66 --- tests/ui/float_cmp_const.stderr | 53 --- 15 files changed, 569 insertions(+), 300 deletions(-) create mode 100644 tests/ui-toml/float_cmp_constant_comparisons/clippy.toml create mode 100644 tests/ui-toml/float_cmp_constant_comparisons/test.rs create mode 100644 tests/ui-toml/float_cmp_constant_comparisons/test.stderr create mode 100644 tests/ui-toml/float_cmp_named_constants/clippy.toml create mode 100644 tests/ui-toml/float_cmp_named_constants/test.rs create mode 100644 tests/ui-toml/float_cmp_named_constants/test.stderr delete mode 100644 tests/ui/float_cmp_const.rs delete mode 100644 tests/ui/float_cmp_const.stderr diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 7eec3d4945a2..3ae0db886b2e 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -645,6 +645,35 @@ define_Conf! { /// /// Whether to also emit warnings for unsafe blocks with metavariable expansions in **private** macros. (warn_unsafe_macro_metavars_in_private_macros: bool = false), + /// Lint: FLOAT_CMP + /// + /// Whether to ignore comparisons to a named constnat + /// + /// #### Example + /// ```no_run + /// const VALUE: f64 = 1.0; + /// fn is_value(x: f64) -> bool { + /// // Will warn if the config is `false` + /// x == VALUE + /// } + /// ``` + (float_cmp_ignore_named_constants: bool = true), + /// Lint: FLOAT_CMP + /// + /// Whether to ignore comparisons which have a constant result. + /// + /// #### Example + /// ```no_run + /// const fn f(x: f64) -> f64 { + /// todo!() + /// } + /// + /// // Will warn if the config is `false` + /// if f(1.0) == f(2.0) { + /// // ... + /// } + /// ``` + (float_cmp_ignore_constant_comparisons: bool = true), } /// Search for the configuration file. diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 48dd0142bd53..39dab2b80b6f 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -1,35 +1,54 @@ -use clippy_utils::consts::{constant_with_source, Constant}; +use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::get_item_name; use clippy_utils::sugg::Sugg; +use clippy_utils::visitors::is_const_evaluatable; +use clippy_utils::{get_item_name, is_expr_named_const, peel_hir_expr_while}; use rustc_errors::Applicability; -use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; +use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, UnOp}; use rustc_lint::LateContext; use rustc_middle::ty; -use super::{FLOAT_CMP, FLOAT_CMP_CONST}; +use super::{FloatCmpConfig, FLOAT_CMP}; pub(crate) fn check<'tcx>( cx: &LateContext<'tcx>, + config: FloatCmpConfig, expr: &'tcx Expr<'_>, op: BinOpKind, left: &'tcx Expr<'_>, right: &'tcx Expr<'_>, ) { - if (op == BinOpKind::Eq || op == BinOpKind::Ne) && is_float(cx, left) { - let left_is_local = match constant_with_source(cx, cx.typeck_results(), left) { - Some((c, s)) if !is_allowed(&c) => s.is_local(), - Some(_) => return, - None => true, - }; - let right_is_local = match constant_with_source(cx, cx.typeck_results(), right) { - Some((c, s)) if !is_allowed(&c) => s.is_local(), - Some(_) => return, - None => true, - }; - + if (op == BinOpKind::Eq || op == BinOpKind::Ne) + && is_float(cx, left) // Allow comparing the results of signum() - if is_signum(cx, left) && is_signum(cx, right) { + && !(is_signum(cx, left) && is_signum(cx, right)) + { + let left_c = constant(cx, cx.typeck_results(), left); + let is_left_const = left_c.is_some(); + if left_c.is_some_and(|c| is_allowed(&c)) { + return; + } + let right_c = constant(cx, cx.typeck_results(), right); + let is_right_const = right_c.is_some(); + if right_c.is_some_and(|c| is_allowed(&c)) { + return; + } + + if config.ignore_constant_comparisons + && (is_left_const || is_const_evaluatable(cx, left)) + && (is_right_const || is_const_evaluatable(cx, right)) + { + return; + } + + let peel_expr = |e: &'tcx Expr<'tcx>| match e.kind { + ExprKind::Cast(e, _) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => Some(e), + _ => None, + }; + if config.ignore_named_constants + && (is_expr_named_const(cx, peel_hir_expr_while(left, peel_expr)) + || is_expr_named_const(cx, peel_hir_expr_while(right, peel_expr))) + { return; } @@ -40,8 +59,12 @@ pub(crate) fn check<'tcx>( } } let is_comparing_arrays = is_array(cx, left) || is_array(cx, right); - let (lint, msg) = get_lint_and_message(left_is_local && right_is_local, is_comparing_arrays); - span_lint_and_then(cx, lint, expr.span, msg, |diag| { + let msg = if is_comparing_arrays { + "strict comparison of `f32` or `f64` arrays" + } else { + "strict comparison of `f32` or `f64`" + }; + span_lint_and_then(cx, FLOAT_CMP, expr.span, msg, |diag| { let lhs = Sugg::hir(cx, left, ".."); let rhs = Sugg::hir(cx, right, ".."); @@ -61,28 +84,6 @@ pub(crate) fn check<'tcx>( } } -fn get_lint_and_message(is_local: bool, is_comparing_arrays: bool) -> (&'static rustc_lint::Lint, &'static str) { - if is_local { - ( - FLOAT_CMP, - if is_comparing_arrays { - "strict comparison of `f32` or `f64` arrays" - } else { - "strict comparison of `f32` or `f64`" - }, - ) - } else { - ( - FLOAT_CMP_CONST, - if is_comparing_arrays { - "strict comparison of `f32` or `f64` constant arrays" - } else { - "strict comparison of `f32` or `f64` constant" - }, - ) - } -} - fn is_allowed(val: &Constant<'_>) -> bool { match val { // FIXME(f16_f128): add when equality check is available on all platforms diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 9baecff801f2..759f9f873a59 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -837,10 +837,17 @@ declare_clippy_lint! { "explicit self-assignment" } +#[derive(Clone, Copy)] +struct FloatCmpConfig { + ignore_named_constants: bool, + ignore_constant_comparisons: bool, +} + pub struct Operators { arithmetic_context: numeric_arithmetic::Context, verbose_bit_mask_threshold: u64, modulo_arithmetic_allow_comparison_to_zero: bool, + float_cmp_config: FloatCmpConfig, } impl Operators { pub fn new(conf: &'static Conf) -> Self { @@ -848,6 +855,10 @@ impl Operators { arithmetic_context: numeric_arithmetic::Context::default(), verbose_bit_mask_threshold: conf.verbose_bit_mask_threshold, modulo_arithmetic_allow_comparison_to_zero: conf.allow_comparison_to_zero, + float_cmp_config: FloatCmpConfig { + ignore_named_constants: conf.float_cmp_ignore_named_constants, + ignore_constant_comparisons: conf.float_cmp_ignore_constant_comparisons, + }, } } } @@ -906,7 +917,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { float_equality_without_abs::check(cx, e, op.node, lhs, rhs); integer_division::check(cx, e, op.node, lhs, rhs); cmp_owned::check(cx, op.node, lhs, rhs); - float_cmp::check(cx, e, op.node, lhs, rhs); + float_cmp::check(cx, self.float_cmp_config, e, op.node, lhs, rhs); modulo_one::check(cx, e, op.node, rhs); modulo_arithmetic::check( cx, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 476370133aee..fb1493884fef 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -245,6 +245,16 @@ pub fn is_inside_always_const_context(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { } } +/// Checks if the expression is path to either a constant or an associated constant. +pub fn is_expr_named_const<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { + matches!(&e.kind, ExprKind::Path(p) + if matches!( + cx.qpath_res(p, e.hir_id), + Res::Def(DefKind::Const | DefKind::AssocConst, _) + ) + ) +} + /// Checks if a `Res` refers to a constructor of a `LangItem` /// For example, use this to check whether a function call or a pattern is `Some(..)`. pub fn is_res_lang_ctor(cx: &LateContext<'_>, res: Res, lang_item: LangItem) -> bool { diff --git a/tests/ui-toml/float_cmp_constant_comparisons/clippy.toml b/tests/ui-toml/float_cmp_constant_comparisons/clippy.toml new file mode 100644 index 000000000000..34006387a248 --- /dev/null +++ b/tests/ui-toml/float_cmp_constant_comparisons/clippy.toml @@ -0,0 +1 @@ +float-cmp-ignore-constant-comparisons = false diff --git a/tests/ui-toml/float_cmp_constant_comparisons/test.rs b/tests/ui-toml/float_cmp_constant_comparisons/test.rs new file mode 100644 index 000000000000..68cd0a08aa10 --- /dev/null +++ b/tests/ui-toml/float_cmp_constant_comparisons/test.rs @@ -0,0 +1,18 @@ +//@no-rustfix + +#![deny(clippy::float_cmp)] + +fn main() { + { + const C: f64 = 1.0; + fn f(x: f64) { + let _ = x == C; + } + } + { + const fn f(x: f64) -> f64 { + todo!() + } + let _ = f(1.0) == f(2.0); + } +} diff --git a/tests/ui-toml/float_cmp_constant_comparisons/test.stderr b/tests/ui-toml/float_cmp_constant_comparisons/test.stderr new file mode 100644 index 000000000000..919ae8d66721 --- /dev/null +++ b/tests/ui-toml/float_cmp_constant_comparisons/test.stderr @@ -0,0 +1,14 @@ +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp_constant_comparisons/test.rs:16:17 + | +LL | let _ = f(1.0) == f(2.0); + | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(2.0)).abs() < error_margin` + | +note: the lint level is defined here + --> tests/ui-toml/float_cmp_constant_comparisons/test.rs:3:9 + | +LL | #![deny(clippy::float_cmp)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/float_cmp_named_constants/clippy.toml b/tests/ui-toml/float_cmp_named_constants/clippy.toml new file mode 100644 index 000000000000..7e24aab86cf6 --- /dev/null +++ b/tests/ui-toml/float_cmp_named_constants/clippy.toml @@ -0,0 +1 @@ +float-cmp-ignore-named-constants = false diff --git a/tests/ui-toml/float_cmp_named_constants/test.rs b/tests/ui-toml/float_cmp_named_constants/test.rs new file mode 100644 index 000000000000..68cd0a08aa10 --- /dev/null +++ b/tests/ui-toml/float_cmp_named_constants/test.rs @@ -0,0 +1,18 @@ +//@no-rustfix + +#![deny(clippy::float_cmp)] + +fn main() { + { + const C: f64 = 1.0; + fn f(x: f64) { + let _ = x == C; + } + } + { + const fn f(x: f64) -> f64 { + todo!() + } + let _ = f(1.0) == f(2.0); + } +} diff --git a/tests/ui-toml/float_cmp_named_constants/test.stderr b/tests/ui-toml/float_cmp_named_constants/test.stderr new file mode 100644 index 000000000000..64e237333336 --- /dev/null +++ b/tests/ui-toml/float_cmp_named_constants/test.stderr @@ -0,0 +1,14 @@ +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp_named_constants/test.rs:9:21 + | +LL | let _ = x == C; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - C).abs() < error_margin` + | +note: the lint level is defined here + --> tests/ui-toml/float_cmp_named_constants/test.rs:3:9 + | +LL | #![deny(clippy::float_cmp)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 5cf9c0fb2710..298d29015fc6 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -42,6 +42,8 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-ignore-constant-comparisons + float-cmp-ignore-named-constants future-size-threshold ignore-interior-mutability large-error-threshold @@ -126,6 +128,8 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-ignore-constant-comparisons + float-cmp-ignore-named-constants future-size-threshold ignore-interior-mutability large-error-threshold @@ -210,6 +214,8 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-ignore-constant-comparisons + float-cmp-ignore-named-constants future-size-threshold ignore-interior-mutability large-error-threshold diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs index 78dd2c6c01c3..d64de06f1c3d 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -1,136 +1,275 @@ +//@no-rustfix + // FIXME(f16_f128): const casting is not yet supported for these types. Add when available. #![warn(clippy::float_cmp)] -#![allow( - unused, - clippy::no_effect, - clippy::op_ref, - clippy::unnecessary_operation, - clippy::cast_lossless -)] -//@no-rustfix -use std::ops::Add; +#![allow(clippy::op_ref)] -const ZERO: f32 = 0.0; -const ONE: f32 = ZERO + 1.0; +fn main() { + { + fn _f(x: f32, y: f32) { + let _ = x == y; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x != y; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == 5.5; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = 5.5 == x; + //~^ ERROR: strict comparison of `f32` or `f64` -fn twice(x: T) -> T -where - T: Add + Copy, -{ - x + x -} + let _ = x < 5.5; + let _ = x <= 5.5; + let _ = x > 5.5; + let _ = x >= 5.5; + let _ = 5.5 < x; + let _ = 5.5 <= x; + let _ = 5.5 > x; + let _ = 5.5 >= x; -fn eq_fl(x: f32, y: f32) -> bool { - if x.is_nan() { y.is_nan() } else { x == y } // no error, inside "eq" fn -} + let _ = 0.0 == x; + let _ = -0.0 == x; + let _ = 1.0 / 0.0 == x; + let _ = -1.0 / 0.0 == x; + let _ = x == 0.0; + let _ = x == -0.0; + let _ = x == 1.0 / 0.0; + let _ = x == -1.0 / 0.0; + } + } + { + fn _f(x: f64, y: f64) { + let _ = x == y; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x != y; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == 5.5; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = 5.5 == x; + //~^ ERROR: strict comparison of `f32` or `f64` -fn fl_eq(x: f32, y: f32) -> bool { - if x.is_nan() { y.is_nan() } else { x == y } // no error, inside "eq" fn -} + let _ = x < 5.5; + let _ = x <= 5.5; + let _ = x > 5.5; + let _ = x >= 5.5; + let _ = 5.5 < x; + let _ = 5.5 <= x; + let _ = 5.5 > x; + let _ = 5.5 >= x; -struct X { - val: f32, -} + let _ = 0.0 == x; + let _ = -0.0 == x; + let _ = 1.0 / 0.0 == x; + let _ = -1.0 / 0.0 == x; + let _ = x == 0.0; + let _ = x == -0.0; + let _ = x == 1.0 / 0.0; + let _ = x == -1.0 / 0.0; + } + } + { + fn _f(x: [f32; 4], y: [f32; 4]) { + let _ = x == y; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == [5.5; 4]; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = [5.5; 4] == x; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = [0.0, 0.0, 0.0, 5.5] == x; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == [0.0, 0.0, 0.0, 5.5]; + //~^ ERROR: strict comparison of `f32` or `f64` -impl PartialEq for X { - fn eq(&self, o: &X) -> bool { - if self.val.is_nan() { - o.val.is_nan() - } else { - self.val == o.val // no error, inside "eq" fn + let _ = [0.0; 4] == x; + let _ = [-0.0; 4] == x; + let _ = [1.0 / 0.0; 4] == x; + let _ = [-1.0 / 0.0; 4] == x; + let _ = [0.0, -0.0, 1.0 / 0.0, -1.0 / 0.0] == x; + let _ = x == [0.0; 4]; + let _ = x == [-0.0; 4]; + let _ = x == [1.0 / 0.0; 4]; + let _ = x == [-1.0 / 0.0; 4]; + let _ = x == [0.0, -0.0, 1.0 / 0.0, -1.0 / 0.0]; } } -} + { + fn _f(x: [f64; 4], y: [f64; 4]) { + let _ = x == y; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == [5.5; 4]; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = [5.5; 4] == x; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = [0.0, 0.0, 0.0, 5.5] == x; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == [0.0, 0.0, 0.0, 5.5]; + //~^ ERROR: strict comparison of `f32` or `f64` -impl PartialEq for X { - fn eq(&self, o: &f32) -> bool { - if self.val.is_nan() { - o.is_nan() - } else { - self.val == *o // no error, inside "eq" fn + let _ = [0.0; 4] == x; + let _ = [-0.0; 4] == x; + let _ = [1.0 / 0.0; 4] == x; + let _ = [-1.0 / 0.0; 4] == x; + let _ = [0.0, -0.0, 1.0 / 0.0, -1.0 / 0.0] == x; + let _ = x == [0.0; 4]; + let _ = x == [-0.0; 4]; + let _ = x == [1.0 / 0.0; 4]; + let _ = x == [-1.0 / 0.0; 4]; + let _ = x == [0.0, -0.0, 1.0 / 0.0, -1.0 / 0.0]; } } -} -fn main() { - ZERO == 0f32; //no error, comparison with zero is ok - 1.0f32 != f32::INFINITY; // also comparison with infinity - 1.0f32 != f32::NEG_INFINITY; // and negative infinity - ZERO == 0.0; //no error, comparison with zero is ok - ZERO + ZERO != 1.0; //no error, comparison with zero is ok - - let x = X { val: 1.0 }; - x == 1.0; // no error, custom type that implement PartialOrder for float is not checked - - ONE == 1f32; - ONE == 1.0 + 0.0; - ONE + ONE == ZERO + ONE + ONE; - ONE != 2.0; - ONE != 0.0; // no error, comparison with zero is ok - twice(ONE) != ONE; - ONE as f64 != 2.0; - //~^ ERROR: strict 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: strict comparison of `f32` or `f64` - x != 0f64; // no error, comparison with zero is ok - - twice(x) != twice(ONE as f64); - //~^ ERROR: strict comparison of `f32` or `f64` - - x < 0.0; // no errors, lower or greater comparisons need no fuzzyness - x > 0.0; - x <= 0.0; - x >= 0.0; - - let xs: [f32; 1] = [0.0]; - let a: *const f32 = xs.as_ptr(); - let b: *const f32 = xs.as_ptr(); - - assert_eq!(a, b); // no errors - - const ZERO_ARRAY: [f32; 2] = [0.0, 0.0]; - const NON_ZERO_ARRAY: [f32; 2] = [0.0, 0.1]; - - let i = 0; - let j = 1; - - ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; // ok, because lhs is zero regardless of i - NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; - //~^ ERROR: strict comparison of `f32` or `f64` - - let a1: [f32; 1] = [0.0]; - let a2: [f32; 1] = [1.1]; - - a1 == a2; - //~^ ERROR: strict comparison of `f32` or `f64` arrays - a1[0] == a2[0]; - //~^ ERROR: strict comparison of `f32` or `f64` - - // no errors - comparing signums is ok - let x32 = 3.21f32; - 1.23f32.signum() == x32.signum(); - 1.23f32.signum() == -(x32.signum()); - 1.23f32.signum() == 3.21f32.signum(); - - 1.23f32.signum() != x32.signum(); - 1.23f32.signum() != -(x32.signum()); - 1.23f32.signum() != 3.21f32.signum(); - - let x64 = 3.21f64; - 1.23f64.signum() == x64.signum(); - 1.23f64.signum() == -(x64.signum()); - 1.23f64.signum() == 3.21f64.signum(); - - 1.23f64.signum() != x64.signum(); - 1.23f64.signum() != -(x64.signum()); - 1.23f64.signum() != 3.21f64.signum(); - - // the comparison should also look through references - &0.0 == &ZERO; - &&&&0.0 == &&&&ZERO; + // Reference comparisons + { + fn _f(x: &&&f32, y: &&&f32) { + let _ = x == y; + //~^ ERROR: strict comparison of `f32` or `f64` + + let _ = x == &&&0.0; + } + } + { + fn _f(x: &&&[f32; 2], y: &&&[f32; 2]) { + let _ = x == y; + //~^ ERROR: strict comparison of `f32` or `f64` + + let _ = x == &&&[0.0, -0.0]; + } + } + + // Comparisons to named constant + { + const C: f32 = 5.5; + fn _f(x: f32, y: f64) { + let _ = x == C; + let _ = C == x; + let _ = &&x == &&C; + let _ = &&C == &&x; + let _ = y == C as f64; + let _ = C as f64 == y; + + let _ = C * x == x * x; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x * x == C * x; + //~^ ERROR: strict comparison of `f32` or `f64` + } + } + { + const C: [f32; 2] = [5.5, 5.5]; + fn _f(x: [f32; 2]) { + let _ = x == C; + let _ = C == x; + let _ = &&x == &&C; + let _ = &&C == &&x; + } + } + + // Constant comparisons + { + const fn f(x: f32) -> f32 { + todo!() + } + let _ = f(1.0) == f(5.0); + let _ = 1.0 == f(5.0); + let _ = f(1.0) + 1.0 != 5.0; + } + { + fn f(x: f32) -> f32 { + todo!() + } + let _ = f(1.0) == f(5.0); + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = 1.0 == f(5.0); + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = f(1.0) + 1.0 != 5.0; + //~^ ERROR: strict comparison of `f32` or `f64` + } + + // Pointer equality + { + fn _f(x: *const f32, y: *const f32) { + let _ = x == y; + } + } + { + fn _f(x: *const [f32; 2], y: *const [f32; 2]) { + let _ = x == y; + } + } + + // `signum` + { + fn _f(x: f32, y: f32) { + let _ = x.signum() == y.signum(); + let _ = x.signum() == -y.signum(); + let _ = -x.signum() == y.signum(); + let _ = -x.signum() == -y.signum(); + } + } + { + fn _f(x: f64, y: f64) { + let _ = x.signum() == y.signum(); + let _ = x.signum() == -y.signum(); + let _ = -x.signum() == y.signum(); + let _ = -x.signum() == -y.signum(); + } + } + + // Index constant array + { + const C: [f32; 3] = [0.0, 5.5, -0.0]; + fn _f(x: f32) { + let _ = x == C[0]; + let _ = x == C[2]; + let _ = C[0] == x; + let _ = C[2] == x; + + let _ = x == C[1]; + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = C[1] == x; + //~^ ERROR: strict comparison of `f32` or `f64` + } + } + + // `eq` functions + { + fn eq(x: f32, y: f32) -> bool { + x == y + } + + fn ne(x: f32, y: f32) -> bool { + x != y + } + + fn is_eq(x: f32, y: f32) -> bool { + x == y + } + + struct _X(f32); + impl PartialEq for _X { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + fn eq_fl(x: f32, y: f32) -> bool { + if x.is_nan() { y.is_nan() } else { x == y } + } + + fn fl_eq(x: f32, y: f32) -> bool { + if x.is_nan() { y.is_nan() } else { x == y } + } + } + + // Custom types + { + struct S; + impl PartialEq for S { + fn eq(&self, _: &f32) -> bool { + false + } + } + + fn _f(x: S, y: f32) { + let _ = x == y; + } + } } diff --git a/tests/ui/float_cmp.stderr b/tests/ui/float_cmp.stderr index d10da8a99a9d..0e3e6cc8b603 100644 --- a/tests/ui/float_cmp.stderr +++ b/tests/ui/float_cmp.stderr @@ -1,41 +1,167 @@ error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:72:5 + --> tests/ui/float_cmp.rs:11:21 | -LL | ONE as f64 != 2.0; - | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin` +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` | = note: `-D clippy::float-cmp` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::float_cmp)]` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:78:5 + --> tests/ui/float_cmp.rs:13:21 | -LL | x == 1.0; - | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin` +LL | let _ = x != y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:82:5 + --> tests/ui/float_cmp.rs:15:21 | -LL | twice(x) != twice(ONE as f64); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin` +LL | let _ = x == 5.5; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:103:5 + --> tests/ui/float_cmp.rs:17:21 | -LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin` +LL | let _ = 5.5 == x; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:41:21 + | +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:43:21 + | +LL | let _ = x != y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:45:21 + | +LL | let _ = x == 5.5; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:47:21 + | +LL | let _ = 5.5 == x; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:71:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:73:21 + | +LL | let _ = x == [5.5; 4]; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:75:21 + | +LL | let _ = [5.5; 4] == x; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:77:21 + | +LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:109:5 + --> tests/ui/float_cmp.rs:79:21 + | +LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:96:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:98:21 + | +LL | let _ = x == [5.5; 4]; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:100:21 + | +LL | let _ = [5.5; 4] == x; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:102:21 + | +LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:104:21 + | +LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:123:21 + | +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui/float_cmp.rs:131:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:149:21 + | +LL | let _ = C * x == x * x; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C * x - x * x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:151:21 + | +LL | let _ = x * x == C * x; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - C * x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:178:17 + | +LL | let _ = f(1.0) == f(5.0); + | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:180:17 + | +LL | let _ = 1.0 == f(5.0); + | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:182:17 + | +LL | let _ = f(1.0) + 1.0 != 5.0; + | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:225:21 | -LL | a1 == a2; - | ^^^^^^^^ +LL | let _ = x == C[1]; + | ^^^^^^^^^ help: consider comparing them within some margin of error: `(x - C[1]).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:111:5 + --> tests/ui/float_cmp.rs:227:21 | -LL | a1[0] == a2[0]; - | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin` +LL | let _ = C[1] == x; + | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` -error: aborting due to 6 previous errors +error: aborting due to 27 previous errors diff --git a/tests/ui/float_cmp_const.rs b/tests/ui/float_cmp_const.rs deleted file mode 100644 index 081805564373..000000000000 --- a/tests/ui/float_cmp_const.rs +++ /dev/null @@ -1,66 +0,0 @@ -// does not test any rustfixable lints -//@no-rustfix -#![warn(clippy::float_cmp_const)] -#![allow(clippy::float_cmp)] -#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)] - -const ONE: f32 = 1.0; -const TWO: f32 = 2.0; - -fn eq_one(x: f32) -> bool { - if x.is_nan() { false } else { x == ONE } // no error, inside "eq" fn -} - -fn main() { - // has errors - 1f32 == ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant - TWO == ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant - TWO != ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant - ONE + ONE == TWO; - //~^ ERROR: strict comparison of `f32` or `f64` constant - let x = 1; - x as f32 == ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant - - let v = 0.9; - v == ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant - v != ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant - - // no errors, lower than or greater than comparisons - v < ONE; - v > ONE; - v <= ONE; - v >= ONE; - - // no errors, zero and infinity values - ONE != 0f32; - TWO == 0f32; - ONE != f32::INFINITY; - ONE == f32::NEG_INFINITY; - - // no errors, but will warn clippy::float_cmp if '#![allow(float_cmp)]' above is removed - let w = 1.1; - v == w; - v != w; - v == 1.0; - v != 1.0; - - const ZERO_ARRAY: [f32; 3] = [0.0, 0.0, 0.0]; - const ZERO_INF_ARRAY: [f32; 3] = [0.0, f32::INFINITY, f32::NEG_INFINITY]; - const NON_ZERO_ARRAY: [f32; 3] = [0.0, 0.1, 0.2]; - const NON_ZERO_ARRAY2: [f32; 3] = [0.2, 0.1, 0.0]; - - // no errors, zero and infinity values - NON_ZERO_ARRAY[0] == NON_ZERO_ARRAY2[1]; // lhs is 0.0 - ZERO_ARRAY == NON_ZERO_ARRAY; // lhs is all zeros - ZERO_INF_ARRAY == NON_ZERO_ARRAY; // lhs is all zeros or infinities - - // has errors - NON_ZERO_ARRAY == NON_ZERO_ARRAY2; - //~^ ERROR: strict comparison of `f32` or `f64` constant arrays -} diff --git a/tests/ui/float_cmp_const.stderr b/tests/ui/float_cmp_const.stderr deleted file mode 100644 index 4f88746e958e..000000000000 --- a/tests/ui/float_cmp_const.stderr +++ /dev/null @@ -1,53 +0,0 @@ -error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:16:5 - | -LL | 1f32 == ONE; - | ^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1f32 - ONE).abs() < error_margin` - | - = note: `-D clippy::float-cmp-const` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::float_cmp_const)]` - -error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:18:5 - | -LL | TWO == ONE; - | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() < error_margin` - -error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:20:5 - | -LL | TWO != ONE; - | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() > error_margin` - -error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:22:5 - | -LL | ONE + ONE == TWO; - | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE + ONE - TWO).abs() < error_margin` - -error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:25:5 - | -LL | x as f32 == ONE; - | ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin` - -error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:29:5 - | -LL | v == ONE; - | ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin` - -error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:31:5 - | -LL | v != ONE; - | ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin` - -error: strict comparison of `f32` or `f64` constant arrays - --> tests/ui/float_cmp_const.rs:64:5 - | -LL | NON_ZERO_ARRAY == NON_ZERO_ARRAY2; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 8 previous errors - From 44e3fdc19423360c4569134d2b43b98d69fc96d3 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Wed, 6 Dec 2023 01:59:47 -0500 Subject: [PATCH 03/10] Deprecate `float_cmp_const` --- clippy_lints/src/declared_lints.rs | 1 - clippy_lints/src/deprecated_lints.rs | 11 +++++ clippy_lints/src/lib.deprecated.rs | 4 ++ clippy_lints/src/operators/mod.rs | 66 +--------------------------- tests/ui/deprecated.rs | 1 + tests/ui/deprecated.stderr | 8 +++- 6 files changed, 24 insertions(+), 67 deletions(-) diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index eabc67601a2f..7806421fbb65 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -570,7 +570,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::operators::ERASING_OP_INFO, crate::operators::FLOAT_ARITHMETIC_INFO, crate::operators::FLOAT_CMP_INFO, - crate::operators::FLOAT_CMP_CONST_INFO, crate::operators::FLOAT_EQUALITY_WITHOUT_ABS_INFO, crate::operators::IDENTITY_OP_INFO, crate::operators::IMPOSSIBLE_COMPARISONS_INFO, diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs index a0900f46f6aa..f3ddb5403b57 100644 --- a/clippy_lints/src/deprecated_lints.rs +++ b/clippy_lints/src/deprecated_lints.rs @@ -241,3 +241,14 @@ declare_deprecated_lint! { pub MISMATCHED_TARGET_OS, "this lint has been replaced by `unexpected_cfgs`" } + +declare_deprecated_lint! { + /// ### What it does + /// Nothing. This lint has been deprecated. + /// + /// ### Deprecation reason + /// `float_cmp` handles this via config options + #[clippy::version = "1.76.0"] + pub FLOAT_CMP_CONST, + "`float_cmp` handles this via config options" +} diff --git a/clippy_lints/src/lib.deprecated.rs b/clippy_lints/src/lib.deprecated.rs index 0d21261822dd..be7c74e36ab1 100644 --- a/clippy_lints/src/lib.deprecated.rs +++ b/clippy_lints/src/lib.deprecated.rs @@ -75,4 +75,8 @@ "clippy::mismatched_target_os", "this lint has been replaced by `unexpected_cfgs`", ); + store.register_removed( + "clippy::float_cmp_const", + "`float_cmp` handles this via config options", + ); } diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 759f9f873a59..0b3eec91c052 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -633,70 +633,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for (in-)equality comparisons on constant floating-point - /// values (apart from zero), except in functions called `*eq*` (which probably - /// implement equality for a type involving floats). - /// - /// ### Why restrict this? - /// Floating point calculations are usually imprecise, so asking if two values are *exactly* - /// equal is asking for trouble because arriving at the same logical result via different - /// routes (e.g. calculation versus constant) may yield different values. - /// - /// ### Example - /// - /// ```no_run - /// let a: f64 = 1000.1; - /// let b: f64 = 0.2; - /// let x = a + b; - /// const Y: f64 = 1000.3; // Expected value. - /// - /// // Actual value: 1000.3000000000001 - /// println!("{x}"); - /// - /// let are_equal = x == Y; - /// println!("{are_equal}"); // false - /// ``` - /// - /// The correct way to compare floating point numbers is to define an allowed error margin. This - /// may be challenging if there is no "natural" error margin to permit. Broadly speaking, there - /// are two cases: - /// - /// 1. If your values are in a known range and you can define a threshold for "close enough to - /// be equal", it may be appropriate to define an absolute error margin. For example, if your - /// data is "length of vehicle in centimeters", you may consider 0.1 cm to be "close enough". - /// 1. If your code is more general and you do not know the range of values, you should use a - /// relative error margin, accepting e.g. 0.1% of error regardless of specific values. - /// - /// For the scenario where you can define a meaningful absolute error margin, consider using: - /// - /// ```no_run - /// let a: f64 = 1000.1; - /// let b: f64 = 0.2; - /// let x = a + b; - /// const Y: f64 = 1000.3; // Expected value. - /// - /// const ALLOWED_ERROR_VEHICLE_LENGTH_CM: f64 = 0.1; - /// let within_tolerance = (x - Y).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM; - /// println!("{within_tolerance}"); // true - /// ``` - /// - /// NB! Do not use `f64::EPSILON` - while the error margin is often called "epsilon", this is - /// a different use of the term that is not suitable for floating point equality comparison. - /// Indeed, for the example above using `f64::EPSILON` as the allowed error would return `false`. - /// - /// For the scenario where no meaningful absolute error can be defined, refer to - /// [the floating point guide](https://www.floating-point-gui.de/errors/comparison) - /// for a reference implementation of relative error based comparison of floating point values. - /// `MIN_NORMAL` in the reference implementation is equivalent to `MIN_POSITIVE` in Rust. - #[clippy::version = "pre 1.29.0"] - pub FLOAT_CMP_CONST, - restriction, - "using `==` or `!=` on float constants instead of comparing difference with an allowed error" -} - -declare_clippy_lint! { - /// ### What it does - /// Checks for getting the remainder of integer division by one or minus + /// Checks for getting the remainder of a division by one or minus /// one. /// /// ### Why is this bad? @@ -884,7 +821,6 @@ impl_lint_pass!(Operators => [ INTEGER_DIVISION, CMP_OWNED, FLOAT_CMP, - FLOAT_CMP_CONST, MODULO_ONE, MODULO_ARITHMETIC, NEEDLESS_BITWISE_BOOL, diff --git a/tests/ui/deprecated.rs b/tests/ui/deprecated.rs index d3c34fb37167..389cc72e3720 100644 --- a/tests/ui/deprecated.rs +++ b/tests/ui/deprecated.rs @@ -20,5 +20,6 @@ #![warn(clippy::wrong_pub_self_convention)] #![warn(clippy::maybe_misused_cfg)] #![warn(clippy::mismatched_target_os)] +#![warn(clippy::float_cmp_const)] fn main() {} diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr index 49b90c70c06e..dd436744ee9e 100644 --- a/tests/ui/deprecated.stderr +++ b/tests/ui/deprecated.stderr @@ -109,5 +109,11 @@ error: lint `clippy::mismatched_target_os` has been removed: this lint has been LL | #![warn(clippy::mismatched_target_os)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 18 previous errors +error: lint `clippy::float_cmp_const` has been removed: `float_cmp` handles this via config options + --> tests/ui/deprecated.rs:23:9 + | +LL | #![warn(clippy::float_cmp_const)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 19 previous errors From 9d77810d755903a42806ba8dac4595be5fe981f8 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Wed, 6 Dec 2023 06:56:22 -0500 Subject: [PATCH 04/10] `float_cmp`: Don't lint literal to literal comparisons --- clippy_lints/src/operators/float_cmp.rs | 28 ++++++++----------- .../float_cmp_constant_comparisons/test.rs | 5 ++++ .../ui-toml/float_cmp_named_constants/test.rs | 5 ++++ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 39dab2b80b6f..8c4453cb8733 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -18,8 +18,17 @@ pub(crate) fn check<'tcx>( left: &'tcx Expr<'_>, right: &'tcx Expr<'_>, ) { - if (op == BinOpKind::Eq || op == BinOpKind::Ne) + let peel_expr = |e: &'tcx Expr<'tcx>| match e.kind { + ExprKind::Cast(e, _) | ExprKind::AddrOf(BorrowKind::Ref, _, e) | ExprKind::Unary(UnOp::Neg, e) => Some(e), + _ => None, + }; + + if matches!(op, BinOpKind::Eq | BinOpKind::Ne) + && let left = peel_hir_expr_while(left, peel_expr) + && let right = peel_hir_expr_while(right, peel_expr) && is_float(cx, left) + // Don't lint literal comparisons + && !(matches!(left.kind, ExprKind::Lit(_)) && matches!(right.kind, ExprKind::Lit(_))) // Allow comparing the results of signum() && !(is_signum(cx, left) && is_signum(cx, right)) { @@ -41,14 +50,7 @@ pub(crate) fn check<'tcx>( return; } - let peel_expr = |e: &'tcx Expr<'tcx>| match e.kind { - ExprKind::Cast(e, _) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => Some(e), - _ => None, - }; - if config.ignore_named_constants - && (is_expr_named_const(cx, peel_hir_expr_while(left, peel_expr)) - || is_expr_named_const(cx, peel_hir_expr_while(right, peel_expr))) - { + if config.ignore_named_constants && (is_expr_named_const(cx, left) || is_expr_named_const(cx, right)) { return; } @@ -106,16 +108,10 @@ fn is_allowed(val: &Constant<'_>) -> bool { // Return true if `expr` is the result of `signum()` invoked on a float value. fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - // The negation of a signum is still a signum - if let ExprKind::Unary(UnOp::Neg, child_expr) = expr.kind { - return is_signum(cx, child_expr); - } - if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind && sym!(signum) == method_name.ident.name - // Check that the receiver of the signum() is a float (expressions[0] is the receiver of - // the method call) { + // Check that the receiver of the signum() is a float return is_float(cx, self_arg); } false diff --git a/tests/ui-toml/float_cmp_constant_comparisons/test.rs b/tests/ui-toml/float_cmp_constant_comparisons/test.rs index 68cd0a08aa10..bbd33eb0f660 100644 --- a/tests/ui-toml/float_cmp_constant_comparisons/test.rs +++ b/tests/ui-toml/float_cmp_constant_comparisons/test.rs @@ -15,4 +15,9 @@ fn main() { } let _ = f(1.0) == f(2.0); } + { + let _ = 1.0f32 == 2.0f32; + let _ = -1.0f32 == -2.0f32; + let _ = 1.0f64 == 2.0f64; + } } diff --git a/tests/ui-toml/float_cmp_named_constants/test.rs b/tests/ui-toml/float_cmp_named_constants/test.rs index 68cd0a08aa10..bbd33eb0f660 100644 --- a/tests/ui-toml/float_cmp_named_constants/test.rs +++ b/tests/ui-toml/float_cmp_named_constants/test.rs @@ -15,4 +15,9 @@ fn main() { } let _ = f(1.0) == f(2.0); } + { + let _ = 1.0f32 == 2.0f32; + let _ = -1.0f32 == -2.0f32; + let _ = 1.0f64 == 2.0f64; + } } From cd6fc09caadcd87e7a1181d405b006a5b3a91cb7 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 8 Dec 2023 14:36:15 -0500 Subject: [PATCH 05/10] `float_cmp`: Ignore comparisons to detect if an operation changes the value. --- clippy_config/src/conf.rs | 12 ++ clippy_lints/src/operators/float_cmp.rs | 111 +++++++++++++++--- clippy_lints/src/operators/mod.rs | 3 +- .../float_cmp_change_detection/clippy.toml | 1 + .../float_cmp_change_detection/test.rs | 29 +++++ .../float_cmp_change_detection/test.stderr | 20 ++++ .../float_cmp_constant_comparisons/test.rs | 6 + .../ui-toml/float_cmp_named_constants/test.rs | 6 + .../toml_unknown_key/conf_unknown_key.stderr | 2 + tests/ui/float_cmp.rs | 68 +++++++++++ tests/ui/float_cmp.stderr | 26 +++- 11 files changed, 267 insertions(+), 17 deletions(-) create mode 100644 tests/ui-toml/float_cmp_change_detection/clippy.toml create mode 100644 tests/ui-toml/float_cmp_change_detection/test.rs create mode 100644 tests/ui-toml/float_cmp_change_detection/test.stderr diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 3ae0db886b2e..c2ea2fce0903 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -674,6 +674,18 @@ define_Conf! { /// } /// ``` (float_cmp_ignore_constant_comparisons: bool = true), + /// Lint: FLOAT_CMP + /// + /// Whether to ignore comparisons which check if an operation changes the value of it's operand. + /// + /// #### Example + /// ```no_run + /// fn f(x: f64) -> bool { + /// // Will warn if the config is `false` + /// x == x + 1.0 + /// } + /// ``` + (float_cmp_ignore_change_detection: bool = true), } /// Search for the configuration file. diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 8c4453cb8733..f34cfafd130e 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -1,12 +1,13 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::sugg::Sugg; -use clippy_utils::visitors::is_const_evaluatable; -use clippy_utils::{get_item_name, is_expr_named_const, peel_hir_expr_while}; +use clippy_utils::visitors::{for_each_expr_without_closures, is_const_evaluatable}; +use clippy_utils::{get_item_name, is_expr_named_const, peel_hir_expr_while, SpanlessEq}; +use core::ops::ControlFlow; use rustc_errors::Applicability; -use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, UnOp}; +use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, Safety, UnOp}; use rustc_lint::LateContext; -use rustc_middle::ty; +use rustc_middle::ty::{self, Ty, TypeFlags, TypeVisitableExt}; use super::{FloatCmpConfig, FLOAT_CMP}; @@ -24,33 +25,40 @@ pub(crate) fn check<'tcx>( }; if matches!(op, BinOpKind::Eq | BinOpKind::Ne) - && let left = peel_hir_expr_while(left, peel_expr) - && let right = peel_hir_expr_while(right, peel_expr) - && is_float(cx, left) + && let left_reduced = peel_hir_expr_while(left, peel_expr) + && let right_reduced = peel_hir_expr_while(right, peel_expr) + && is_float(cx, left_reduced) // Don't lint literal comparisons - && !(matches!(left.kind, ExprKind::Lit(_)) && matches!(right.kind, ExprKind::Lit(_))) + && !(matches!(left_reduced.kind, ExprKind::Lit(_)) && matches!(right_reduced.kind, ExprKind::Lit(_))) // Allow comparing the results of signum() - && !(is_signum(cx, left) && is_signum(cx, right)) + && !(is_signum(cx, left_reduced) && is_signum(cx, right_reduced)) { - let left_c = constant(cx, cx.typeck_results(), left); + let left_c = constant(cx, cx.typeck_results(), left_reduced); let is_left_const = left_c.is_some(); if left_c.is_some_and(|c| is_allowed(&c)) { return; } - let right_c = constant(cx, cx.typeck_results(), right); + let right_c = constant(cx, cx.typeck_results(), right_reduced); let is_right_const = right_c.is_some(); if right_c.is_some_and(|c| is_allowed(&c)) { return; } if config.ignore_constant_comparisons - && (is_left_const || is_const_evaluatable(cx, left)) - && (is_right_const || is_const_evaluatable(cx, right)) + && (is_left_const || is_const_evaluatable(cx, left_reduced)) + && (is_right_const || is_const_evaluatable(cx, right_reduced)) { return; } - if config.ignore_named_constants && (is_expr_named_const(cx, left) || is_expr_named_const(cx, right)) { + if config.ignore_named_constants && (is_expr_named_const(cx, left_reduced) || is_expr_named_const(cx, right_reduced)) { + return; + } + + if config.ignore_change_detection + && ((is_pure_expr(cx, left_reduced) && contains_expr(cx, right, left)) + || (is_pure_expr(cx, right_reduced) && contains_expr(cx, left, right))) + { return; } @@ -60,7 +68,7 @@ pub(crate) fn check<'tcx>( return; } } - let is_comparing_arrays = is_array(cx, left) || is_array(cx, right); + let is_comparing_arrays = is_array(cx, left_reduced) || is_array(cx, right_reduced); let msg = if is_comparing_arrays { "strict comparison of `f32` or `f64` arrays" } else { @@ -106,6 +114,79 @@ fn is_allowed(val: &Constant<'_>) -> bool { } } +// This is a best effort guess and may have false positives and negatives. +fn is_pure_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { + match e.kind { + ExprKind::Path(_) | ExprKind::Lit(_) => true, + ExprKind::Field(e, _) | ExprKind::Cast(e, _) | ExprKind::Repeat(e, _) => is_pure_expr(cx, e), + ExprKind::Tup(args) => args.iter().all(|arg| is_pure_expr(cx, arg)), + ExprKind::Struct(_, fields, base) => { + base.map_or(true, |base| is_pure_expr(cx, base)) && fields.iter().all(|f| is_pure_expr(cx, f.expr)) + }, + + // Since rust doesn't actually have the concept of a pure function we + // have to guess whether it's likely pure from the signature of the + // function. + ExprKind::Unary(_, e) => is_pure_arg_ty(cx, cx.typeck_results().expr_ty_adjusted(e)) && is_pure_expr(cx, e), + ExprKind::Binary(_, x, y) | ExprKind::Index(x, y, _) => { + is_pure_arg_ty(cx, cx.typeck_results().expr_ty_adjusted(x)) + && is_pure_arg_ty(cx, cx.typeck_results().expr_ty_adjusted(y)) + && is_pure_expr(cx, x) + && is_pure_expr(cx, y) + }, + ExprKind::MethodCall(_, recv, args, _) => { + is_pure_arg_ty(cx, cx.typeck_results().expr_ty_adjusted(recv)) + && is_pure_expr(cx, recv) + && cx + .typeck_results() + .type_dependent_def_id(e.hir_id) + .is_some_and(|did| matches!(cx.tcx.fn_sig(did).skip_binder().skip_binder().safety, Safety::Safe)) + && args + .iter() + .all(|arg| is_pure_arg_ty(cx, cx.typeck_results().expr_ty_adjusted(arg)) && is_pure_expr(cx, arg)) + }, + ExprKind::Call(f, args @ [_, ..]) => { + is_pure_expr(cx, f) + && is_pure_fn_ty(cx, cx.typeck_results().expr_ty_adjusted(f)) + && args + .iter() + .all(|arg| is_pure_arg_ty(cx, cx.typeck_results().expr_ty_adjusted(arg)) && is_pure_expr(cx, arg)) + }, + + _ => false, + } +} + +fn is_pure_fn_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + let sig = match *ty.peel_refs().kind() { + ty::FnDef(did, _) => cx.tcx.fn_sig(did).skip_binder(), + ty::FnPtr(sig) => sig, + ty::Closure(_, args) => { + return args.as_closure().upvar_tys().iter().all(|ty| is_pure_arg_ty(cx, ty)); + }, + _ => return false, + }; + matches!(sig.skip_binder().safety, Safety::Safe) +} + +fn is_pure_arg_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + !ty.is_mutable_ptr() + && ty.is_copy_modulo_regions(cx.tcx, cx.param_env) + && (ty.peel_refs().is_freeze(cx.tcx, cx.param_env) + || !ty.has_type_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_ERASED | TypeFlags::HAS_RE_BOUND)) +} + +fn contains_expr<'tcx>(cx: &LateContext<'tcx>, corpus: &'tcx Expr<'tcx>, e: &'tcx Expr<'tcx>) -> bool { + for_each_expr_without_closures(corpus, |corpus| { + if SpanlessEq::new(cx).eq_expr(corpus, e) { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + }) + .is_some() +} + // Return true if `expr` is the result of `signum()` invoked on a float value. fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 0b3eec91c052..6bb52a0ccf65 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -778,6 +778,7 @@ declare_clippy_lint! { struct FloatCmpConfig { ignore_named_constants: bool, ignore_constant_comparisons: bool, + ignore_change_detection: bool, } pub struct Operators { @@ -795,6 +796,7 @@ impl Operators { float_cmp_config: FloatCmpConfig { ignore_named_constants: conf.float_cmp_ignore_named_constants, ignore_constant_comparisons: conf.float_cmp_ignore_constant_comparisons, + ignore_change_detection: conf.float_cmp_ignore_change_detection, }, } } @@ -827,7 +829,6 @@ impl_lint_pass!(Operators => [ PTR_EQ, SELF_ASSIGNMENT, ]); - impl<'tcx> LateLintPass<'tcx> for Operators { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { eq_op::check_assert(cx, e); diff --git a/tests/ui-toml/float_cmp_change_detection/clippy.toml b/tests/ui-toml/float_cmp_change_detection/clippy.toml new file mode 100644 index 000000000000..c78367975726 --- /dev/null +++ b/tests/ui-toml/float_cmp_change_detection/clippy.toml @@ -0,0 +1 @@ +float-cmp-ignore-change-detection = false diff --git a/tests/ui-toml/float_cmp_change_detection/test.rs b/tests/ui-toml/float_cmp_change_detection/test.rs new file mode 100644 index 000000000000..65f6b9edecc3 --- /dev/null +++ b/tests/ui-toml/float_cmp_change_detection/test.rs @@ -0,0 +1,29 @@ +//@no-rustfix + +#![deny(clippy::float_cmp)] + +fn main() { + { + const C: f64 = 1.0; + fn f(x: f64) { + let _ = x == C; + } + } + { + const fn f(x: f64) -> f64 { + todo!() + } + let _ = f(1.0) == f(2.0); + } + { + let _ = 1.0f32 == 2.0f32; + let _ = -1.0f32 == -2.0f32; + let _ = 1.0f64 == 2.0f64; + } + { + fn f(x: f32) { + let _ = x + 1.0 == x; + let _ = x == x + 1.0; + } + } +} diff --git a/tests/ui-toml/float_cmp_change_detection/test.stderr b/tests/ui-toml/float_cmp_change_detection/test.stderr new file mode 100644 index 000000000000..00c36fef8c57 --- /dev/null +++ b/tests/ui-toml/float_cmp_change_detection/test.stderr @@ -0,0 +1,20 @@ +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp_change_detection/test.rs:25:21 + | +LL | let _ = x + 1.0 == x; + | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x + 1.0 - x).abs() < error_margin` + | +note: the lint level is defined here + --> tests/ui-toml/float_cmp_change_detection/test.rs:3:9 + | +LL | #![deny(clippy::float_cmp)] + | ^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp_change_detection/test.rs:26:21 + | +LL | let _ = x == x + 1.0; + | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - (x + 1.0)).abs() < error_margin` + +error: aborting due to 2 previous errors + diff --git a/tests/ui-toml/float_cmp_constant_comparisons/test.rs b/tests/ui-toml/float_cmp_constant_comparisons/test.rs index bbd33eb0f660..65f6b9edecc3 100644 --- a/tests/ui-toml/float_cmp_constant_comparisons/test.rs +++ b/tests/ui-toml/float_cmp_constant_comparisons/test.rs @@ -20,4 +20,10 @@ fn main() { let _ = -1.0f32 == -2.0f32; let _ = 1.0f64 == 2.0f64; } + { + fn f(x: f32) { + let _ = x + 1.0 == x; + let _ = x == x + 1.0; + } + } } diff --git a/tests/ui-toml/float_cmp_named_constants/test.rs b/tests/ui-toml/float_cmp_named_constants/test.rs index bbd33eb0f660..65f6b9edecc3 100644 --- a/tests/ui-toml/float_cmp_named_constants/test.rs +++ b/tests/ui-toml/float_cmp_named_constants/test.rs @@ -20,4 +20,10 @@ fn main() { let _ = -1.0f32 == -2.0f32; let _ = 1.0f64 == 2.0f64; } + { + fn f(x: f32) { + let _ = x + 1.0 == x; + let _ = x == x + 1.0; + } + } } diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 298d29015fc6..caeb65153d52 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -42,6 +42,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-ignore-change-detection float-cmp-ignore-constant-comparisons float-cmp-ignore-named-constants future-size-threshold @@ -128,6 +129,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-ignore-change-detection float-cmp-ignore-constant-comparisons float-cmp-ignore-named-constants future-size-threshold diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs index d64de06f1c3d..5aa338496a9a 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -272,4 +272,72 @@ fn main() { let _ = x == y; } } + + // modified operands + { + fn f1(x: f32) -> f32 { + x + 1.0 + } + + fn f2(x: f32, y: f32) -> f32 { + x + y + } + + fn _f(x: f32, y: f32) { + let _ = x == x + 1.0; + let _ = x + 1.0 == x; + let _ = -x == -x + 1.0; + let _ = -x + 1.0 == -x; + let _ = x == f1(x); + let _ = f1(x) == x; + let _ = x == f2(x, y); + let _ = f2(x, y) == x; + let _ = f1(f1(x)) == f1(x); + let _ = f1(x) == f1(f1(x)); + + let z = (x, y); + let _ = z.0 == z.0 + 1.0; + let _ = z.0 + 1.0 == z.0; + } + + fn _f2(x: &f32) { + let _ = *x + 1.0 == *x; + let _ = *x == *x + 1.0; + let _ = *x == f1(*x); + let _ = f1(*x) == *x; + } + } + { + fn _f(mut x: impl Iterator) { + let _ = x.next().unwrap() == x.next().unwrap() + 1.0; + //~^ ERROR: strict comparison of `f32` or `f64` + } + } + { + use core::cell::RefCell; + + struct S(RefCell); + impl S { + fn f(&self) -> f32 { + let x = *self.0.borrow(); + *self.0.borrow_mut() *= 2.0; + x + } + } + + fn _f(x: S) { + let _ = x.f() + 1.0 == x.f(); + //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x.f() == x.f() + 1.0; + //~^ ERROR: strict comparison of `f32` or `f64` + } + } + { + let f = |x: f32| -> f32 { x }; + let _ = f(1.0) == f(1.0) + 1.0; + + let mut x = 1.0; + let mut f = |y: f32| -> f32 { core::mem::replace(&mut x, y) }; + let _ = f(1.0) == f(1.0) + 1.0; //~ float_cmp + } } diff --git a/tests/ui/float_cmp.stderr b/tests/ui/float_cmp.stderr index 0e3e6cc8b603..f5b7376c4a47 100644 --- a/tests/ui/float_cmp.stderr +++ b/tests/ui/float_cmp.stderr @@ -163,5 +163,29 @@ error: strict comparison of `f32` or `f64` LL | let _ = C[1] == x; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` -error: aborting due to 27 previous errors +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:312:21 + | +LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:329:21 + | +LL | let _ = x.f() + 1.0 == x.f(); + | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:331:21 + | +LL | let _ = x.f() == x.f() + 1.0; + | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui/float_cmp.rs:341:17 + | +LL | let _ = f(1.0) == f(1.0) + 1.0; + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` + +error: aborting due to 31 previous errors From e911f0aa7752da055107fe3895cac22d4574909c Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 7 Jun 2024 14:07:55 -0400 Subject: [PATCH 06/10] `float_cmp`: Don't lint self comparisons. --- clippy_lints/src/operators/float_cmp.rs | 13 ++++++++++--- tests/ui-toml/float_cmp_change_detection/test.rs | 11 +++++++++++ .../ui-toml/float_cmp_change_detection/test.stderr | 4 ++-- .../ui-toml/float_cmp_constant_comparisons/test.rs | 11 +++++++++++ .../float_cmp_constant_comparisons/test.stderr | 2 +- tests/ui-toml/float_cmp_named_constants/test.rs | 11 +++++++++++ .../ui-toml/float_cmp_named_constants/test.stderr | 2 +- .../toml_unknown_key/conf_unknown_key.stderr | 1 + tests/ui/float_cmp.rs | 14 +++++++++++++- 9 files changed, 61 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index f34cfafd130e..986e221fca3a 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -2,9 +2,10 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::sugg::Sugg; use clippy_utils::visitors::{for_each_expr_without_closures, is_const_evaluatable}; -use clippy_utils::{get_item_name, is_expr_named_const, peel_hir_expr_while, SpanlessEq}; +use clippy_utils::{get_item_name, is_expr_named_const, path_res, peel_hir_expr_while, SpanlessEq}; use core::ops::ControlFlow; use rustc_errors::Applicability; +use rustc_hir::def::Res; use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, Safety, UnOp}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty, TypeFlags, TypeVisitableExt}; @@ -32,6 +33,10 @@ pub(crate) fn check<'tcx>( && !(matches!(left_reduced.kind, ExprKind::Lit(_)) && matches!(right_reduced.kind, ExprKind::Lit(_))) // Allow comparing the results of signum() && !(is_signum(cx, left_reduced) && is_signum(cx, right_reduced)) + && match (path_res(cx, left_reduced), path_res(cx, right_reduced)) { + (Res::Err, _) | (_, Res::Err) => true, + (left, right) => left != right, + } { let left_c = constant(cx, cx.typeck_results(), left_reduced); let is_left_const = left_c.is_some(); @@ -51,7 +56,9 @@ pub(crate) fn check<'tcx>( return; } - if config.ignore_named_constants && (is_expr_named_const(cx, left_reduced) || is_expr_named_const(cx, right_reduced)) { + if config.ignore_named_constants + && (is_expr_named_const(cx, left_reduced) || is_expr_named_const(cx, right_reduced)) + { return; } @@ -64,7 +71,7 @@ pub(crate) fn check<'tcx>( if let Some(name) = get_item_name(cx, expr) { let name = name.as_str(); - if name == "eq" || name == "ne" || name == "is_nan" || name.starts_with("eq_") || name.ends_with("_eq") { + if name == "eq" || name == "ne" || name.starts_with("eq_") || name.ends_with("_eq") { return; } } diff --git a/tests/ui-toml/float_cmp_change_detection/test.rs b/tests/ui-toml/float_cmp_change_detection/test.rs index 65f6b9edecc3..c16776e104e3 100644 --- a/tests/ui-toml/float_cmp_change_detection/test.rs +++ b/tests/ui-toml/float_cmp_change_detection/test.rs @@ -1,6 +1,7 @@ //@no-rustfix #![deny(clippy::float_cmp)] +#![allow(clippy::op_ref, clippy::eq_op)] fn main() { { @@ -26,4 +27,14 @@ fn main() { let _ = x == x + 1.0; } } + { + fn _f(x: f32) { + let _ = x == x; + let _ = x != x; + let _ = x == -x; + let _ = -x == x; + let _ = x as f64 == x as f64; + let _ = &&x == &&x; + } + } } diff --git a/tests/ui-toml/float_cmp_change_detection/test.stderr b/tests/ui-toml/float_cmp_change_detection/test.stderr index 00c36fef8c57..7bbe9713f56a 100644 --- a/tests/ui-toml/float_cmp_change_detection/test.stderr +++ b/tests/ui-toml/float_cmp_change_detection/test.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp_change_detection/test.rs:25:21 + --> tests/ui-toml/float_cmp_change_detection/test.rs:26:21 | LL | let _ = x + 1.0 == x; | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x + 1.0 - x).abs() < error_margin` @@ -11,7 +11,7 @@ LL | #![deny(clippy::float_cmp)] | ^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp_change_detection/test.rs:26:21 + --> tests/ui-toml/float_cmp_change_detection/test.rs:27:21 | LL | let _ = x == x + 1.0; | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - (x + 1.0)).abs() < error_margin` diff --git a/tests/ui-toml/float_cmp_constant_comparisons/test.rs b/tests/ui-toml/float_cmp_constant_comparisons/test.rs index 65f6b9edecc3..c16776e104e3 100644 --- a/tests/ui-toml/float_cmp_constant_comparisons/test.rs +++ b/tests/ui-toml/float_cmp_constant_comparisons/test.rs @@ -1,6 +1,7 @@ //@no-rustfix #![deny(clippy::float_cmp)] +#![allow(clippy::op_ref, clippy::eq_op)] fn main() { { @@ -26,4 +27,14 @@ fn main() { let _ = x == x + 1.0; } } + { + fn _f(x: f32) { + let _ = x == x; + let _ = x != x; + let _ = x == -x; + let _ = -x == x; + let _ = x as f64 == x as f64; + let _ = &&x == &&x; + } + } } diff --git a/tests/ui-toml/float_cmp_constant_comparisons/test.stderr b/tests/ui-toml/float_cmp_constant_comparisons/test.stderr index 919ae8d66721..7f6db02b485d 100644 --- a/tests/ui-toml/float_cmp_constant_comparisons/test.stderr +++ b/tests/ui-toml/float_cmp_constant_comparisons/test.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp_constant_comparisons/test.rs:16:17 + --> tests/ui-toml/float_cmp_constant_comparisons/test.rs:17:17 | LL | let _ = f(1.0) == f(2.0); | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(2.0)).abs() < error_margin` diff --git a/tests/ui-toml/float_cmp_named_constants/test.rs b/tests/ui-toml/float_cmp_named_constants/test.rs index 65f6b9edecc3..c16776e104e3 100644 --- a/tests/ui-toml/float_cmp_named_constants/test.rs +++ b/tests/ui-toml/float_cmp_named_constants/test.rs @@ -1,6 +1,7 @@ //@no-rustfix #![deny(clippy::float_cmp)] +#![allow(clippy::op_ref, clippy::eq_op)] fn main() { { @@ -26,4 +27,14 @@ fn main() { let _ = x == x + 1.0; } } + { + fn _f(x: f32) { + let _ = x == x; + let _ = x != x; + let _ = x == -x; + let _ = -x == x; + let _ = x as f64 == x as f64; + let _ = &&x == &&x; + } + } } diff --git a/tests/ui-toml/float_cmp_named_constants/test.stderr b/tests/ui-toml/float_cmp_named_constants/test.stderr index 64e237333336..74036b354cd6 100644 --- a/tests/ui-toml/float_cmp_named_constants/test.stderr +++ b/tests/ui-toml/float_cmp_named_constants/test.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp_named_constants/test.rs:9:21 + --> tests/ui-toml/float_cmp_named_constants/test.rs:10:21 | LL | let _ = x == C; | ^^^^^^ help: consider comparing them within some margin of error: `(x - C).abs() < error_margin` diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index caeb65153d52..56b80b0ed2c6 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -216,6 +216,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-ignore-change-detection float-cmp-ignore-constant-comparisons float-cmp-ignore-named-constants future-size-threshold diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs index 5aa338496a9a..25ed439753a6 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -3,7 +3,7 @@ // FIXME(f16_f128): const casting is not yet supported for these types. Add when available. #![warn(clippy::float_cmp)] -#![allow(clippy::op_ref)] +#![allow(clippy::op_ref, clippy::eq_op)] fn main() { { @@ -340,4 +340,16 @@ fn main() { let mut f = |y: f32| -> f32 { core::mem::replace(&mut x, y) }; let _ = f(1.0) == f(1.0) + 1.0; //~ float_cmp } + + // Self comparisons + { + fn _f(x: f32) { + let _ = x == x; + let _ = x != x; + let _ = x == -x; + let _ = -x == x; + let _ = x as f64 == x as f64; + let _ = &&x == &&x; + } + } } From 72f80715700104120c0055abe4d7fdaacb37a3d1 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 12 Jul 2024 21:23:24 -0400 Subject: [PATCH 07/10] Merge `float_cmp` tests --- .../change_detect}/clippy.toml | 0 .../const_cmp}/clippy.toml | 0 .../named_const}/clippy.toml | 0 .../float_cmp/test.change_detect.stderr | 296 ++++++++++++++++++ .../float_cmp/test.const_cmp.stderr} | 89 ++++-- .../ui-toml/float_cmp/test.named_const.stderr | 254 +++++++++++++++ .../float_cmp/test.rs} | 158 ++++------ .../float_cmp_change_detection/test.rs | 40 --- .../float_cmp_change_detection/test.stderr | 20 -- .../float_cmp_constant_comparisons/test.rs | 40 --- .../test.stderr | 14 - .../ui-toml/float_cmp_named_constants/test.rs | 40 --- .../float_cmp_named_constants/test.stderr | 14 - 13 files changed, 670 insertions(+), 295 deletions(-) rename tests/ui-toml/{float_cmp_change_detection => float_cmp/change_detect}/clippy.toml (100%) rename tests/ui-toml/{float_cmp_constant_comparisons => float_cmp/const_cmp}/clippy.toml (100%) rename tests/ui-toml/{float_cmp_named_constants => float_cmp/named_const}/clippy.toml (100%) create mode 100644 tests/ui-toml/float_cmp/test.change_detect.stderr rename tests/{ui/float_cmp.stderr => ui-toml/float_cmp/test.const_cmp.stderr} (71%) create mode 100644 tests/ui-toml/float_cmp/test.named_const.stderr rename tests/{ui/float_cmp.rs => ui-toml/float_cmp/test.rs} (61%) delete mode 100644 tests/ui-toml/float_cmp_change_detection/test.rs delete mode 100644 tests/ui-toml/float_cmp_change_detection/test.stderr delete mode 100644 tests/ui-toml/float_cmp_constant_comparisons/test.rs delete mode 100644 tests/ui-toml/float_cmp_constant_comparisons/test.stderr delete mode 100644 tests/ui-toml/float_cmp_named_constants/test.rs delete mode 100644 tests/ui-toml/float_cmp_named_constants/test.stderr diff --git a/tests/ui-toml/float_cmp_change_detection/clippy.toml b/tests/ui-toml/float_cmp/change_detect/clippy.toml similarity index 100% rename from tests/ui-toml/float_cmp_change_detection/clippy.toml rename to tests/ui-toml/float_cmp/change_detect/clippy.toml diff --git a/tests/ui-toml/float_cmp_constant_comparisons/clippy.toml b/tests/ui-toml/float_cmp/const_cmp/clippy.toml similarity index 100% rename from tests/ui-toml/float_cmp_constant_comparisons/clippy.toml rename to tests/ui-toml/float_cmp/const_cmp/clippy.toml diff --git a/tests/ui-toml/float_cmp_named_constants/clippy.toml b/tests/ui-toml/float_cmp/named_const/clippy.toml similarity index 100% rename from tests/ui-toml/float_cmp_named_constants/clippy.toml rename to tests/ui-toml/float_cmp/named_const/clippy.toml diff --git a/tests/ui-toml/float_cmp/test.change_detect.stderr b/tests/ui-toml/float_cmp/test.change_detect.stderr new file mode 100644 index 000000000000..e212739c7afe --- /dev/null +++ b/tests/ui-toml/float_cmp/test.change_detect.stderr @@ -0,0 +1,296 @@ +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:15:21 + | +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` + | +note: the lint level is defined here + --> tests/ui-toml/float_cmp/test.rs:9:9 + | +LL | #![deny(clippy::float_cmp)] + | ^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:16:21 + | +LL | let _ = x != y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:17:21 + | +LL | let _ = x == 5.5; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:18:21 + | +LL | let _ = 5.5 == x; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:41:21 + | +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:42:21 + | +LL | let _ = x != y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:43:21 + | +LL | let _ = x == 5.5; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:44:21 + | +LL | let _ = 5.5 == x; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:67:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:68:21 + | +LL | let _ = x == [5.5; 4]; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:69:21 + | +LL | let _ = [5.5; 4] == x; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:70:21 + | +LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:71:21 + | +LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:87:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:88:21 + | +LL | let _ = x == [5.5; 4]; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:89:21 + | +LL | let _ = [5.5; 4] == x; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:90:21 + | +LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:91:21 + | +LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:109:21 + | +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:115:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:131:21 + | +LL | let _ = C * x == x * x; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C * x - x * x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:132:21 + | +LL | let _ = x * x == C * x; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - C * x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:158:17 + | +LL | let _ = f(1.0) == f(5.0); + | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:159:17 + | +LL | let _ = 1.0 == f(5.0); + | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:160:17 + | +LL | let _ = f(1.0) + 1.0 != 5.0; + | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:202:21 + | +LL | let _ = x == C[1]; + | ^^^^^^^^^ help: consider comparing them within some margin of error: `(x - C[1]).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:203:21 + | +LL | let _ = C[1] == x; + | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:262:21 + | +LL | let _ = x == x + 1.0; + | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - (x + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:263:21 + | +LL | let _ = x + 1.0 == x; + | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x + 1.0 - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:264:21 + | +LL | let _ = -x == -x + 1.0; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(-x - (-x + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:265:21 + | +LL | let _ = -x + 1.0 == -x; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(-x + 1.0 - -x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:266:21 + | +LL | let _ = x == f1(x); + | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - f1(x)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:267:21 + | +LL | let _ = f1(x) == x; + | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(x) - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:268:21 + | +LL | let _ = x == f2(x, y); + | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - f2(x, y)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:269:21 + | +LL | let _ = f2(x, y) == x; + | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f2(x, y) - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:270:21 + | +LL | let _ = f1(f1(x)) == f1(x); + | ^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(f1(x)) - f1(x)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:271:21 + | +LL | let _ = f1(x) == f1(f1(x)); + | ^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(x) - f1(f1(x))).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:274:21 + | +LL | let _ = z.0 == z.0 + 1.0; + | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(z.0 - (z.0 + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:275:21 + | +LL | let _ = z.0 + 1.0 == z.0; + | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(z.0 + 1.0 - z.0).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:279:21 + | +LL | let _ = *x + 1.0 == *x; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x + 1.0 - *x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:280:21 + | +LL | let _ = *x == *x + 1.0; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x - (*x + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:281:21 + | +LL | let _ = *x == f1(*x); + | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x - f1(*x)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:282:21 + | +LL | let _ = f1(*x) == *x; + | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(*x) - *x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:287:21 + | +LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:303:21 + | +LL | let _ = x.f() + 1.0 == x.f(); + | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:304:21 + | +LL | let _ = x.f() == x.f() + 1.0; + | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:309:17 + | +LL | let _ = f(1.0) == f(1.0) + 1.0; + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:313:17 + | +LL | let _ = f(1.0) == f(1.0) + 1.0; + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` + +error: aborting due to 48 previous errors + diff --git a/tests/ui/float_cmp.stderr b/tests/ui-toml/float_cmp/test.const_cmp.stderr similarity index 71% rename from tests/ui/float_cmp.stderr rename to tests/ui-toml/float_cmp/test.const_cmp.stderr index f5b7376c4a47..584b68caaae6 100644 --- a/tests/ui/float_cmp.stderr +++ b/tests/ui-toml/float_cmp/test.const_cmp.stderr @@ -1,191 +1,212 @@ error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:11:21 + --> tests/ui-toml/float_cmp/test.rs:15:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` | - = note: `-D clippy::float-cmp` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::float_cmp)]` +note: the lint level is defined here + --> tests/ui-toml/float_cmp/test.rs:9:9 + | +LL | #![deny(clippy::float_cmp)] + | ^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:13:21 + --> tests/ui-toml/float_cmp/test.rs:16:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:15:21 + --> tests/ui-toml/float_cmp/test.rs:17:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:17:21 + --> tests/ui-toml/float_cmp/test.rs:18:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:41:21 + --> tests/ui-toml/float_cmp/test.rs:41:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:43:21 + --> tests/ui-toml/float_cmp/test.rs:42:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:45:21 + --> tests/ui-toml/float_cmp/test.rs:43:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:47:21 + --> tests/ui-toml/float_cmp/test.rs:44:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:71:21 + --> tests/ui-toml/float_cmp/test.rs:67:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:73:21 + --> tests/ui-toml/float_cmp/test.rs:68:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:75:21 + --> tests/ui-toml/float_cmp/test.rs:69:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:77:21 + --> tests/ui-toml/float_cmp/test.rs:70:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:79:21 + --> tests/ui-toml/float_cmp/test.rs:71:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:96:21 + --> tests/ui-toml/float_cmp/test.rs:87:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:98:21 + --> tests/ui-toml/float_cmp/test.rs:88:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:100:21 + --> tests/ui-toml/float_cmp/test.rs:89:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:102:21 + --> tests/ui-toml/float_cmp/test.rs:90:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:104:21 + --> tests/ui-toml/float_cmp/test.rs:91:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:123:21 + --> tests/ui-toml/float_cmp/test.rs:109:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:131:21 + --> tests/ui-toml/float_cmp/test.rs:115:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:149:21 + --> tests/ui-toml/float_cmp/test.rs:131:21 | LL | let _ = C * x == x * x; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C * x - x * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:151:21 + --> tests/ui-toml/float_cmp/test.rs:132:21 | LL | let _ = x * x == C * x; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - C * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:178:17 + --> tests/ui-toml/float_cmp/test.rs:150:17 + | +LL | let _ = f(1.0) == f(5.0); + | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:151:17 + | +LL | let _ = 1.0 == f(5.0); + | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:152:17 + | +LL | let _ = f(1.0) + 1.0 != 5.0; + | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:158:17 | LL | let _ = f(1.0) == f(5.0); | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:180:17 + --> tests/ui-toml/float_cmp/test.rs:159:17 | LL | let _ = 1.0 == f(5.0); | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:182:17 + --> tests/ui-toml/float_cmp/test.rs:160:17 | LL | let _ = f(1.0) + 1.0 != 5.0; | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:225:21 + --> tests/ui-toml/float_cmp/test.rs:202:21 | LL | let _ = x == C[1]; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(x - C[1]).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:227:21 + --> tests/ui-toml/float_cmp/test.rs:203:21 | LL | let _ = C[1] == x; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:312:21 + --> tests/ui-toml/float_cmp/test.rs:287:21 | LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:329:21 + --> tests/ui-toml/float_cmp/test.rs:303:21 | LL | let _ = x.f() + 1.0 == x.f(); | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:331:21 + --> tests/ui-toml/float_cmp/test.rs:304:21 | LL | let _ = x.f() == x.f() + 1.0; | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:341:17 + --> tests/ui-toml/float_cmp/test.rs:313:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` -error: aborting due to 31 previous errors +error: aborting due to 34 previous errors diff --git a/tests/ui-toml/float_cmp/test.named_const.stderr b/tests/ui-toml/float_cmp/test.named_const.stderr new file mode 100644 index 000000000000..eb49aff7b280 --- /dev/null +++ b/tests/ui-toml/float_cmp/test.named_const.stderr @@ -0,0 +1,254 @@ +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:15:21 + | +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` + | +note: the lint level is defined here + --> tests/ui-toml/float_cmp/test.rs:9:9 + | +LL | #![deny(clippy::float_cmp)] + | ^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:16:21 + | +LL | let _ = x != y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:17:21 + | +LL | let _ = x == 5.5; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:18:21 + | +LL | let _ = 5.5 == x; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:41:21 + | +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:42:21 + | +LL | let _ = x != y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:43:21 + | +LL | let _ = x == 5.5; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:44:21 + | +LL | let _ = 5.5 == x; + | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:67:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:68:21 + | +LL | let _ = x == [5.5; 4]; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:69:21 + | +LL | let _ = [5.5; 4] == x; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:70:21 + | +LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:71:21 + | +LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:87:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:88:21 + | +LL | let _ = x == [5.5; 4]; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:89:21 + | +LL | let _ = [5.5; 4] == x; + | ^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:90:21 + | +LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:91:21 + | +LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:109:21 + | +LL | let _ = x == y; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:115:21 + | +LL | let _ = x == y; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:124:21 + | +LL | let _ = x == C; + | ^^^^^^ help: consider comparing them within some margin of error: `(x - C).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:125:21 + | +LL | let _ = C == x; + | ^^^^^^ help: consider comparing them within some margin of error: `(C - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:126:21 + | +LL | let _ = &&x == &&C; + | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(&&x - &&C).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:127:21 + | +LL | let _ = &&C == &&x; + | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(&&C - &&x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:128:21 + | +LL | let _ = y == C as f64; + | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(y - C as f64).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:129:21 + | +LL | let _ = C as f64 == y; + | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C as f64 - y).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:131:21 + | +LL | let _ = C * x == x * x; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C * x - x * x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:132:21 + | +LL | let _ = x * x == C * x; + | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - C * x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:138:21 + | +LL | let _ = x == C; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:139:21 + | +LL | let _ = C == x; + | ^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:140:21 + | +LL | let _ = &&x == &&C; + | ^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` arrays + --> tests/ui-toml/float_cmp/test.rs:141:21 + | +LL | let _ = &&C == &&x; + | ^^^^^^^^^^ + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:158:17 + | +LL | let _ = f(1.0) == f(5.0); + | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:159:17 + | +LL | let _ = 1.0 == f(5.0); + | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:160:17 + | +LL | let _ = f(1.0) + 1.0 != 5.0; + | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:202:21 + | +LL | let _ = x == C[1]; + | ^^^^^^^^^ help: consider comparing them within some margin of error: `(x - C[1]).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:203:21 + | +LL | let _ = C[1] == x; + | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:287:21 + | +LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:303:21 + | +LL | let _ = x.f() + 1.0 == x.f(); + | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:304:21 + | +LL | let _ = x.f() == x.f() + 1.0; + | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:313:17 + | +LL | let _ = f(1.0) == f(1.0) + 1.0; + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` + +error: aborting due to 41 previous errors + diff --git a/tests/ui/float_cmp.rs b/tests/ui-toml/float_cmp/test.rs similarity index 61% rename from tests/ui/float_cmp.rs rename to tests/ui-toml/float_cmp/test.rs index 25ed439753a6..443064b45733 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui-toml/float_cmp/test.rs @@ -1,21 +1,21 @@ //@no-rustfix +//@revisions: change_detect const_cmp named_const +//@[change_detect] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/float_cmp/change_detect +//@[const_cmp] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/float_cmp/const_cmp +//@[named_const] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/float_cmp/named_const // FIXME(f16_f128): const casting is not yet supported for these types. Add when available. -#![warn(clippy::float_cmp)] +#![deny(clippy::float_cmp)] #![allow(clippy::op_ref, clippy::eq_op)] fn main() { { fn _f(x: f32, y: f32) { - let _ = x == y; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x != y; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x == 5.5; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = 5.5 == x; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == y; //~ float_cmp + let _ = x != y; //~ float_cmp + let _ = x == 5.5; //~ float_cmp + let _ = 5.5 == x; //~ float_cmp let _ = x < 5.5; let _ = x <= 5.5; @@ -38,14 +38,10 @@ fn main() { } { fn _f(x: f64, y: f64) { - let _ = x == y; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x != y; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x == 5.5; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = 5.5 == x; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == y; //~ float_cmp + let _ = x != y; //~ float_cmp + let _ = x == 5.5; //~ float_cmp + let _ = 5.5 == x; //~ float_cmp let _ = x < 5.5; let _ = x <= 5.5; @@ -68,16 +64,11 @@ fn main() { } { fn _f(x: [f32; 4], y: [f32; 4]) { - let _ = x == y; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x == [5.5; 4]; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = [5.5; 4] == x; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = [0.0, 0.0, 0.0, 5.5] == x; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x == [0.0, 0.0, 0.0, 5.5]; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == y; //~ float_cmp + let _ = x == [5.5; 4]; //~ float_cmp + let _ = [5.5; 4] == x; //~ float_cmp + let _ = [0.0, 0.0, 0.0, 5.5] == x; //~ float_cmp + let _ = x == [0.0, 0.0, 0.0, 5.5]; //~ float_cmp let _ = [0.0; 4] == x; let _ = [-0.0; 4] == x; @@ -93,16 +84,11 @@ fn main() { } { fn _f(x: [f64; 4], y: [f64; 4]) { - let _ = x == y; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x == [5.5; 4]; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = [5.5; 4] == x; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = [0.0, 0.0, 0.0, 5.5] == x; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x == [0.0, 0.0, 0.0, 5.5]; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == y; //~ float_cmp + let _ = x == [5.5; 4]; //~ float_cmp + let _ = [5.5; 4] == x; //~ float_cmp + let _ = [0.0, 0.0, 0.0, 5.5] == x; //~ float_cmp + let _ = x == [0.0, 0.0, 0.0, 5.5]; //~ float_cmp let _ = [0.0; 4] == x; let _ = [-0.0; 4] == x; @@ -120,17 +106,13 @@ fn main() { // Reference comparisons { fn _f(x: &&&f32, y: &&&f32) { - let _ = x == y; - //~^ ERROR: strict comparison of `f32` or `f64` - + let _ = x == y; //~ float_cmp let _ = x == &&&0.0; } } { fn _f(x: &&&[f32; 2], y: &&&[f32; 2]) { - let _ = x == y; - //~^ ERROR: strict comparison of `f32` or `f64` - + let _ = x == y; //~ float_cmp let _ = x == &&&[0.0, -0.0]; } } @@ -139,26 +121,24 @@ fn main() { { const C: f32 = 5.5; fn _f(x: f32, y: f64) { - let _ = x == C; - let _ = C == x; - let _ = &&x == &&C; - let _ = &&C == &&x; - let _ = y == C as f64; - let _ = C as f64 == y; - - let _ = C * x == x * x; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x * x == C * x; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == C; //~[named_const] float_cmp + let _ = C == x; //~[named_const] float_cmp + let _ = &&x == &&C; //~[named_const] float_cmp + let _ = &&C == &&x; //~[named_const] float_cmp + let _ = y == C as f64; //~[named_const] float_cmp + let _ = C as f64 == y; //~[named_const] float_cmp + + let _ = C * x == x * x; //~ float_cmp + let _ = x * x == C * x; //~ float_cmp } } { const C: [f32; 2] = [5.5, 5.5]; fn _f(x: [f32; 2]) { - let _ = x == C; - let _ = C == x; - let _ = &&x == &&C; - let _ = &&C == &&x; + let _ = x == C; //~[named_const] float_cmp + let _ = C == x; //~[named_const] float_cmp + let _ = &&x == &&C; //~[named_const] float_cmp + let _ = &&C == &&x; //~[named_const] float_cmp } } @@ -167,20 +147,17 @@ fn main() { const fn f(x: f32) -> f32 { todo!() } - let _ = f(1.0) == f(5.0); - let _ = 1.0 == f(5.0); - let _ = f(1.0) + 1.0 != 5.0; + let _ = f(1.0) == f(5.0); //~[const_cmp] float_cmp + let _ = 1.0 == f(5.0); //~[const_cmp] float_cmp + let _ = f(1.0) + 1.0 != 5.0; //~[const_cmp] float_cmp } { fn f(x: f32) -> f32 { todo!() } - let _ = f(1.0) == f(5.0); - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = 1.0 == f(5.0); - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = f(1.0) + 1.0 != 5.0; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = f(1.0) == f(5.0); //~ float_cmp + let _ = 1.0 == f(5.0); //~ float_cmp + let _ = f(1.0) + 1.0 != 5.0; //~ float_cmp } // Pointer equality @@ -222,10 +199,8 @@ fn main() { let _ = C[0] == x; let _ = C[2] == x; - let _ = x == C[1]; - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = C[1] == x; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x == C[1]; //~ float_cmp + let _ = C[1] == x; //~ float_cmp } } @@ -284,33 +259,32 @@ fn main() { } fn _f(x: f32, y: f32) { - let _ = x == x + 1.0; - let _ = x + 1.0 == x; - let _ = -x == -x + 1.0; - let _ = -x + 1.0 == -x; - let _ = x == f1(x); - let _ = f1(x) == x; - let _ = x == f2(x, y); - let _ = f2(x, y) == x; - let _ = f1(f1(x)) == f1(x); - let _ = f1(x) == f1(f1(x)); + let _ = x == x + 1.0; //~[change_detect] float_cmp + let _ = x + 1.0 == x; //~[change_detect] float_cmp + let _ = -x == -x + 1.0; //~[change_detect] float_cmp + let _ = -x + 1.0 == -x; //~[change_detect] float_cmp + let _ = x == f1(x); //~[change_detect] float_cmp + let _ = f1(x) == x; //~[change_detect] float_cmp + let _ = x == f2(x, y); //~[change_detect] float_cmp + let _ = f2(x, y) == x; //~[change_detect] float_cmp + let _ = f1(f1(x)) == f1(x); //~[change_detect] float_cmp + let _ = f1(x) == f1(f1(x)); //~[change_detect] float_cmp let z = (x, y); - let _ = z.0 == z.0 + 1.0; - let _ = z.0 + 1.0 == z.0; + let _ = z.0 == z.0 + 1.0; //~[change_detect] float_cmp + let _ = z.0 + 1.0 == z.0; //~[change_detect] float_cmp } fn _f2(x: &f32) { - let _ = *x + 1.0 == *x; - let _ = *x == *x + 1.0; - let _ = *x == f1(*x); - let _ = f1(*x) == *x; + let _ = *x + 1.0 == *x; //~[change_detect] float_cmp + let _ = *x == *x + 1.0; //~[change_detect] float_cmp + let _ = *x == f1(*x); //~[change_detect] float_cmp + let _ = f1(*x) == *x; //~[change_detect] float_cmp } } { fn _f(mut x: impl Iterator) { - let _ = x.next().unwrap() == x.next().unwrap() + 1.0; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x.next().unwrap() == x.next().unwrap() + 1.0; //~ float_cmp } } { @@ -326,10 +300,8 @@ fn main() { } fn _f(x: S) { - let _ = x.f() + 1.0 == x.f(); - //~^ ERROR: strict comparison of `f32` or `f64` - let _ = x.f() == x.f() + 1.0; - //~^ ERROR: strict comparison of `f32` or `f64` + let _ = x.f() + 1.0 == x.f(); //~ float_cmp + let _ = x.f() == x.f() + 1.0; //~ float_cmp } } { diff --git a/tests/ui-toml/float_cmp_change_detection/test.rs b/tests/ui-toml/float_cmp_change_detection/test.rs deleted file mode 100644 index c16776e104e3..000000000000 --- a/tests/ui-toml/float_cmp_change_detection/test.rs +++ /dev/null @@ -1,40 +0,0 @@ -//@no-rustfix - -#![deny(clippy::float_cmp)] -#![allow(clippy::op_ref, clippy::eq_op)] - -fn main() { - { - const C: f64 = 1.0; - fn f(x: f64) { - let _ = x == C; - } - } - { - const fn f(x: f64) -> f64 { - todo!() - } - let _ = f(1.0) == f(2.0); - } - { - let _ = 1.0f32 == 2.0f32; - let _ = -1.0f32 == -2.0f32; - let _ = 1.0f64 == 2.0f64; - } - { - fn f(x: f32) { - let _ = x + 1.0 == x; - let _ = x == x + 1.0; - } - } - { - fn _f(x: f32) { - let _ = x == x; - let _ = x != x; - let _ = x == -x; - let _ = -x == x; - let _ = x as f64 == x as f64; - let _ = &&x == &&x; - } - } -} diff --git a/tests/ui-toml/float_cmp_change_detection/test.stderr b/tests/ui-toml/float_cmp_change_detection/test.stderr deleted file mode 100644 index 7bbe9713f56a..000000000000 --- a/tests/ui-toml/float_cmp_change_detection/test.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp_change_detection/test.rs:26:21 - | -LL | let _ = x + 1.0 == x; - | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x + 1.0 - x).abs() < error_margin` - | -note: the lint level is defined here - --> tests/ui-toml/float_cmp_change_detection/test.rs:3:9 - | -LL | #![deny(clippy::float_cmp)] - | ^^^^^^^^^^^^^^^^^ - -error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp_change_detection/test.rs:27:21 - | -LL | let _ = x == x + 1.0; - | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - (x + 1.0)).abs() < error_margin` - -error: aborting due to 2 previous errors - diff --git a/tests/ui-toml/float_cmp_constant_comparisons/test.rs b/tests/ui-toml/float_cmp_constant_comparisons/test.rs deleted file mode 100644 index c16776e104e3..000000000000 --- a/tests/ui-toml/float_cmp_constant_comparisons/test.rs +++ /dev/null @@ -1,40 +0,0 @@ -//@no-rustfix - -#![deny(clippy::float_cmp)] -#![allow(clippy::op_ref, clippy::eq_op)] - -fn main() { - { - const C: f64 = 1.0; - fn f(x: f64) { - let _ = x == C; - } - } - { - const fn f(x: f64) -> f64 { - todo!() - } - let _ = f(1.0) == f(2.0); - } - { - let _ = 1.0f32 == 2.0f32; - let _ = -1.0f32 == -2.0f32; - let _ = 1.0f64 == 2.0f64; - } - { - fn f(x: f32) { - let _ = x + 1.0 == x; - let _ = x == x + 1.0; - } - } - { - fn _f(x: f32) { - let _ = x == x; - let _ = x != x; - let _ = x == -x; - let _ = -x == x; - let _ = x as f64 == x as f64; - let _ = &&x == &&x; - } - } -} diff --git a/tests/ui-toml/float_cmp_constant_comparisons/test.stderr b/tests/ui-toml/float_cmp_constant_comparisons/test.stderr deleted file mode 100644 index 7f6db02b485d..000000000000 --- a/tests/ui-toml/float_cmp_constant_comparisons/test.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp_constant_comparisons/test.rs:17:17 - | -LL | let _ = f(1.0) == f(2.0); - | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(2.0)).abs() < error_margin` - | -note: the lint level is defined here - --> tests/ui-toml/float_cmp_constant_comparisons/test.rs:3:9 - | -LL | #![deny(clippy::float_cmp)] - | ^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui-toml/float_cmp_named_constants/test.rs b/tests/ui-toml/float_cmp_named_constants/test.rs deleted file mode 100644 index c16776e104e3..000000000000 --- a/tests/ui-toml/float_cmp_named_constants/test.rs +++ /dev/null @@ -1,40 +0,0 @@ -//@no-rustfix - -#![deny(clippy::float_cmp)] -#![allow(clippy::op_ref, clippy::eq_op)] - -fn main() { - { - const C: f64 = 1.0; - fn f(x: f64) { - let _ = x == C; - } - } - { - const fn f(x: f64) -> f64 { - todo!() - } - let _ = f(1.0) == f(2.0); - } - { - let _ = 1.0f32 == 2.0f32; - let _ = -1.0f32 == -2.0f32; - let _ = 1.0f64 == 2.0f64; - } - { - fn f(x: f32) { - let _ = x + 1.0 == x; - let _ = x == x + 1.0; - } - } - { - fn _f(x: f32) { - let _ = x == x; - let _ = x != x; - let _ = x == -x; - let _ = -x == x; - let _ = x as f64 == x as f64; - let _ = &&x == &&x; - } - } -} diff --git a/tests/ui-toml/float_cmp_named_constants/test.stderr b/tests/ui-toml/float_cmp_named_constants/test.stderr deleted file mode 100644 index 74036b354cd6..000000000000 --- a/tests/ui-toml/float_cmp_named_constants/test.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp_named_constants/test.rs:10:21 - | -LL | let _ = x == C; - | ^^^^^^ help: consider comparing them within some margin of error: `(x - C).abs() < error_margin` - | -note: the lint level is defined here - --> tests/ui-toml/float_cmp_named_constants/test.rs:3:9 - | -LL | #![deny(clippy::float_cmp)] - | ^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - From fde377a492d08e6c4f25535db4596c68399d29dd Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sat, 13 Jul 2024 14:07:56 -0400 Subject: [PATCH 08/10] `float_cmp`: Change `allow_named_constants` to an allow list. --- CHANGELOG.md | 3 + book/src/lint_configuration.md | 53 ++++++++++ clippy_config/src/conf.rs | 6 +- clippy_lints/src/lib.rs | 2 +- clippy_lints/src/operators/float_cmp.rs | 8 +- clippy_lints/src/operators/mod.rs | 16 ++- clippy_utils/src/lib.rs | 17 ++-- .../float_cmp/change_detect/clippy.toml | 5 + tests/ui-toml/float_cmp/const_cmp/clippy.toml | 5 + .../ui-toml/float_cmp/named_const/clippy.toml | 1 - .../float_cmp/test.change_detect.stderr | 52 +++++----- tests/ui-toml/float_cmp/test.const_cmp.stderr | 52 +++++----- .../ui-toml/float_cmp/test.named_const.stderr | 98 +++++++++---------- tests/ui-toml/float_cmp/test.rs | 32 +++--- .../toml_unknown_key/conf_unknown_key.stderr | 6 +- 15 files changed, 214 insertions(+), 142 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55281f3cbec0..e58199b0cf90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6045,6 +6045,9 @@ Released 2018-09-13 [`enum-variant-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-name-threshold [`enum-variant-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-size-threshold [`excessive-nesting-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#excessive-nesting-threshold +[`float-cmp-allowed-constants`]: https://doc.rust-lang.org/clippy/lint_configuration.html#float-cmp-allowed-constants +[`float-cmp-ignore-change-detection`]: https://doc.rust-lang.org/clippy/lint_configuration.html#float-cmp-ignore-change-detection +[`float-cmp-ignore-constant-comparisons`]: https://doc.rust-lang.org/clippy/lint_configuration.html#float-cmp-ignore-constant-comparisons [`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold [`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability [`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index ce6cbc62a505..03b2e76ac4de 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -538,6 +538,59 @@ The maximum amount of nesting a block can reside in * [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting) +## `float-cmp-allowed-constants` +#### Example +```no_run +const VALUE: f64 = 1.0; +fn is_value(x: f64) -> bool { + // Will warn unless `crate_name::VALUE` is allowed + x == VALUE +} +``` + +**Default Value:** `[]` + +--- +**Affected lints:** +* [`float_cmp`](https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp) + + +## `float-cmp-ignore-change-detection` +#### Example +```no_run +fn f(x: f64) -> bool { + // Will warn if the config is `false` + x == x + 1.0 +} +``` + +**Default Value:** `true` + +--- +**Affected lints:** +* [`float_cmp`](https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp) + + +## `float-cmp-ignore-constant-comparisons` +#### Example +```no_run +const fn f(x: f64) -> f64 { + todo!() +} + +// Will warn if the config is `false` +if f(1.0) == f(2.0) { + // ... +} +``` + +**Default Value:** `true` + +--- +**Affected lints:** +* [`float_cmp`](https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp) + + ## `future-size-threshold` The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index c2ea2fce0903..5ca4bbeaf563 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -647,17 +647,17 @@ define_Conf! { (warn_unsafe_macro_metavars_in_private_macros: bool = false), /// Lint: FLOAT_CMP /// - /// Whether to ignore comparisons to a named constnat + /// The list of constants which can be checked for exact equality. /// /// #### Example /// ```no_run /// const VALUE: f64 = 1.0; /// fn is_value(x: f64) -> bool { - /// // Will warn if the config is `false` + /// // Will warn unless `crate_name::VALUE` is allowed /// x == VALUE /// } /// ``` - (float_cmp_ignore_named_constants: bool = true), + (float_cmp_allowed_constants: Vec = Vec::new()), /// Lint: FLOAT_CMP /// /// Whether to ignore comparisons which have a constant result. diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 25cd76104007..d284d1f4eeb6 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -816,7 +816,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(conf))); store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(conf))); store.register_late_pass(move |_| Box::new(manual_rotate::ManualRotate)); - store.register_late_pass(move |_| Box::new(operators::Operators::new(conf))); + store.register_late_pass(move |tcx| Box::new(operators::Operators::new(tcx, conf))); store.register_late_pass(|_| Box::::default()); store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(conf))); store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone)); diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 986e221fca3a..6a7961d9b464 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -2,7 +2,7 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::sugg::Sugg; use clippy_utils::visitors::{for_each_expr_without_closures, is_const_evaluatable}; -use clippy_utils::{get_item_name, is_expr_named_const, path_res, peel_hir_expr_while, SpanlessEq}; +use clippy_utils::{get_item_name, get_named_const_def_id, path_res, peel_hir_expr_while, SpanlessEq}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::def::Res; @@ -14,7 +14,7 @@ use super::{FloatCmpConfig, FLOAT_CMP}; pub(crate) fn check<'tcx>( cx: &LateContext<'tcx>, - config: FloatCmpConfig, + config: &FloatCmpConfig, expr: &'tcx Expr<'_>, op: BinOpKind, left: &'tcx Expr<'_>, @@ -56,8 +56,8 @@ pub(crate) fn check<'tcx>( return; } - if config.ignore_named_constants - && (is_expr_named_const(cx, left_reduced) || is_expr_named_const(cx, right_reduced)) + if get_named_const_def_id(cx, left_reduced).is_some_and(|id| config.allowed_constants.contains(&id)) + || get_named_const_def_id(cx, right_reduced).is_some_and(|id| config.allowed_constants.contains(&id)) { return; } diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 6bb52a0ccf65..43488c6064d4 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -24,8 +24,11 @@ mod verbose_bit_mask; pub(crate) mod arithmetic_side_effects; use clippy_config::Conf; +use clippy_utils::def_path_def_ids; +use rustc_hir::def_id::DefIdSet; use rustc_hir::{Body, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::TyCtxt; use rustc_session::impl_lint_pass; declare_clippy_lint! { @@ -774,9 +777,8 @@ declare_clippy_lint! { "explicit self-assignment" } -#[derive(Clone, Copy)] struct FloatCmpConfig { - ignore_named_constants: bool, + allowed_constants: DefIdSet, ignore_constant_comparisons: bool, ignore_change_detection: bool, } @@ -788,13 +790,17 @@ pub struct Operators { float_cmp_config: FloatCmpConfig, } impl Operators { - pub fn new(conf: &'static Conf) -> Self { + pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self { Self { arithmetic_context: numeric_arithmetic::Context::default(), verbose_bit_mask_threshold: conf.verbose_bit_mask_threshold, modulo_arithmetic_allow_comparison_to_zero: conf.allow_comparison_to_zero, float_cmp_config: FloatCmpConfig { - ignore_named_constants: conf.float_cmp_ignore_named_constants, + allowed_constants: conf + .float_cmp_allowed_constants + .iter() + .flat_map(|x| def_path_def_ids(tcx, &x.split("::").collect::>())) + .collect(), ignore_constant_comparisons: conf.float_cmp_ignore_constant_comparisons, ignore_change_detection: conf.float_cmp_ignore_change_detection, }, @@ -854,7 +860,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { float_equality_without_abs::check(cx, e, op.node, lhs, rhs); integer_division::check(cx, e, op.node, lhs, rhs); cmp_owned::check(cx, op.node, lhs, rhs); - float_cmp::check(cx, self.float_cmp_config, e, op.node, lhs, rhs); + float_cmp::check(cx, &self.float_cmp_config, e, op.node, lhs, rhs); modulo_one::check(cx, e, op.node, rhs); modulo_arithmetic::check( cx, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index fb1493884fef..3bbf64708706 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -245,14 +245,15 @@ pub fn is_inside_always_const_context(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { } } -/// Checks if the expression is path to either a constant or an associated constant. -pub fn is_expr_named_const<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { - matches!(&e.kind, ExprKind::Path(p) - if matches!( - cx.qpath_res(p, e.hir_id), - Res::Def(DefKind::Const | DefKind::AssocConst, _) - ) - ) +/// If the expression is path to either a constant or an associated constant get the `DefId`. +pub fn get_named_const_def_id<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option { + if let ExprKind::Path(p) = &e.kind + && let Res::Def(DefKind::Const | DefKind::AssocConst, id) = cx.qpath_res(p, e.hir_id) + { + Some(id) + } else { + None + } } /// Checks if a `Res` refers to a constructor of a `LangItem` diff --git a/tests/ui-toml/float_cmp/change_detect/clippy.toml b/tests/ui-toml/float_cmp/change_detect/clippy.toml index c78367975726..65e32118cb09 100644 --- a/tests/ui-toml/float_cmp/change_detect/clippy.toml +++ b/tests/ui-toml/float_cmp/change_detect/clippy.toml @@ -1 +1,6 @@ float-cmp-ignore-change-detection = false +float-cmp-allowed-constants = [ + "core::f32::EPSILON", + "f32::EPSILON", + "test::F32_ARRAY", +] diff --git a/tests/ui-toml/float_cmp/const_cmp/clippy.toml b/tests/ui-toml/float_cmp/const_cmp/clippy.toml index 34006387a248..c7521206a899 100644 --- a/tests/ui-toml/float_cmp/const_cmp/clippy.toml +++ b/tests/ui-toml/float_cmp/const_cmp/clippy.toml @@ -1 +1,6 @@ float-cmp-ignore-constant-comparisons = false +float-cmp-allowed-constants = [ + "core::f32::EPSILON", + "f32::EPSILON", + "test::F32_ARRAY", +] diff --git a/tests/ui-toml/float_cmp/named_const/clippy.toml b/tests/ui-toml/float_cmp/named_const/clippy.toml index 7e24aab86cf6..e69de29bb2d1 100644 --- a/tests/ui-toml/float_cmp/named_const/clippy.toml +++ b/tests/ui-toml/float_cmp/named_const/clippy.toml @@ -1 +0,0 @@ -float-cmp-ignore-named-constants = false diff --git a/tests/ui-toml/float_cmp/test.change_detect.stderr b/tests/ui-toml/float_cmp/test.change_detect.stderr index e212739c7afe..397b035ca13f 100644 --- a/tests/ui-toml/float_cmp/test.change_detect.stderr +++ b/tests/ui-toml/float_cmp/test.change_detect.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:15:21 + --> tests/ui-toml/float_cmp/test.rs:17:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` @@ -11,130 +11,130 @@ LL | #![deny(clippy::float_cmp)] | ^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:16:21 + --> tests/ui-toml/float_cmp/test.rs:18:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:17:21 + --> tests/ui-toml/float_cmp/test.rs:19:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:18:21 + --> tests/ui-toml/float_cmp/test.rs:20:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:41:21 + --> tests/ui-toml/float_cmp/test.rs:43:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:42:21 + --> tests/ui-toml/float_cmp/test.rs:44:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:43:21 + --> tests/ui-toml/float_cmp/test.rs:45:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:44:21 + --> tests/ui-toml/float_cmp/test.rs:46:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:67:21 + --> tests/ui-toml/float_cmp/test.rs:69:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:68:21 + --> tests/ui-toml/float_cmp/test.rs:70:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:69:21 + --> tests/ui-toml/float_cmp/test.rs:71:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:70:21 + --> tests/ui-toml/float_cmp/test.rs:72:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:71:21 + --> tests/ui-toml/float_cmp/test.rs:73:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:87:21 + --> tests/ui-toml/float_cmp/test.rs:89:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:88:21 + --> tests/ui-toml/float_cmp/test.rs:90:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:89:21 + --> tests/ui-toml/float_cmp/test.rs:91:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:90:21 + --> tests/ui-toml/float_cmp/test.rs:92:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:91:21 + --> tests/ui-toml/float_cmp/test.rs:93:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:109:21 + --> tests/ui-toml/float_cmp/test.rs:111:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:115:21 + --> tests/ui-toml/float_cmp/test.rs:117:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:131:21 + --> tests/ui-toml/float_cmp/test.rs:132:21 | -LL | let _ = C * x == x * x; - | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C * x - x * x).abs() < error_margin` +LL | let _ = f32::EPSILON * x == x * x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON * x - x * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:132:21 + --> tests/ui-toml/float_cmp/test.rs:133:21 | -LL | let _ = x * x == C * x; - | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - C * x).abs() < error_margin` +LL | let _ = x * x == f32::EPSILON * x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - f32::EPSILON * x).abs() < error_margin` error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:158:17 diff --git a/tests/ui-toml/float_cmp/test.const_cmp.stderr b/tests/ui-toml/float_cmp/test.const_cmp.stderr index 584b68caaae6..0335aa19d1eb 100644 --- a/tests/ui-toml/float_cmp/test.const_cmp.stderr +++ b/tests/ui-toml/float_cmp/test.const_cmp.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:15:21 + --> tests/ui-toml/float_cmp/test.rs:17:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` @@ -11,130 +11,130 @@ LL | #![deny(clippy::float_cmp)] | ^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:16:21 + --> tests/ui-toml/float_cmp/test.rs:18:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:17:21 + --> tests/ui-toml/float_cmp/test.rs:19:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:18:21 + --> tests/ui-toml/float_cmp/test.rs:20:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:41:21 + --> tests/ui-toml/float_cmp/test.rs:43:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:42:21 + --> tests/ui-toml/float_cmp/test.rs:44:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:43:21 + --> tests/ui-toml/float_cmp/test.rs:45:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:44:21 + --> tests/ui-toml/float_cmp/test.rs:46:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:67:21 + --> tests/ui-toml/float_cmp/test.rs:69:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:68:21 + --> tests/ui-toml/float_cmp/test.rs:70:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:69:21 + --> tests/ui-toml/float_cmp/test.rs:71:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:70:21 + --> tests/ui-toml/float_cmp/test.rs:72:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:71:21 + --> tests/ui-toml/float_cmp/test.rs:73:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:87:21 + --> tests/ui-toml/float_cmp/test.rs:89:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:88:21 + --> tests/ui-toml/float_cmp/test.rs:90:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:89:21 + --> tests/ui-toml/float_cmp/test.rs:91:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:90:21 + --> tests/ui-toml/float_cmp/test.rs:92:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:91:21 + --> tests/ui-toml/float_cmp/test.rs:93:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:109:21 + --> tests/ui-toml/float_cmp/test.rs:111:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:115:21 + --> tests/ui-toml/float_cmp/test.rs:117:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:131:21 + --> tests/ui-toml/float_cmp/test.rs:132:21 | -LL | let _ = C * x == x * x; - | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C * x - x * x).abs() < error_margin` +LL | let _ = f32::EPSILON * x == x * x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON * x - x * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:132:21 + --> tests/ui-toml/float_cmp/test.rs:133:21 | -LL | let _ = x * x == C * x; - | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - C * x).abs() < error_margin` +LL | let _ = x * x == f32::EPSILON * x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - f32::EPSILON * x).abs() < error_margin` error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:150:17 diff --git a/tests/ui-toml/float_cmp/test.named_const.stderr b/tests/ui-toml/float_cmp/test.named_const.stderr index eb49aff7b280..7add667279cd 100644 --- a/tests/ui-toml/float_cmp/test.named_const.stderr +++ b/tests/ui-toml/float_cmp/test.named_const.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:15:21 + --> tests/ui-toml/float_cmp/test.rs:17:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` @@ -11,190 +11,190 @@ LL | #![deny(clippy::float_cmp)] | ^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:16:21 + --> tests/ui-toml/float_cmp/test.rs:18:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:17:21 + --> tests/ui-toml/float_cmp/test.rs:19:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:18:21 + --> tests/ui-toml/float_cmp/test.rs:20:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:41:21 + --> tests/ui-toml/float_cmp/test.rs:43:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:42:21 + --> tests/ui-toml/float_cmp/test.rs:44:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:43:21 + --> tests/ui-toml/float_cmp/test.rs:45:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:44:21 + --> tests/ui-toml/float_cmp/test.rs:46:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:67:21 + --> tests/ui-toml/float_cmp/test.rs:69:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:68:21 + --> tests/ui-toml/float_cmp/test.rs:70:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:69:21 + --> tests/ui-toml/float_cmp/test.rs:71:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:70:21 + --> tests/ui-toml/float_cmp/test.rs:72:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:71:21 + --> tests/ui-toml/float_cmp/test.rs:73:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:87:21 + --> tests/ui-toml/float_cmp/test.rs:89:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:88:21 + --> tests/ui-toml/float_cmp/test.rs:90:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:89:21 + --> tests/ui-toml/float_cmp/test.rs:91:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:90:21 + --> tests/ui-toml/float_cmp/test.rs:92:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:91:21 + --> tests/ui-toml/float_cmp/test.rs:93:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:109:21 + --> tests/ui-toml/float_cmp/test.rs:111:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:115:21 + --> tests/ui-toml/float_cmp/test.rs:117:21 | LL | let _ = x == y; | ^^^^^^ -error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:124:21 - | -LL | let _ = x == C; - | ^^^^^^ help: consider comparing them within some margin of error: `(x - C).abs() < error_margin` - error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:125:21 | -LL | let _ = C == x; - | ^^^^^^ help: consider comparing them within some margin of error: `(C - x).abs() < error_margin` +LL | let _ = x == f32::EPSILON; + | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - f32::EPSILON).abs() < error_margin` error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:126:21 | -LL | let _ = &&x == &&C; - | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(&&x - &&C).abs() < error_margin` +LL | let _ = f32::EPSILON == x; + | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON - x).abs() < error_margin` error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:127:21 | -LL | let _ = &&C == &&x; - | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(&&C - &&x).abs() < error_margin` +LL | let _ = &&x == &&core::f32::EPSILON; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(&&x - &&core::f32::EPSILON).abs() < error_margin` error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:128:21 | -LL | let _ = y == C as f64; - | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(y - C as f64).abs() < error_margin` +LL | let _ = &&core::f32::EPSILON == &&x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(&&core::f32::EPSILON - &&x).abs() < error_margin` error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:129:21 | -LL | let _ = C as f64 == y; - | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C as f64 - y).abs() < error_margin` +LL | let _ = y == f32::EPSILON as f64; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(y - f32::EPSILON as f64).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:131:21 + --> tests/ui-toml/float_cmp/test.rs:130:21 | -LL | let _ = C * x == x * x; - | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C * x - x * x).abs() < error_margin` +LL | let _ = f32::EPSILON as f64 == y; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON as f64 - y).abs() < error_margin` error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:132:21 | -LL | let _ = x * x == C * x; - | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - C * x).abs() < error_margin` +LL | let _ = f32::EPSILON * x == x * x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON * x - x * x).abs() < error_margin` + +error: strict comparison of `f32` or `f64` + --> tests/ui-toml/float_cmp/test.rs:133:21 + | +LL | let _ = x * x == f32::EPSILON * x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - f32::EPSILON * x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays --> tests/ui-toml/float_cmp/test.rs:138:21 | -LL | let _ = x == C; - | ^^^^^^ +LL | let _ = x == F32_ARRAY; + | ^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays --> tests/ui-toml/float_cmp/test.rs:139:21 | -LL | let _ = C == x; - | ^^^^^^ +LL | let _ = F32_ARRAY == x; + | ^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays --> tests/ui-toml/float_cmp/test.rs:140:21 | -LL | let _ = &&x == &&C; - | ^^^^^^^^^^ +LL | let _ = &&x == &&F32_ARRAY; + | ^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays --> tests/ui-toml/float_cmp/test.rs:141:21 | -LL | let _ = &&C == &&x; - | ^^^^^^^^^^ +LL | let _ = &&F32_ARRAY == &&x; + | ^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` --> tests/ui-toml/float_cmp/test.rs:158:17 diff --git a/tests/ui-toml/float_cmp/test.rs b/tests/ui-toml/float_cmp/test.rs index 443064b45733..e9a084bd1f11 100644 --- a/tests/ui-toml/float_cmp/test.rs +++ b/tests/ui-toml/float_cmp/test.rs @@ -7,7 +7,9 @@ // FIXME(f16_f128): const casting is not yet supported for these types. Add when available. #![deny(clippy::float_cmp)] -#![allow(clippy::op_ref, clippy::eq_op)] +#![allow(clippy::op_ref, clippy::eq_op, clippy::legacy_numeric_constants)] + +const F32_ARRAY: [f32; 2] = [5.5, 5.5]; fn main() { { @@ -119,26 +121,24 @@ fn main() { // Comparisons to named constant { - const C: f32 = 5.5; fn _f(x: f32, y: f64) { - let _ = x == C; //~[named_const] float_cmp - let _ = C == x; //~[named_const] float_cmp - let _ = &&x == &&C; //~[named_const] float_cmp - let _ = &&C == &&x; //~[named_const] float_cmp - let _ = y == C as f64; //~[named_const] float_cmp - let _ = C as f64 == y; //~[named_const] float_cmp - - let _ = C * x == x * x; //~ float_cmp - let _ = x * x == C * x; //~ float_cmp + let _ = x == f32::EPSILON; //~[named_const] float_cmp + let _ = f32::EPSILON == x; //~[named_const] float_cmp + let _ = &&x == &&core::f32::EPSILON; //~[named_const] float_cmp + let _ = &&core::f32::EPSILON == &&x; //~[named_const] float_cmp + let _ = y == f32::EPSILON as f64; //~[named_const] float_cmp + let _ = f32::EPSILON as f64 == y; //~[named_const] float_cmp + + let _ = f32::EPSILON * x == x * x; //~ float_cmp + let _ = x * x == f32::EPSILON * x; //~ float_cmp } } { - const C: [f32; 2] = [5.5, 5.5]; fn _f(x: [f32; 2]) { - let _ = x == C; //~[named_const] float_cmp - let _ = C == x; //~[named_const] float_cmp - let _ = &&x == &&C; //~[named_const] float_cmp - let _ = &&C == &&x; //~[named_const] float_cmp + let _ = x == F32_ARRAY; //~[named_const] float_cmp + let _ = F32_ARRAY == x; //~[named_const] float_cmp + let _ = &&x == &&F32_ARRAY; //~[named_const] float_cmp + let _ = &&F32_ARRAY == &&x; //~[named_const] float_cmp } } diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 56b80b0ed2c6..2a8a2520141a 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -42,9 +42,9 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-allowed-constants float-cmp-ignore-change-detection float-cmp-ignore-constant-comparisons - float-cmp-ignore-named-constants future-size-threshold ignore-interior-mutability large-error-threshold @@ -129,9 +129,9 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-allowed-constants float-cmp-ignore-change-detection float-cmp-ignore-constant-comparisons - float-cmp-ignore-named-constants future-size-threshold ignore-interior-mutability large-error-threshold @@ -216,9 +216,9 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni enum-variant-name-threshold enum-variant-size-threshold excessive-nesting-threshold + float-cmp-allowed-constants float-cmp-ignore-change-detection float-cmp-ignore-constant-comparisons - float-cmp-ignore-named-constants future-size-threshold ignore-interior-mutability large-error-threshold From 5bb41b2f8b7b8736edde59653647e995d44a72e8 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Thu, 18 Jul 2024 14:10:27 -0400 Subject: [PATCH 09/10] `float_cmp`: Ensure both sides are a float type. --- clippy_lints/src/operators/float_cmp.rs | 1 + .../float_cmp/test.change_detect.stderr | 42 +++++++++---------- tests/ui-toml/float_cmp/test.const_cmp.stderr | 8 ++-- .../ui-toml/float_cmp/test.named_const.stderr | 8 ++-- tests/ui-toml/float_cmp/test.rs | 6 +++ 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 6a7961d9b464..4b16c346ab02 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -29,6 +29,7 @@ pub(crate) fn check<'tcx>( && let left_reduced = peel_hir_expr_while(left, peel_expr) && let right_reduced = peel_hir_expr_while(right, peel_expr) && is_float(cx, left_reduced) + && is_float(cx, right_reduced) // Don't lint literal comparisons && !(matches!(left_reduced.kind, ExprKind::Lit(_)) && matches!(right_reduced.kind, ExprKind::Lit(_))) // Allow comparing the results of signum() diff --git a/tests/ui-toml/float_cmp/test.change_detect.stderr b/tests/ui-toml/float_cmp/test.change_detect.stderr index 397b035ca13f..b83fa517b57c 100644 --- a/tests/ui-toml/float_cmp/test.change_detect.stderr +++ b/tests/ui-toml/float_cmp/test.change_detect.stderr @@ -167,127 +167,127 @@ LL | let _ = C[1] == x; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:262:21 + --> tests/ui-toml/float_cmp/test.rs:268:21 | LL | let _ = x == x + 1.0; | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - (x + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:263:21 + --> tests/ui-toml/float_cmp/test.rs:269:21 | LL | let _ = x + 1.0 == x; | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x + 1.0 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:264:21 + --> tests/ui-toml/float_cmp/test.rs:270:21 | LL | let _ = -x == -x + 1.0; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(-x - (-x + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:265:21 + --> tests/ui-toml/float_cmp/test.rs:271:21 | LL | let _ = -x + 1.0 == -x; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(-x + 1.0 - -x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:266:21 + --> tests/ui-toml/float_cmp/test.rs:272:21 | LL | let _ = x == f1(x); | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - f1(x)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:267:21 + --> tests/ui-toml/float_cmp/test.rs:273:21 | LL | let _ = f1(x) == x; | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(x) - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:268:21 + --> tests/ui-toml/float_cmp/test.rs:274:21 | LL | let _ = x == f2(x, y); | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - f2(x, y)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:269:21 + --> tests/ui-toml/float_cmp/test.rs:275:21 | LL | let _ = f2(x, y) == x; | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f2(x, y) - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:270:21 + --> tests/ui-toml/float_cmp/test.rs:276:21 | LL | let _ = f1(f1(x)) == f1(x); | ^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(f1(x)) - f1(x)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:271:21 + --> tests/ui-toml/float_cmp/test.rs:277:21 | LL | let _ = f1(x) == f1(f1(x)); | ^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(x) - f1(f1(x))).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:274:21 + --> tests/ui-toml/float_cmp/test.rs:280:21 | LL | let _ = z.0 == z.0 + 1.0; | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(z.0 - (z.0 + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:275:21 + --> tests/ui-toml/float_cmp/test.rs:281:21 | LL | let _ = z.0 + 1.0 == z.0; | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(z.0 + 1.0 - z.0).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:279:21 + --> tests/ui-toml/float_cmp/test.rs:285:21 | LL | let _ = *x + 1.0 == *x; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x + 1.0 - *x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:280:21 + --> tests/ui-toml/float_cmp/test.rs:286:21 | LL | let _ = *x == *x + 1.0; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x - (*x + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:281:21 + --> tests/ui-toml/float_cmp/test.rs:287:21 | LL | let _ = *x == f1(*x); | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x - f1(*x)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:282:21 + --> tests/ui-toml/float_cmp/test.rs:288:21 | LL | let _ = f1(*x) == *x; | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(*x) - *x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:287:21 + --> tests/ui-toml/float_cmp/test.rs:293:21 | LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:303:21 + --> tests/ui-toml/float_cmp/test.rs:309:21 | LL | let _ = x.f() + 1.0 == x.f(); | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:304:21 + --> tests/ui-toml/float_cmp/test.rs:310:21 | LL | let _ = x.f() == x.f() + 1.0; | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:309:17 + --> tests/ui-toml/float_cmp/test.rs:315:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:313:17 + --> tests/ui-toml/float_cmp/test.rs:319:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` diff --git a/tests/ui-toml/float_cmp/test.const_cmp.stderr b/tests/ui-toml/float_cmp/test.const_cmp.stderr index 0335aa19d1eb..d1dd285f2a08 100644 --- a/tests/ui-toml/float_cmp/test.const_cmp.stderr +++ b/tests/ui-toml/float_cmp/test.const_cmp.stderr @@ -185,25 +185,25 @@ LL | let _ = C[1] == x; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:287:21 + --> tests/ui-toml/float_cmp/test.rs:293:21 | LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:303:21 + --> tests/ui-toml/float_cmp/test.rs:309:21 | LL | let _ = x.f() + 1.0 == x.f(); | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:304:21 + --> tests/ui-toml/float_cmp/test.rs:310:21 | LL | let _ = x.f() == x.f() + 1.0; | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:313:17 + --> tests/ui-toml/float_cmp/test.rs:319:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` diff --git a/tests/ui-toml/float_cmp/test.named_const.stderr b/tests/ui-toml/float_cmp/test.named_const.stderr index 7add667279cd..2c2d70498167 100644 --- a/tests/ui-toml/float_cmp/test.named_const.stderr +++ b/tests/ui-toml/float_cmp/test.named_const.stderr @@ -227,25 +227,25 @@ LL | let _ = C[1] == x; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:287:21 + --> tests/ui-toml/float_cmp/test.rs:293:21 | LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:303:21 + --> tests/ui-toml/float_cmp/test.rs:309:21 | LL | let _ = x.f() + 1.0 == x.f(); | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:304:21 + --> tests/ui-toml/float_cmp/test.rs:310:21 | LL | let _ = x.f() == x.f() + 1.0; | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:313:17 + --> tests/ui-toml/float_cmp/test.rs:319:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` diff --git a/tests/ui-toml/float_cmp/test.rs b/tests/ui-toml/float_cmp/test.rs index e9a084bd1f11..e28b94aef739 100644 --- a/tests/ui-toml/float_cmp/test.rs +++ b/tests/ui-toml/float_cmp/test.rs @@ -242,9 +242,15 @@ fn main() { false } } + impl PartialEq for f32 { + fn eq(&self, _: &S) -> bool { + false + } + } fn _f(x: S, y: f32) { let _ = x == y; + let _ = y == x; } } From 847e7d660b758d0a7d62ff50a8aade0e442aa860 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Thu, 18 Jul 2024 14:23:54 -0400 Subject: [PATCH 10/10] `float_cmp`: Allow literal to constant comparisons. --- clippy_lints/src/operators/float_cmp.rs | 11 ++- .../float_cmp/test.change_detect.stderr | 96 +++++++++---------- tests/ui-toml/float_cmp/test.const_cmp.stderr | 68 ++++++------- .../ui-toml/float_cmp/test.named_const.stderr | 82 ++++++++-------- tests/ui-toml/float_cmp/test.rs | 15 ++- 5 files changed, 145 insertions(+), 127 deletions(-) diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 4b16c346ab02..5544a661e834 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -31,7 +31,9 @@ pub(crate) fn check<'tcx>( && is_float(cx, left_reduced) && is_float(cx, right_reduced) // Don't lint literal comparisons - && !(matches!(left_reduced.kind, ExprKind::Lit(_)) && matches!(right_reduced.kind, ExprKind::Lit(_))) + && let is_left_lit = matches!(left_reduced.kind, ExprKind::Lit(_)) + && let is_right_lit = matches!(right_reduced.kind, ExprKind::Lit(_)) + && !(is_left_lit && is_right_lit) // Allow comparing the results of signum() && !(is_signum(cx, left_reduced) && is_signum(cx, right_reduced)) && match (path_res(cx, left_reduced), path_res(cx, right_reduced)) { @@ -57,8 +59,11 @@ pub(crate) fn check<'tcx>( return; } - if get_named_const_def_id(cx, left_reduced).is_some_and(|id| config.allowed_constants.contains(&id)) - || get_named_const_def_id(cx, right_reduced).is_some_and(|id| config.allowed_constants.contains(&id)) + // Neither `CONST == lit` or `ALLOWED_CONST == x` should lint. + if get_named_const_def_id(cx, left_reduced) + .is_some_and(|id| is_right_lit || config.allowed_constants.contains(&id)) + || get_named_const_def_id(cx, right_reduced) + .is_some_and(|id| is_left_lit || config.allowed_constants.contains(&id)) { return; } diff --git a/tests/ui-toml/float_cmp/test.change_detect.stderr b/tests/ui-toml/float_cmp/test.change_detect.stderr index b83fa517b57c..49da8754d72f 100644 --- a/tests/ui-toml/float_cmp/test.change_detect.stderr +++ b/tests/ui-toml/float_cmp/test.change_detect.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:17:21 + --> tests/ui-toml/float_cmp/test.rs:22:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` @@ -11,283 +11,283 @@ LL | #![deny(clippy::float_cmp)] | ^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:18:21 + --> tests/ui-toml/float_cmp/test.rs:23:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:19:21 + --> tests/ui-toml/float_cmp/test.rs:24:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:20:21 + --> tests/ui-toml/float_cmp/test.rs:25:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:43:21 + --> tests/ui-toml/float_cmp/test.rs:48:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:44:21 + --> tests/ui-toml/float_cmp/test.rs:49:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:45:21 + --> tests/ui-toml/float_cmp/test.rs:50:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:46:21 + --> tests/ui-toml/float_cmp/test.rs:51:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:69:21 + --> tests/ui-toml/float_cmp/test.rs:74:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:70:21 + --> tests/ui-toml/float_cmp/test.rs:75:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:71:21 + --> tests/ui-toml/float_cmp/test.rs:76:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:72:21 + --> tests/ui-toml/float_cmp/test.rs:77:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:73:21 + --> tests/ui-toml/float_cmp/test.rs:78:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:89:21 + --> tests/ui-toml/float_cmp/test.rs:94:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:90:21 + --> tests/ui-toml/float_cmp/test.rs:95:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:91:21 + --> tests/ui-toml/float_cmp/test.rs:96:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:92:21 + --> tests/ui-toml/float_cmp/test.rs:97:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:93:21 + --> tests/ui-toml/float_cmp/test.rs:98:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:111:21 + --> tests/ui-toml/float_cmp/test.rs:116:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:117:21 + --> tests/ui-toml/float_cmp/test.rs:122:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:132:21 + --> tests/ui-toml/float_cmp/test.rs:137:21 | LL | let _ = f32::EPSILON * x == x * x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON * x - x * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:133:21 + --> tests/ui-toml/float_cmp/test.rs:138:21 | LL | let _ = x * x == f32::EPSILON * x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - f32::EPSILON * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:158:17 + --> tests/ui-toml/float_cmp/test.rs:163:17 | LL | let _ = f(1.0) == f(5.0); | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:159:17 + --> tests/ui-toml/float_cmp/test.rs:164:17 | LL | let _ = 1.0 == f(5.0); | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:160:17 + --> tests/ui-toml/float_cmp/test.rs:165:17 | LL | let _ = f(1.0) + 1.0 != 5.0; | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:202:21 + --> tests/ui-toml/float_cmp/test.rs:207:21 | LL | let _ = x == C[1]; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(x - C[1]).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:203:21 + --> tests/ui-toml/float_cmp/test.rs:208:21 | LL | let _ = C[1] == x; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:268:21 + --> tests/ui-toml/float_cmp/test.rs:273:21 | LL | let _ = x == x + 1.0; | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - (x + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:269:21 + --> tests/ui-toml/float_cmp/test.rs:274:21 | LL | let _ = x + 1.0 == x; | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x + 1.0 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:270:21 + --> tests/ui-toml/float_cmp/test.rs:275:21 | LL | let _ = -x == -x + 1.0; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(-x - (-x + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:271:21 + --> tests/ui-toml/float_cmp/test.rs:276:21 | LL | let _ = -x + 1.0 == -x; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(-x + 1.0 - -x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:272:21 + --> tests/ui-toml/float_cmp/test.rs:277:21 | LL | let _ = x == f1(x); | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - f1(x)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:273:21 + --> tests/ui-toml/float_cmp/test.rs:278:21 | LL | let _ = f1(x) == x; | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(x) - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:274:21 + --> tests/ui-toml/float_cmp/test.rs:279:21 | LL | let _ = x == f2(x, y); | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - f2(x, y)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:275:21 + --> tests/ui-toml/float_cmp/test.rs:280:21 | LL | let _ = f2(x, y) == x; | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f2(x, y) - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:276:21 + --> tests/ui-toml/float_cmp/test.rs:281:21 | LL | let _ = f1(f1(x)) == f1(x); | ^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(f1(x)) - f1(x)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:277:21 + --> tests/ui-toml/float_cmp/test.rs:282:21 | LL | let _ = f1(x) == f1(f1(x)); | ^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(x) - f1(f1(x))).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:280:21 + --> tests/ui-toml/float_cmp/test.rs:285:21 | LL | let _ = z.0 == z.0 + 1.0; | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(z.0 - (z.0 + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:281:21 + --> tests/ui-toml/float_cmp/test.rs:286:21 | LL | let _ = z.0 + 1.0 == z.0; | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(z.0 + 1.0 - z.0).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:285:21 + --> tests/ui-toml/float_cmp/test.rs:290:21 | LL | let _ = *x + 1.0 == *x; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x + 1.0 - *x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:286:21 + --> tests/ui-toml/float_cmp/test.rs:291:21 | LL | let _ = *x == *x + 1.0; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x - (*x + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:287:21 + --> tests/ui-toml/float_cmp/test.rs:292:21 | LL | let _ = *x == f1(*x); | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(*x - f1(*x)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:288:21 + --> tests/ui-toml/float_cmp/test.rs:293:21 | LL | let _ = f1(*x) == *x; | ^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f1(*x) - *x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:293:21 + --> tests/ui-toml/float_cmp/test.rs:298:21 | LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:309:21 + --> tests/ui-toml/float_cmp/test.rs:314:21 | LL | let _ = x.f() + 1.0 == x.f(); | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:310:21 + --> tests/ui-toml/float_cmp/test.rs:315:21 | LL | let _ = x.f() == x.f() + 1.0; | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:315:17 + --> tests/ui-toml/float_cmp/test.rs:320:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:319:17 + --> tests/ui-toml/float_cmp/test.rs:324:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` diff --git a/tests/ui-toml/float_cmp/test.const_cmp.stderr b/tests/ui-toml/float_cmp/test.const_cmp.stderr index d1dd285f2a08..cf50d04eab7d 100644 --- a/tests/ui-toml/float_cmp/test.const_cmp.stderr +++ b/tests/ui-toml/float_cmp/test.const_cmp.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:17:21 + --> tests/ui-toml/float_cmp/test.rs:22:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` @@ -11,199 +11,199 @@ LL | #![deny(clippy::float_cmp)] | ^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:18:21 + --> tests/ui-toml/float_cmp/test.rs:23:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:19:21 + --> tests/ui-toml/float_cmp/test.rs:24:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:20:21 + --> tests/ui-toml/float_cmp/test.rs:25:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:43:21 + --> tests/ui-toml/float_cmp/test.rs:48:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:44:21 + --> tests/ui-toml/float_cmp/test.rs:49:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:45:21 + --> tests/ui-toml/float_cmp/test.rs:50:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:46:21 + --> tests/ui-toml/float_cmp/test.rs:51:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:69:21 + --> tests/ui-toml/float_cmp/test.rs:74:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:70:21 + --> tests/ui-toml/float_cmp/test.rs:75:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:71:21 + --> tests/ui-toml/float_cmp/test.rs:76:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:72:21 + --> tests/ui-toml/float_cmp/test.rs:77:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:73:21 + --> tests/ui-toml/float_cmp/test.rs:78:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:89:21 + --> tests/ui-toml/float_cmp/test.rs:94:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:90:21 + --> tests/ui-toml/float_cmp/test.rs:95:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:91:21 + --> tests/ui-toml/float_cmp/test.rs:96:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:92:21 + --> tests/ui-toml/float_cmp/test.rs:97:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:93:21 + --> tests/ui-toml/float_cmp/test.rs:98:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:111:21 + --> tests/ui-toml/float_cmp/test.rs:116:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:117:21 + --> tests/ui-toml/float_cmp/test.rs:122:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:132:21 + --> tests/ui-toml/float_cmp/test.rs:137:21 | LL | let _ = f32::EPSILON * x == x * x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON * x - x * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:133:21 + --> tests/ui-toml/float_cmp/test.rs:138:21 | LL | let _ = x * x == f32::EPSILON * x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - f32::EPSILON * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:150:17 + --> tests/ui-toml/float_cmp/test.rs:155:17 | LL | let _ = f(1.0) == f(5.0); | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:151:17 + --> tests/ui-toml/float_cmp/test.rs:156:17 | LL | let _ = 1.0 == f(5.0); | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:152:17 + --> tests/ui-toml/float_cmp/test.rs:157:17 | LL | let _ = f(1.0) + 1.0 != 5.0; | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:158:17 + --> tests/ui-toml/float_cmp/test.rs:163:17 | LL | let _ = f(1.0) == f(5.0); | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:159:17 + --> tests/ui-toml/float_cmp/test.rs:164:17 | LL | let _ = 1.0 == f(5.0); | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:160:17 + --> tests/ui-toml/float_cmp/test.rs:165:17 | LL | let _ = f(1.0) + 1.0 != 5.0; | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:202:21 + --> tests/ui-toml/float_cmp/test.rs:207:21 | LL | let _ = x == C[1]; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(x - C[1]).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:203:21 + --> tests/ui-toml/float_cmp/test.rs:208:21 | LL | let _ = C[1] == x; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:293:21 + --> tests/ui-toml/float_cmp/test.rs:298:21 | LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:309:21 + --> tests/ui-toml/float_cmp/test.rs:314:21 | LL | let _ = x.f() + 1.0 == x.f(); | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:310:21 + --> tests/ui-toml/float_cmp/test.rs:315:21 | LL | let _ = x.f() == x.f() + 1.0; | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:319:17 + --> tests/ui-toml/float_cmp/test.rs:324:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` diff --git a/tests/ui-toml/float_cmp/test.named_const.stderr b/tests/ui-toml/float_cmp/test.named_const.stderr index 2c2d70498167..20f041ec61c9 100644 --- a/tests/ui-toml/float_cmp/test.named_const.stderr +++ b/tests/ui-toml/float_cmp/test.named_const.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:17:21 + --> tests/ui-toml/float_cmp/test.rs:22:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` @@ -11,241 +11,241 @@ LL | #![deny(clippy::float_cmp)] | ^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:18:21 + --> tests/ui-toml/float_cmp/test.rs:23:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:19:21 + --> tests/ui-toml/float_cmp/test.rs:24:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:20:21 + --> tests/ui-toml/float_cmp/test.rs:25:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:43:21 + --> tests/ui-toml/float_cmp/test.rs:48:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:44:21 + --> tests/ui-toml/float_cmp/test.rs:49:21 | LL | let _ = x != y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:45:21 + --> tests/ui-toml/float_cmp/test.rs:50:21 | LL | let _ = x == 5.5; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:46:21 + --> tests/ui-toml/float_cmp/test.rs:51:21 | LL | let _ = 5.5 == x; | ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:69:21 + --> tests/ui-toml/float_cmp/test.rs:74:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:70:21 + --> tests/ui-toml/float_cmp/test.rs:75:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:71:21 + --> tests/ui-toml/float_cmp/test.rs:76:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:72:21 + --> tests/ui-toml/float_cmp/test.rs:77:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:73:21 + --> tests/ui-toml/float_cmp/test.rs:78:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:89:21 + --> tests/ui-toml/float_cmp/test.rs:94:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:90:21 + --> tests/ui-toml/float_cmp/test.rs:95:21 | LL | let _ = x == [5.5; 4]; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:91:21 + --> tests/ui-toml/float_cmp/test.rs:96:21 | LL | let _ = [5.5; 4] == x; | ^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:92:21 + --> tests/ui-toml/float_cmp/test.rs:97:21 | LL | let _ = [0.0, 0.0, 0.0, 5.5] == x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:93:21 + --> tests/ui-toml/float_cmp/test.rs:98:21 | LL | let _ = x == [0.0, 0.0, 0.0, 5.5]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:111:21 + --> tests/ui-toml/float_cmp/test.rs:116:21 | LL | let _ = x == y; | ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:117:21 + --> tests/ui-toml/float_cmp/test.rs:122:21 | LL | let _ = x == y; | ^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:125:21 + --> tests/ui-toml/float_cmp/test.rs:130:21 | LL | let _ = x == f32::EPSILON; | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x - f32::EPSILON).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:126:21 + --> tests/ui-toml/float_cmp/test.rs:131:21 | LL | let _ = f32::EPSILON == x; | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:127:21 + --> tests/ui-toml/float_cmp/test.rs:132:21 | LL | let _ = &&x == &&core::f32::EPSILON; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(&&x - &&core::f32::EPSILON).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:128:21 + --> tests/ui-toml/float_cmp/test.rs:133:21 | LL | let _ = &&core::f32::EPSILON == &&x; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(&&core::f32::EPSILON - &&x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:129:21 + --> tests/ui-toml/float_cmp/test.rs:134:21 | LL | let _ = y == f32::EPSILON as f64; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(y - f32::EPSILON as f64).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:130:21 + --> tests/ui-toml/float_cmp/test.rs:135:21 | LL | let _ = f32::EPSILON as f64 == y; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON as f64 - y).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:132:21 + --> tests/ui-toml/float_cmp/test.rs:137:21 | LL | let _ = f32::EPSILON * x == x * x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON * x - x * x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:133:21 + --> tests/ui-toml/float_cmp/test.rs:138:21 | LL | let _ = x * x == f32::EPSILON * x; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - f32::EPSILON * x).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:138:21 + --> tests/ui-toml/float_cmp/test.rs:143:21 | LL | let _ = x == F32_ARRAY; | ^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:139:21 + --> tests/ui-toml/float_cmp/test.rs:144:21 | LL | let _ = F32_ARRAY == x; | ^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:140:21 + --> tests/ui-toml/float_cmp/test.rs:145:21 | LL | let _ = &&x == &&F32_ARRAY; | ^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` arrays - --> tests/ui-toml/float_cmp/test.rs:141:21 + --> tests/ui-toml/float_cmp/test.rs:146:21 | LL | let _ = &&F32_ARRAY == &&x; | ^^^^^^^^^^^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:158:17 + --> tests/ui-toml/float_cmp/test.rs:163:17 | LL | let _ = f(1.0) == f(5.0); | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:159:17 + --> tests/ui-toml/float_cmp/test.rs:164:17 | LL | let _ = 1.0 == f(5.0); | ^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1.0 - f(5.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:160:17 + --> tests/ui-toml/float_cmp/test.rs:165:17 | LL | let _ = f(1.0) + 1.0 != 5.0; | ^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) + 1.0 - 5.0).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:202:21 + --> tests/ui-toml/float_cmp/test.rs:207:21 | LL | let _ = x == C[1]; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(x - C[1]).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:203:21 + --> tests/ui-toml/float_cmp/test.rs:208:21 | LL | let _ = C[1] == x; | ^^^^^^^^^ help: consider comparing them within some margin of error: `(C[1] - x).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:293:21 + --> tests/ui-toml/float_cmp/test.rs:298:21 | LL | let _ = x.next().unwrap() == x.next().unwrap() + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.next().unwrap() - (x.next().unwrap() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:309:21 + --> tests/ui-toml/float_cmp/test.rs:314:21 | LL | let _ = x.f() + 1.0 == x.f(); | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() + 1.0 - x.f()).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:310:21 + --> tests/ui-toml/float_cmp/test.rs:315:21 | LL | let _ = x.f() == x.f() + 1.0; | ^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x.f() - (x.f() + 1.0)).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui-toml/float_cmp/test.rs:319:17 + --> tests/ui-toml/float_cmp/test.rs:324:17 | LL | let _ = f(1.0) == f(1.0) + 1.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f(1.0) - (f(1.0) + 1.0)).abs() < error_margin` diff --git a/tests/ui-toml/float_cmp/test.rs b/tests/ui-toml/float_cmp/test.rs index e28b94aef739..75d8d43a684c 100644 --- a/tests/ui-toml/float_cmp/test.rs +++ b/tests/ui-toml/float_cmp/test.rs @@ -7,7 +7,12 @@ // FIXME(f16_f128): const casting is not yet supported for these types. Add when available. #![deny(clippy::float_cmp)] -#![allow(clippy::op_ref, clippy::eq_op, clippy::legacy_numeric_constants)] +#![allow( + clippy::op_ref, + clippy::eq_op, + clippy::legacy_numeric_constants, + clippy::excessive_precision +)] const F32_ARRAY: [f32; 2] = [5.5, 5.5]; @@ -330,4 +335,12 @@ fn main() { let _ = &&x == &&x; } } + + // Constant to literal + { + fn _f(x: f64) { + let _ = f64::EPSILON == 2.2204460492503131E-16f64; + let _ = 2.2204460492503131E-16f64 == core::f64::EPSILON; + } + } }