1- use clippy_utils:: consts:: { constant_with_source , Constant } ;
1+ use clippy_utils:: consts:: { constant , Constant } ;
22use clippy_utils:: diagnostics:: span_lint_and_then;
3- use clippy_utils:: get_item_name;
43use clippy_utils:: sugg:: Sugg ;
4+ use clippy_utils:: visitors:: is_const_evaluatable;
5+ use clippy_utils:: { get_item_name, is_expr_named_const, peel_hir_expr_while} ;
56use rustc_errors:: Applicability ;
6- use rustc_hir:: { BinOpKind , Expr , ExprKind , UnOp } ;
7+ use rustc_hir:: { BinOpKind , BorrowKind , Expr , ExprKind , UnOp } ;
78use rustc_lint:: LateContext ;
89use rustc_middle:: ty;
910
10- use super :: { FLOAT_CMP , FLOAT_CMP_CONST } ;
11+ use super :: { FloatCmpConfig , FLOAT_CMP } ;
1112
1213pub ( crate ) fn check < ' tcx > (
1314 cx : & LateContext < ' tcx > ,
15+ config : FloatCmpConfig ,
1416 expr : & ' tcx Expr < ' _ > ,
1517 op : BinOpKind ,
1618 left : & ' tcx Expr < ' _ > ,
1719 right : & ' tcx Expr < ' _ > ,
1820) {
19- if ( op == BinOpKind :: Eq || op == BinOpKind :: Ne ) && is_float ( cx, left) {
20- let left_is_local = match constant_with_source ( cx, cx. typeck_results ( ) , left) {
21- Some ( ( c, s) ) if !is_allowed ( & c) => s. is_local ( ) ,
22- Some ( _) => return ,
23- None => true ,
24- } ;
25- let right_is_local = match constant_with_source ( cx, cx. typeck_results ( ) , right) {
26- Some ( ( c, s) ) if !is_allowed ( & c) => s. is_local ( ) ,
27- Some ( _) => return ,
28- None => true ,
29- } ;
30-
21+ if ( op == BinOpKind :: Eq || op == BinOpKind :: Ne )
22+ && is_float ( cx, left)
3123 // Allow comparing the results of signum()
32- if is_signum ( cx, left) && is_signum ( cx, right) {
24+ && !( is_signum ( cx, left) && is_signum ( cx, right) )
25+ {
26+ let left_c = constant ( cx, cx. typeck_results ( ) , left) ;
27+ let is_left_const = left_c. is_some ( ) ;
28+ if left_c. is_some_and ( |c| is_allowed ( & c) ) {
29+ return ;
30+ }
31+ let right_c = constant ( cx, cx. typeck_results ( ) , right) ;
32+ let is_right_const = right_c. is_some ( ) ;
33+ if right_c. is_some_and ( |c| is_allowed ( & c) ) {
34+ return ;
35+ }
36+
37+ if config. ignore_constant_comparisons
38+ && ( is_left_const || is_const_evaluatable ( cx, left) )
39+ && ( is_right_const || is_const_evaluatable ( cx, right) )
40+ {
41+ return ;
42+ }
43+
44+ let peel_expr = |e : & ' tcx Expr < ' tcx > | match e. kind {
45+ ExprKind :: Cast ( e, _) | ExprKind :: AddrOf ( BorrowKind :: Ref , _, e) => Some ( e) ,
46+ _ => None ,
47+ } ;
48+ if config. ignore_named_constants
49+ && ( is_expr_named_const ( cx, peel_hir_expr_while ( left, peel_expr) )
50+ || is_expr_named_const ( cx, peel_hir_expr_while ( right, peel_expr) ) )
51+ {
3352 return ;
3453 }
3554
@@ -40,8 +59,12 @@ pub(crate) fn check<'tcx>(
4059 }
4160 }
4261 let is_comparing_arrays = is_array ( cx, left) || is_array ( cx, right) ;
43- let ( lint, msg) = get_lint_and_message ( left_is_local && right_is_local, is_comparing_arrays) ;
44- span_lint_and_then ( cx, lint, expr. span , msg, |diag| {
62+ let msg = if is_comparing_arrays {
63+ "strict comparison of `f32` or `f64` arrays"
64+ } else {
65+ "strict comparison of `f32` or `f64`"
66+ } ;
67+ span_lint_and_then ( cx, FLOAT_CMP , expr. span , msg, |diag| {
4568 let lhs = Sugg :: hir ( cx, left, ".." ) ;
4669 let rhs = Sugg :: hir ( cx, right, ".." ) ;
4770
@@ -62,28 +85,6 @@ pub(crate) fn check<'tcx>(
6285 }
6386}
6487
65- fn get_lint_and_message ( is_local : bool , is_comparing_arrays : bool ) -> ( & ' static rustc_lint:: Lint , & ' static str ) {
66- if is_local {
67- (
68- FLOAT_CMP ,
69- if is_comparing_arrays {
70- "strict comparison of `f32` or `f64` arrays"
71- } else {
72- "strict comparison of `f32` or `f64`"
73- } ,
74- )
75- } else {
76- (
77- FLOAT_CMP_CONST ,
78- if is_comparing_arrays {
79- "strict comparison of `f32` or `f64` constant arrays"
80- } else {
81- "strict comparison of `f32` or `f64` constant"
82- } ,
83- )
84- }
85- }
86-
8788fn is_allowed ( val : & Constant < ' _ > ) -> bool {
8889 match val {
8990 Constant :: Ref ( val) => is_allowed ( val) ,
0 commit comments