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
|
[`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
|
[`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
|
[`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_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_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
|
[`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::SAME_ITEM_PUSH_INFO,
|
||||||
crate::loops::SINGLE_ELEMENT_LOOP_INFO,
|
crate::loops::SINGLE_ELEMENT_LOOP_INFO,
|
||||||
crate::loops::UNUSED_ENUMERATE_INDEX_INFO,
|
crate::loops::UNUSED_ENUMERATE_INDEX_INFO,
|
||||||
|
crate::loops::WHILE_FLOAT_INFO,
|
||||||
crate::loops::WHILE_IMMUTABLE_CONDITION_INFO,
|
crate::loops::WHILE_IMMUTABLE_CONDITION_INFO,
|
||||||
crate::loops::WHILE_LET_LOOP_INFO,
|
crate::loops::WHILE_LET_LOOP_INFO,
|
||||||
crate::loops::WHILE_LET_ON_ITERATOR_INFO,
|
crate::loops::WHILE_LET_ON_ITERATOR_INFO,
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
mod single_element_loop;
|
mod single_element_loop;
|
||||||
mod unused_enumerate_index;
|
mod unused_enumerate_index;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod while_float;
|
||||||
mod while_immutable_condition;
|
mod while_immutable_condition;
|
||||||
mod while_let_loop;
|
mod while_let_loop;
|
||||||
mod while_let_on_iterator;
|
mod while_let_on_iterator;
|
||||||
@ -416,6 +417,39 @@
|
|||||||
"variables used within while expression are not mutated in the body"
|
"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! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Checks whether a for loop is being used to push a constant
|
/// 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,
|
NEVER_LOOP,
|
||||||
MUT_RANGE_BOUND,
|
MUT_RANGE_BOUND,
|
||||||
WHILE_IMMUTABLE_CONDITION,
|
WHILE_IMMUTABLE_CONDITION,
|
||||||
|
WHILE_FLOAT,
|
||||||
SAME_ITEM_PUSH,
|
SAME_ITEM_PUSH,
|
||||||
SINGLE_ELEMENT_LOOP,
|
SINGLE_ELEMENT_LOOP,
|
||||||
MISSING_SPIN_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) {
|
if let Some(higher::While { condition, body, span }) = higher::While::hir(expr) {
|
||||||
while_immutable_condition::check(cx, condition, body);
|
while_immutable_condition::check(cx, condition, body);
|
||||||
|
while_float::check(cx, condition);
|
||||||
missing_spin_loop::check(cx, condition, body);
|
missing_spin_loop::check(cx, condition, body);
|
||||||
manual_while_let_some::check(cx, condition, body, span);
|
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