diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 837fba7e8eb8..ac6c4125b383 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 aba3e24b5657..12ae050b97a1 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -1,7 +1,7 @@ //@no-rustfix #![warn(clippy::float_cmp)] -#![allow(clippy::op_ref)] +#![allow(clippy::op_ref, clippy::eq_op)] fn main() { { @@ -338,4 +338,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; + } + } }