Auto merge of #12765 - yusufraji:while-float, r=llogiq
Add new lint `while_float` This PR adds a nursery lint that checks for while loops comparing floating point values. changelog: ``` changelog: [`while_float`]: Checks for while loops comparing floating point values. ``` Fixes #758
This commit is contained in:
commit
2efebd2f0c
@ -5911,6 +5911,7 @@ Released 2018-09-13
|
||||
[`verbose_file_reads`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_file_reads
|
||||
[`vtable_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons
|
||||
[`waker_clone_wake`]: https://rust-lang.github.io/rust-clippy/master/index.html#waker_clone_wake
|
||||
[`while_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_float
|
||||
[`while_immutable_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_immutable_condition
|
||||
[`while_let_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_loop
|
||||
[`while_let_on_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator
|
||||
|
@ -293,6 +293,7 @@
|
||||
crate::loops::SAME_ITEM_PUSH_INFO,
|
||||
crate::loops::SINGLE_ELEMENT_LOOP_INFO,
|
||||
crate::loops::UNUSED_ENUMERATE_INDEX_INFO,
|
||||
crate::loops::WHILE_FLOAT_INFO,
|
||||
crate::loops::WHILE_IMMUTABLE_CONDITION_INFO,
|
||||
crate::loops::WHILE_LET_LOOP_INFO,
|
||||
crate::loops::WHILE_LET_ON_ITERATOR_INFO,
|
||||
|
@ -17,6 +17,7 @@
|
||||
mod single_element_loop;
|
||||
mod unused_enumerate_index;
|
||||
mod utils;
|
||||
mod while_float;
|
||||
mod while_immutable_condition;
|
||||
mod while_let_loop;
|
||||
mod while_let_on_iterator;
|
||||
@ -416,6 +417,39 @@
|
||||
"variables used within while expression are not mutated in the body"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for while loops comparing floating point values.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// If you increment floating point values, errors can compound,
|
||||
/// so, use integers instead if possible.
|
||||
///
|
||||
/// ### Known problems
|
||||
/// The lint will catch all while loops comparing floating point
|
||||
/// values without regarding the increment.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// let mut x = 0.0;
|
||||
/// while x < 42.0 {
|
||||
/// x += 1.0;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```no_run
|
||||
/// let mut x = 0;
|
||||
/// while x < 42 {
|
||||
/// x += 1;
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.80.0"]
|
||||
pub WHILE_FLOAT,
|
||||
nursery,
|
||||
"while loops comaparing floating point values"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks whether a for loop is being used to push a constant
|
||||
@ -706,6 +740,7 @@ pub fn new(msrv: Msrv, enforce_iter_loop_reborrow: bool) -> Self {
|
||||
NEVER_LOOP,
|
||||
MUT_RANGE_BOUND,
|
||||
WHILE_IMMUTABLE_CONDITION,
|
||||
WHILE_FLOAT,
|
||||
SAME_ITEM_PUSH,
|
||||
SINGLE_ELEMENT_LOOP,
|
||||
MISSING_SPIN_LOOP,
|
||||
@ -762,6 +797,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
|
||||
if let Some(higher::While { condition, body, span }) = higher::While::hir(expr) {
|
||||
while_immutable_condition::check(cx, condition, body);
|
||||
while_float::check(cx, condition);
|
||||
missing_spin_loop::check(cx, condition, body);
|
||||
manual_while_let_some::check(cx, condition, body, span);
|
||||
}
|
||||
|
20
clippy_lints/src/loops/while_float.rs
Normal file
20
clippy_lints/src/loops/while_float.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_hir::ExprKind;
|
||||
|
||||
pub(super) fn check(cx: &rustc_lint::LateContext<'_>, condition: &rustc_hir::Expr<'_>) {
|
||||
if let ExprKind::Binary(_op, left, right) = condition.kind
|
||||
&& is_float_type(cx, left)
|
||||
&& is_float_type(cx, right)
|
||||
{
|
||||
span_lint(
|
||||
cx,
|
||||
super::WHILE_FLOAT,
|
||||
condition.span,
|
||||
"while condition comparing floats",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn is_float_type(cx: &rustc_lint::LateContext<'_>, expr: &rustc_hir::Expr<'_>) -> bool {
|
||||
cx.typeck_results().expr_ty(expr).is_floating_point()
|
||||
}
|
14
tests/ui/while_float.rs
Normal file
14
tests/ui/while_float.rs
Normal file
@ -0,0 +1,14 @@
|
||||
#[deny(clippy::while_float)]
|
||||
fn main() {
|
||||
let mut x = 0.0_f32;
|
||||
while x < 42.0_f32 {
|
||||
x += 0.5;
|
||||
}
|
||||
while x < 42.0 {
|
||||
x += 1.0;
|
||||
}
|
||||
let mut x = 0;
|
||||
while x < 42 {
|
||||
x += 1;
|
||||
}
|
||||
}
|
20
tests/ui/while_float.stderr
Normal file
20
tests/ui/while_float.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error: while condition comparing floats
|
||||
--> tests/ui/while_float.rs:4:11
|
||||
|
|
||||
LL | while x < 42.0_f32 {
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> tests/ui/while_float.rs:1:8
|
||||
|
|
||||
LL | #[deny(clippy::while_float)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: while condition comparing floats
|
||||
--> tests/ui/while_float.rs:7:11
|
||||
|
|
||||
LL | while x < 42.0 {
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user