Skip to content

Commit 49e864f

Browse files
committed
Refactor, remove Constant::to_bits
1 parent a0af2f8 commit 49e864f

File tree

4 files changed

+47
-34
lines changed

4 files changed

+47
-34
lines changed

clippy_lints/src/manual_float_methods.rs

+33-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use clippy_utils::{
2-
consts::constant, diagnostics::span_lint_and_then, is_from_proc_macro, path_to_local, source::snippet_opt,
2+
consts::{constant, Constant},
3+
diagnostics::span_lint_and_then,
4+
is_from_proc_macro, path_to_local,
5+
source::snippet_opt,
36
};
47
use rustc_errors::Applicability;
58
use rustc_hir::{BinOpKind, Expr, ExprKind};
@@ -9,10 +12,11 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
912

1013
declare_clippy_lint! {
1114
/// ### What it does
12-
/// Checks for `x == <float>::INFINITY || x == <float>::NEG_INFINITY`.
15+
/// Checks for manual `is_infinite` reimplementations
16+
/// (i.e., `x == <float>::INFINITY || x == <float>::NEG_INFINITY`).
1317
///
1418
/// ### Why is this bad?
15-
/// This should use the dedicated method instead, `is_infinite`.
19+
/// This should use the aforementioned dedicated method instead, `is_infinite`.
1620
///
1721
/// ### Example
1822
/// ```rust
@@ -31,20 +35,23 @@ declare_clippy_lint! {
3135
}
3236
declare_clippy_lint! {
3337
/// ### What it does
34-
/// Checks for `x != <float>::INFINITY && x != <float>::NEG_INFINITY`.
38+
/// Checks for manual `is_finite` reimplementations
39+
/// (i.e., `x != <float>::INFINITY && x != <float>::NEG_INFINITY`).
3540
///
3641
/// ### Why is this bad?
37-
/// This should use the dedicated method instead, `is_finite`.
42+
/// This should use the aforementioned dedicated method instead, `is_finite`.
3843
///
3944
/// ### Example
4045
/// ```rust
4146
/// # let x = 1.0f32;
4247
/// if x != f32::INFINITY && x != f32::NEG_INFINITY {}
48+
/// if x.abs() < f32::INFINITY {}
4349
/// ```
4450
/// Use instead:
4551
/// ```rust
4652
/// # let x = 1.0f32;
4753
/// if x.is_finite() {}
54+
/// if x.is_finite() {}
4855
/// ```
4956
#[clippy::version = "1.72.0"]
5057
pub MANUAL_IS_FINITE,
@@ -84,18 +91,20 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
8491
&& let ExprKind::Binary(rhs_kind, rhs_lhs, rhs_rhs) = rhs.kind
8592
// Checking all possible scenarios using a function would be a hopeless task, as we have
8693
// 16 possible alignments of constants/operands. For now, let's use `partition`.
87-
&& let (operands, consts) = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
94+
&& let (operands, constants) = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
8895
.into_iter()
8996
.partition::<Vec<&Expr<'_>>, _>(|i| path_to_local(i).is_some())
9097
&& let [first, second] = &*operands
91-
&& let Some([const_1, const_2]) = consts
98+
&& let Some([const_1, const_2]) = constants
9299
.into_iter()
93-
.map(|i| constant(cx, cx.typeck_results(), i).and_then(|c| c.to_bits()))
100+
.map(|i| constant(cx, cx.typeck_results(), i))
94101
.collect::<Option<Vec<_>>>()
95102
.as_deref()
96103
&& path_to_local(first).is_some_and(|f| path_to_local(second).is_some_and(|s| f == s))
97-
&& (is_infinity(*const_1) && is_neg_infinity(*const_2)
98-
|| is_neg_infinity(*const_1) && is_infinity(*const_2))
104+
// The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in
105+
// case somebody does that for some reason
106+
&& (is_infinity(const_1) && is_neg_infinity(const_2)
107+
|| is_neg_infinity(const_1) && is_infinity(const_2))
99108
&& let Some(local_snippet) = snippet_opt(cx, first.span)
100109
&& !is_from_proc_macro(cx, expr)
101110
{
@@ -141,18 +150,26 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
141150
format!("!{local_snippet}.is_infinite()"),
142151
Applicability::MaybeIncorrect,
143152
);
144-
}
153+
},
145154
}
146-
}
155+
},
147156
);
148157
}
149158
}
150159
}
151160

152-
fn is_infinity(bits: u128) -> bool {
153-
bits == 0x7f80_0000 || bits == 0x7ff0_0000_0000_0000
161+
fn is_infinity(constant: &Constant<'_>) -> bool {
162+
match constant {
163+
Constant::F32(float) => *float == f32::INFINITY,
164+
Constant::F64(float) => *float == f64::INFINITY,
165+
_ => false,
166+
}
154167
}
155168

156-
fn is_neg_infinity(bits: u128) -> bool {
157-
bits == 0xff80_0000 || bits == 0xfff0_0000_0000_0000
169+
fn is_neg_infinity(constant: &Constant<'_>) -> bool {
170+
match constant {
171+
Constant::F32(float) => *float == f32::NEG_INFINITY,
172+
Constant::F64(float) => *float == f64::NEG_INFINITY,
173+
_ => false,
174+
}
158175
}

clippy_utils/src/consts.rs

-11
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,6 @@ impl<'tcx> Constant<'tcx> {
190190
}
191191
}
192192

193-
/// Returns the bit representation if `self` is a bool, integer, or float.
194-
pub fn to_bits(&self) -> Option<u128> {
195-
match self {
196-
Constant::Int(int) => Some(*int),
197-
Constant::F32(float) => Some(u128::from(float.to_bits())),
198-
Constant::F64(float) => Some(u128::from(float.to_bits())),
199-
Constant::Bool(bool) => Some(u128::from(*bool)),
200-
_ => None,
201-
}
202-
}
203-
204193
/// Returns the integer value or `None` if `self` or `val_type` is not integer type.
205194
pub fn int_value(&self, cx: &LateContext<'_>, val_type: Ty<'_>) -> Option<FullInt> {
206195
if let Constant::Int(const_int) = *self {

tests/ui/manual_float_methods.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//@aux-build:proc_macros.rs:proc-macro
22
#![allow(clippy::needless_if, unused)]
33
#![warn(clippy::manual_is_infinite, clippy::manual_is_finite)]
4+
#![feature(inline_const)]
45

56
#[macro_use]
67
extern crate proc_macros;
@@ -20,8 +21,14 @@ fn main() {
2021
// Don't lint
2122
if x.is_infinite() {}
2223
if x.is_finite() {}
23-
// If they're doing it this way, they probably know what they're doing
2424
if x.abs() < f64::INFINITY {}
25+
if f64::INFINITY > x.abs() {}
26+
if f64::abs(x) < f64::INFINITY {}
27+
if f64::INFINITY > f64::abs(x) {}
28+
const X: f64 = 1.0f64;
29+
// Will be linted if `const_float_classify` is enabled
30+
if const { X == f64::INFINITY || X == f64::NEG_INFINITY } {}
31+
if const { X != f64::INFINITY && X != f64::NEG_INFINITY } {}
2532
external! {
2633
let x = 1.0;
2734
if x == f32::INFINITY || x == f32::NEG_INFINITY {}

tests/ui/manual_float_methods.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: manually checking if a float is infinite
2-
--> $DIR/manual_float_methods.rs:13:8
2+
--> $DIR/manual_float_methods.rs:14:8
33
|
44
LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {}
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
66
|
77
= note: `-D clippy::manual-is-infinite` implied by `-D warnings`
88

99
error: manually checking if a float is finite
10-
--> $DIR/manual_float_methods.rs:14:8
10+
--> $DIR/manual_float_methods.rs:15:8
1111
|
1212
LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {}
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -27,13 +27,13 @@ LL | if !x.is_infinite() {}
2727
| ~~~~~~~~~~~~~~~~
2828

2929
error: manually checking if a float is infinite
30-
--> $DIR/manual_float_methods.rs:15:8
30+
--> $DIR/manual_float_methods.rs:16:8
3131
|
3232
LL | if x == INFINITE || x == NEG_INFINITE {}
3333
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
3434

3535
error: manually checking if a float is finite
36-
--> $DIR/manual_float_methods.rs:16:8
36+
--> $DIR/manual_float_methods.rs:17:8
3737
|
3838
LL | if x != INFINITE && x != NEG_INFINITE {}
3939
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,13 +52,13 @@ LL | if !x.is_infinite() {}
5252
| ~~~~~~~~~~~~~~~~
5353

5454
error: manually checking if a float is infinite
55-
--> $DIR/manual_float_methods.rs:18:8
55+
--> $DIR/manual_float_methods.rs:19:8
5656
|
5757
LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {}
5858
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
5959

6060
error: manually checking if a float is finite
61-
--> $DIR/manual_float_methods.rs:19:8
61+
--> $DIR/manual_float_methods.rs:20:8
6262
|
6363
LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {}
6464
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)