-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathunused_rounding.rs
65 lines (62 loc) · 2.12 KB
/
unused_rounding.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use rustc_ast::ast::{Expr, ExprKind, MethodCall};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
/// ### What it does
///
/// Detects cases where a whole-number literal float is being rounded, using
/// the `floor`, `ceil`, or `round` methods.
///
/// ### Why is this bad?
///
/// This is unnecessary and confusing to the reader. Doing this is probably a mistake.
///
/// ### Example
/// ```no_run
/// let x = 1f32.ceil();
/// ```
/// Use instead:
/// ```no_run
/// let x = 1f32;
/// ```
#[clippy::version = "1.63.0"]
pub UNUSED_ROUNDING,
nursery,
"Uselessly rounding a whole number floating-point literal"
}
declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);
fn is_useless_rounding<'a>(cx: &EarlyContext<'_>, expr: &'a Expr) -> Option<(&'a str, String)> {
if let ExprKind::MethodCall(box MethodCall {
seg: name_ident,
receiver,
..
}) = &expr.kind
&& let method_name = name_ident.ident.name.as_str()
&& (method_name == "ceil" || method_name == "round" || method_name == "floor")
&& let ExprKind::Lit(token_lit) = &receiver.kind
&& token_lit.is_semantic_float()
&& let Ok(f) = token_lit.symbol.as_str().replace('_', "").parse::<f64>()
{
(f.fract() == 0.0).then(|| (method_name, snippet(cx, receiver.span, "..").to_string()))
} else {
None
}
}
impl EarlyLintPass for UnusedRounding {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
if let Some((method_name, float)) = is_useless_rounding(cx, expr) {
span_lint_and_sugg(
cx,
UNUSED_ROUNDING,
expr.span,
format!("used the `{method_name}` method with a whole number float"),
format!("remove the `{method_name}` method call"),
float,
Applicability::MachineApplicable,
);
}
}
}