Skip to content

Commit e1550af

Browse files
committed
float_cmp: Allow named constants by path.
1 parent 63d5498 commit e1550af

File tree

12 files changed

+145
-134
lines changed

12 files changed

+145
-134
lines changed

clippy_config/src/conf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ define_Conf! {
657657
/// x == VALUE
658658
/// }
659659
/// ```
660-
(float_cmp_allowed_constants: Vec<String> = true),
660+
(float_cmp_allowed_constants: Vec<String> = Vec::new()),
661661
/// Lint: FLOAT_CMP
662662
///
663663
/// Whether to ignore comparisons which have a constant result.

clippy_lints/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
816816
store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(conf)));
817817
store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(conf)));
818818
store.register_late_pass(move |_| Box::new(manual_rotate::ManualRotate));
819-
store.register_late_pass(move |_| Box::new(operators::Operators::new(conf)));
819+
store.register_late_pass(move |tcx| Box::new(operators::Operators::new(tcx, conf)));
820820
store.register_late_pass(|_| Box::<std_instead_of_core::StdReexports>::default());
821821
store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(conf)));
822822
store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));

clippy_lints/src/operators/float_cmp.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::consts::{constant, Constant};
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::sugg::Sugg;
44
use clippy_utils::visitors::{for_each_expr_without_closures, is_const_evaluatable};
5-
use clippy_utils::{get_item_name, is_expr_named_const, path_res, peel_hir_expr_while, SpanlessEq};
5+
use clippy_utils::{get_item_name, get_named_const_def_id, path_res, peel_hir_expr_while, SpanlessEq};
66
use core::ops::ControlFlow;
77
use rustc_errors::Applicability;
88
use rustc_hir::def::Res;
@@ -14,7 +14,7 @@ use super::{FloatCmpConfig, FLOAT_CMP};
1414

1515
pub(crate) fn check<'tcx>(
1616
cx: &LateContext<'tcx>,
17-
config: FloatCmpConfig,
17+
config: &FloatCmpConfig,
1818
expr: &'tcx Expr<'_>,
1919
op: BinOpKind,
2020
left: &'tcx Expr<'_>,
@@ -56,8 +56,8 @@ pub(crate) fn check<'tcx>(
5656
return;
5757
}
5858

59-
if config.ignore_named_constants
60-
&& (is_expr_named_const(cx, left_reduced) || is_expr_named_const(cx, right_reduced))
59+
if get_named_const_def_id(cx, left_reduced).is_some_and(|id| config.allowed_constants.contains(&id))
60+
|| get_named_const_def_id(cx, right_reduced).is_some_and(|id| config.allowed_constants.contains(&id))
6161
{
6262
return;
6363
}

clippy_lints/src/operators/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use clippy_utils::def_path_def_ids;
2828
use rustc_hir::def_id::DefIdSet;
2929
use rustc_hir::{Body, Expr, ExprKind, UnOp};
3030
use rustc_lint::{LateContext, LateLintPass};
31+
use rustc_middle::ty::TyCtxt;
3132
use rustc_session::impl_lint_pass;
3233

3334
declare_clippy_lint! {
@@ -789,7 +790,7 @@ pub struct Operators {
789790
float_cmp_config: FloatCmpConfig,
790791
}
791792
impl Operators {
792-
pub fn new(conf: &'static Conf) -> Self {
793+
pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
793794
Self {
794795
arithmetic_context: numeric_arithmetic::Context::default(),
795796
verbose_bit_mask_threshold: conf.verbose_bit_mask_threshold,
@@ -859,7 +860,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
859860
float_equality_without_abs::check(cx, e, op.node, lhs, rhs);
860861
integer_division::check(cx, e, op.node, lhs, rhs);
861862
cmp_owned::check(cx, op.node, lhs, rhs);
862-
float_cmp::check(cx, self.float_cmp_config, e, op.node, lhs, rhs);
863+
float_cmp::check(cx, &self.float_cmp_config, e, op.node, lhs, rhs);
863864
modulo_one::check(cx, e, op.node, rhs);
864865
modulo_arithmetic::check(
865866
cx,

clippy_utils/src/lib.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -245,14 +245,15 @@ pub fn is_inside_always_const_context(tcx: TyCtxt<'_>, hir_id: HirId) -> bool {
245245
}
246246
}
247247

248-
/// Checks if the expression is path to either a constant or an associated constant.
249-
pub fn is_expr_named_const<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
250-
matches!(&e.kind, ExprKind::Path(p)
251-
if matches!(
252-
cx.qpath_res(p, e.hir_id),
253-
Res::Def(DefKind::Const | DefKind::AssocConst, _)
254-
)
255-
)
248+
/// If the expression is path to either a constant or an associated constant get the `DefId`.
249+
pub fn get_named_const_def_id<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<DefId> {
250+
if let ExprKind::Path(p) = &e.kind
251+
&& let Res::Def(DefKind::Const | DefKind::AssocConst, id) = cx.qpath_res(p, e.hir_id)
252+
{
253+
Some(id)
254+
} else {
255+
None
256+
}
256257
}
257258

258259
/// Checks if a `Res` refers to a constructor of a `LangItem`
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
float-cmp-ignore-change-detection = false
2+
float-cmp-allowed-constants = [
3+
"core::f32::EPSILON",
4+
"f32::EPSILON",
5+
"test::F32_ARRAY",
6+
]
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
float-cmp-ignore-constant-comparisons = false
2+
float-cmp-allowed-constants = [
3+
"core::f32::EPSILON",
4+
"f32::EPSILON",
5+
"test::F32_ARRAY",
6+
]
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
float-cmp-ignore-named-constants = false

tests/ui-toml/float_cmp/test.change_detect.stderr

+26-26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: strict comparison of `f32` or `f64`
2-
--> tests/ui-toml/float_cmp/test.rs:15:21
2+
--> tests/ui-toml/float_cmp/test.rs:17:21
33
|
44
LL | let _ = x == y;
55
| ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin`
@@ -11,130 +11,130 @@ LL | #![deny(clippy::float_cmp)]
1111
| ^^^^^^^^^^^^^^^^^
1212

1313
error: strict comparison of `f32` or `f64`
14-
--> tests/ui-toml/float_cmp/test.rs:16:21
14+
--> tests/ui-toml/float_cmp/test.rs:18:21
1515
|
1616
LL | let _ = x != y;
1717
| ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin`
1818

1919
error: strict comparison of `f32` or `f64`
20-
--> tests/ui-toml/float_cmp/test.rs:17:21
20+
--> tests/ui-toml/float_cmp/test.rs:19:21
2121
|
2222
LL | let _ = x == 5.5;
2323
| ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin`
2424

2525
error: strict comparison of `f32` or `f64`
26-
--> tests/ui-toml/float_cmp/test.rs:18:21
26+
--> tests/ui-toml/float_cmp/test.rs:20:21
2727
|
2828
LL | let _ = 5.5 == x;
2929
| ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin`
3030

3131
error: strict comparison of `f32` or `f64`
32-
--> tests/ui-toml/float_cmp/test.rs:41:21
32+
--> tests/ui-toml/float_cmp/test.rs:43:21
3333
|
3434
LL | let _ = x == y;
3535
| ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin`
3636

3737
error: strict comparison of `f32` or `f64`
38-
--> tests/ui-toml/float_cmp/test.rs:42:21
38+
--> tests/ui-toml/float_cmp/test.rs:44:21
3939
|
4040
LL | let _ = x != y;
4141
| ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() > error_margin`
4242

4343
error: strict comparison of `f32` or `f64`
44-
--> tests/ui-toml/float_cmp/test.rs:43:21
44+
--> tests/ui-toml/float_cmp/test.rs:45:21
4545
|
4646
LL | let _ = x == 5.5;
4747
| ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 5.5).abs() < error_margin`
4848

4949
error: strict comparison of `f32` or `f64`
50-
--> tests/ui-toml/float_cmp/test.rs:44:21
50+
--> tests/ui-toml/float_cmp/test.rs:46:21
5151
|
5252
LL | let _ = 5.5 == x;
5353
| ^^^^^^^^ help: consider comparing them within some margin of error: `(5.5 - x).abs() < error_margin`
5454

5555
error: strict comparison of `f32` or `f64` arrays
56-
--> tests/ui-toml/float_cmp/test.rs:67:21
56+
--> tests/ui-toml/float_cmp/test.rs:69:21
5757
|
5858
LL | let _ = x == y;
5959
| ^^^^^^
6060

6161
error: strict comparison of `f32` or `f64` arrays
62-
--> tests/ui-toml/float_cmp/test.rs:68:21
62+
--> tests/ui-toml/float_cmp/test.rs:70:21
6363
|
6464
LL | let _ = x == [5.5; 4];
6565
| ^^^^^^^^^^^^^
6666

6767
error: strict comparison of `f32` or `f64` arrays
68-
--> tests/ui-toml/float_cmp/test.rs:69:21
68+
--> tests/ui-toml/float_cmp/test.rs:71:21
6969
|
7070
LL | let _ = [5.5; 4] == x;
7171
| ^^^^^^^^^^^^^
7272

7373
error: strict comparison of `f32` or `f64` arrays
74-
--> tests/ui-toml/float_cmp/test.rs:70:21
74+
--> tests/ui-toml/float_cmp/test.rs:72:21
7575
|
7676
LL | let _ = [0.0, 0.0, 0.0, 5.5] == x;
7777
| ^^^^^^^^^^^^^^^^^^^^^^^^^
7878

7979
error: strict comparison of `f32` or `f64` arrays
80-
--> tests/ui-toml/float_cmp/test.rs:71:21
80+
--> tests/ui-toml/float_cmp/test.rs:73:21
8181
|
8282
LL | let _ = x == [0.0, 0.0, 0.0, 5.5];
8383
| ^^^^^^^^^^^^^^^^^^^^^^^^^
8484

8585
error: strict comparison of `f32` or `f64` arrays
86-
--> tests/ui-toml/float_cmp/test.rs:87:21
86+
--> tests/ui-toml/float_cmp/test.rs:89:21
8787
|
8888
LL | let _ = x == y;
8989
| ^^^^^^
9090

9191
error: strict comparison of `f32` or `f64` arrays
92-
--> tests/ui-toml/float_cmp/test.rs:88:21
92+
--> tests/ui-toml/float_cmp/test.rs:90:21
9393
|
9494
LL | let _ = x == [5.5; 4];
9595
| ^^^^^^^^^^^^^
9696

9797
error: strict comparison of `f32` or `f64` arrays
98-
--> tests/ui-toml/float_cmp/test.rs:89:21
98+
--> tests/ui-toml/float_cmp/test.rs:91:21
9999
|
100100
LL | let _ = [5.5; 4] == x;
101101
| ^^^^^^^^^^^^^
102102

103103
error: strict comparison of `f32` or `f64` arrays
104-
--> tests/ui-toml/float_cmp/test.rs:90:21
104+
--> tests/ui-toml/float_cmp/test.rs:92:21
105105
|
106106
LL | let _ = [0.0, 0.0, 0.0, 5.5] == x;
107107
| ^^^^^^^^^^^^^^^^^^^^^^^^^
108108

109109
error: strict comparison of `f32` or `f64` arrays
110-
--> tests/ui-toml/float_cmp/test.rs:91:21
110+
--> tests/ui-toml/float_cmp/test.rs:93:21
111111
|
112112
LL | let _ = x == [0.0, 0.0, 0.0, 5.5];
113113
| ^^^^^^^^^^^^^^^^^^^^^^^^^
114114

115115
error: strict comparison of `f32` or `f64`
116-
--> tests/ui-toml/float_cmp/test.rs:109:21
116+
--> tests/ui-toml/float_cmp/test.rs:111:21
117117
|
118118
LL | let _ = x == y;
119119
| ^^^^^^ help: consider comparing them within some margin of error: `(x - y).abs() < error_margin`
120120

121121
error: strict comparison of `f32` or `f64` arrays
122-
--> tests/ui-toml/float_cmp/test.rs:115:21
122+
--> tests/ui-toml/float_cmp/test.rs:117:21
123123
|
124124
LL | let _ = x == y;
125125
| ^^^^^^
126126

127127
error: strict comparison of `f32` or `f64`
128-
--> tests/ui-toml/float_cmp/test.rs:131:21
128+
--> tests/ui-toml/float_cmp/test.rs:132:21
129129
|
130-
LL | let _ = C * x == x * x;
131-
| ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(C * x - x * x).abs() < error_margin`
130+
LL | let _ = f32::EPSILON * x == x * x;
131+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(f32::EPSILON * x - x * x).abs() < error_margin`
132132

133133
error: strict comparison of `f32` or `f64`
134-
--> tests/ui-toml/float_cmp/test.rs:132:21
134+
--> tests/ui-toml/float_cmp/test.rs:133:21
135135
|
136-
LL | let _ = x * x == C * x;
137-
| ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - C * x).abs() < error_margin`
136+
LL | let _ = x * x == f32::EPSILON * x;
137+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x * x - f32::EPSILON * x).abs() < error_margin`
138138

139139
error: strict comparison of `f32` or `f64`
140140
--> tests/ui-toml/float_cmp/test.rs:158:17

0 commit comments

Comments
 (0)