Skip to content

Commit d7c7056

Browse files
committed
Auto merge of #4910 - krishna-veerareddy:issue-1205-cmp-nan-against-consts, r=phansch
Detect comparisons with NAN constants Currently `cmp_nan` lint doesn't detect comparisons with NaN's if the operands are consts variables so to fix this we evaluate the const variables first before testing for NaN. changelog: Detect comparisons with NaN constants in `cmp_nan` lint Fixes #1205
2 parents c62396d + 460d5a3 commit d7c7056

File tree

3 files changed

+115
-24
lines changed

3 files changed

+115
-24
lines changed

clippy_lints/src/misc.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
343343
ExprKind::Binary(ref cmp, ref left, ref right) => {
344344
let op = cmp.node;
345345
if op.is_comparison() {
346-
if let ExprKind::Path(QPath::Resolved(_, ref path)) = left.kind {
347-
check_nan(cx, path, expr);
348-
}
349-
if let ExprKind::Path(QPath::Resolved(_, ref path)) = right.kind {
350-
check_nan(cx, path, expr);
351-
}
346+
check_nan(cx, left, expr);
347+
check_nan(cx, right, expr);
352348
check_to_owned(cx, left, right);
353349
check_to_owned(cx, right, left);
354350
}
@@ -444,14 +440,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
444440
}
445441
}
446442

447-
fn check_nan(cx: &LateContext<'_, '_>, path: &Path, expr: &Expr) {
448-
if !in_constant(cx, expr.hir_id) {
449-
if let Some(seg) = path.segments.last() {
450-
if seg.ident.name == sym!(NAN) {
443+
fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr, cmp_expr: &Expr) {
444+
if_chain! {
445+
if !in_constant(cx, cmp_expr.hir_id);
446+
if let Some((value, _)) = constant(cx, cx.tables, expr);
447+
then {
448+
let needs_lint = match value {
449+
Constant::F32(num) => num.is_nan(),
450+
Constant::F64(num) => num.is_nan(),
451+
_ => false,
452+
};
453+
454+
if needs_lint {
451455
span_lint(
452456
cx,
453457
CMP_NAN,
454-
expr.span,
458+
cmp_expr.span,
455459
"doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead",
456460
);
457461
}

tests/ui/cmp_nan.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
const NAN_F32: f32 = std::f32::NAN;
2+
const NAN_F64: f64 = std::f64::NAN;
3+
14
#[warn(clippy::cmp_nan)]
25
#[allow(clippy::float_cmp, clippy::no_effect, clippy::unnecessary_operation)]
36
fn main() {
@@ -8,6 +11,12 @@ fn main() {
811
x > std::f32::NAN;
912
x <= std::f32::NAN;
1013
x >= std::f32::NAN;
14+
x == NAN_F32;
15+
x != NAN_F32;
16+
x < NAN_F32;
17+
x > NAN_F32;
18+
x <= NAN_F32;
19+
x >= NAN_F32;
1120

1221
let y = 0f64;
1322
y == std::f64::NAN;
@@ -16,4 +25,10 @@ fn main() {
1625
y > std::f64::NAN;
1726
y <= std::f64::NAN;
1827
y >= std::f64::NAN;
28+
y == NAN_F64;
29+
y != NAN_F64;
30+
y < NAN_F64;
31+
y > NAN_F64;
32+
y <= NAN_F64;
33+
y >= NAN_F64;
1934
}

tests/ui/cmp_nan.stderr

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,148 @@
11
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
2-
--> $DIR/cmp_nan.rs:5:5
2+
--> $DIR/cmp_nan.rs:8:5
33
|
44
LL | x == std::f32::NAN;
55
| ^^^^^^^^^^^^^^^^^^
66
|
77
= note: `-D clippy::cmp-nan` implied by `-D warnings`
88

99
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
10-
--> $DIR/cmp_nan.rs:6:5
10+
--> $DIR/cmp_nan.rs:9:5
1111
|
1212
LL | x != std::f32::NAN;
1313
| ^^^^^^^^^^^^^^^^^^
1414

1515
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
16-
--> $DIR/cmp_nan.rs:7:5
16+
--> $DIR/cmp_nan.rs:10:5
1717
|
1818
LL | x < std::f32::NAN;
1919
| ^^^^^^^^^^^^^^^^^
2020

2121
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
22-
--> $DIR/cmp_nan.rs:8:5
22+
--> $DIR/cmp_nan.rs:11:5
2323
|
2424
LL | x > std::f32::NAN;
2525
| ^^^^^^^^^^^^^^^^^
2626

2727
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
28-
--> $DIR/cmp_nan.rs:9:5
28+
--> $DIR/cmp_nan.rs:12:5
2929
|
3030
LL | x <= std::f32::NAN;
3131
| ^^^^^^^^^^^^^^^^^^
3232

3333
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
34-
--> $DIR/cmp_nan.rs:10:5
34+
--> $DIR/cmp_nan.rs:13:5
3535
|
3636
LL | x >= std::f32::NAN;
3737
| ^^^^^^^^^^^^^^^^^^
3838

3939
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
40-
--> $DIR/cmp_nan.rs:13:5
40+
--> $DIR/cmp_nan.rs:14:5
41+
|
42+
LL | x == NAN_F32;
43+
| ^^^^^^^^^^^^
44+
45+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
46+
--> $DIR/cmp_nan.rs:15:5
47+
|
48+
LL | x != NAN_F32;
49+
| ^^^^^^^^^^^^
50+
51+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
52+
--> $DIR/cmp_nan.rs:16:5
53+
|
54+
LL | x < NAN_F32;
55+
| ^^^^^^^^^^^
56+
57+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
58+
--> $DIR/cmp_nan.rs:17:5
59+
|
60+
LL | x > NAN_F32;
61+
| ^^^^^^^^^^^
62+
63+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
64+
--> $DIR/cmp_nan.rs:18:5
65+
|
66+
LL | x <= NAN_F32;
67+
| ^^^^^^^^^^^^
68+
69+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
70+
--> $DIR/cmp_nan.rs:19:5
71+
|
72+
LL | x >= NAN_F32;
73+
| ^^^^^^^^^^^^
74+
75+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
76+
--> $DIR/cmp_nan.rs:22:5
4177
|
4278
LL | y == std::f64::NAN;
4379
| ^^^^^^^^^^^^^^^^^^
4480

4581
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
46-
--> $DIR/cmp_nan.rs:14:5
82+
--> $DIR/cmp_nan.rs:23:5
4783
|
4884
LL | y != std::f64::NAN;
4985
| ^^^^^^^^^^^^^^^^^^
5086

5187
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
52-
--> $DIR/cmp_nan.rs:15:5
88+
--> $DIR/cmp_nan.rs:24:5
5389
|
5490
LL | y < std::f64::NAN;
5591
| ^^^^^^^^^^^^^^^^^
5692

5793
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
58-
--> $DIR/cmp_nan.rs:16:5
94+
--> $DIR/cmp_nan.rs:25:5
5995
|
6096
LL | y > std::f64::NAN;
6197
| ^^^^^^^^^^^^^^^^^
6298

6399
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
64-
--> $DIR/cmp_nan.rs:17:5
100+
--> $DIR/cmp_nan.rs:26:5
65101
|
66102
LL | y <= std::f64::NAN;
67103
| ^^^^^^^^^^^^^^^^^^
68104

69105
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
70-
--> $DIR/cmp_nan.rs:18:5
106+
--> $DIR/cmp_nan.rs:27:5
71107
|
72108
LL | y >= std::f64::NAN;
73109
| ^^^^^^^^^^^^^^^^^^
74110

75-
error: aborting due to 12 previous errors
111+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
112+
--> $DIR/cmp_nan.rs:28:5
113+
|
114+
LL | y == NAN_F64;
115+
| ^^^^^^^^^^^^
116+
117+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
118+
--> $DIR/cmp_nan.rs:29:5
119+
|
120+
LL | y != NAN_F64;
121+
| ^^^^^^^^^^^^
122+
123+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
124+
--> $DIR/cmp_nan.rs:30:5
125+
|
126+
LL | y < NAN_F64;
127+
| ^^^^^^^^^^^
128+
129+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
130+
--> $DIR/cmp_nan.rs:31:5
131+
|
132+
LL | y > NAN_F64;
133+
| ^^^^^^^^^^^
134+
135+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
136+
--> $DIR/cmp_nan.rs:32:5
137+
|
138+
LL | y <= NAN_F64;
139+
| ^^^^^^^^^^^^
140+
141+
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
142+
--> $DIR/cmp_nan.rs:33:5
143+
|
144+
LL | y >= NAN_F64;
145+
| ^^^^^^^^^^^^
146+
147+
error: aborting due to 24 previous errors
76148

0 commit comments

Comments
 (0)