]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #8866 - botahamec:unused-rounding, r=llogiq
authorbors <bors@rust-lang.org>
Thu, 26 May 2022 05:16:37 +0000 (05:16 +0000)
committerbors <bors@rust-lang.org>
Thu, 26 May 2022 05:16:37 +0000 (05:16 +0000)
Add new lint `[unused_rounding]`

fixes #39

changelog: added a ``[`unused_rounding`]`` lint to check for the rounding of whole-number literals

CHANGELOG.md
clippy_lints/src/lib.register_lints.rs
clippy_lints/src/lib.register_nursery.rs
clippy_lints/src/lib.rs
clippy_lints/src/unused_rounding.rs [new file with mode: 0644]
tests/ui/unused_rounding.fixed [new file with mode: 0644]
tests/ui/unused_rounding.rs [new file with mode: 0644]
tests/ui/unused_rounding.stderr [new file with mode: 0644]

index 0f6295a45f3fbbd63491a522c268f7ef24a068b1..137fd793e754c266768001d7483f7270963e2f1c 100644 (file)
@@ -3821,6 +3821,7 @@ Released 2018-09-13
 [`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect
 [`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount
 [`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label
+[`unused_rounding`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_rounding
 [`unused_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_self
 [`unused_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit
 [`unusual_byte_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unusual_byte_groupings
index 570d736518bde84802c671305f7afed333bb57e1..02171a0909ed7e9c9f4991384cf9a14937b053aa 100644 (file)
     unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
     unused_async::UNUSED_ASYNC,
     unused_io_amount::UNUSED_IO_AMOUNT,
+    unused_rounding::UNUSED_ROUNDING,
     unused_self::UNUSED_SELF,
     unused_unit::UNUSED_UNIT,
     unwrap::PANICKING_UNWRAP,
index ec187563b3f645a1c3c50d774cc8f2e26bf0d2ab..10808af363d7019d6bb393c37e29f7760a215b47 100644 (file)
@@ -32,5 +32,6 @@
     LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
     LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
     LintId::of(transmute::USELESS_TRANSMUTE),
+    LintId::of(unused_rounding::UNUSED_ROUNDING),
     LintId::of(use_self::USE_SELF),
 ])
index 5f636e5114bddbf76bad91fd964a84f0b56c852c..09435b06d0a1e403059f60e81b8836b8a8896452 100644 (file)
@@ -402,6 +402,7 @@ macro_rules! declare_clippy_lint {
 mod unsafe_removed_from_name;
 mod unused_async;
 mod unused_io_amount;
+mod unused_rounding;
 mod unused_self;
 mod unused_unit;
 mod unwrap;
@@ -906,6 +907,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| Box::new(rc_clone_in_vec_init::RcCloneInVecInit));
     store.register_early_pass(|| Box::new(duplicate_mod::DuplicateMod::default()));
     store.register_late_pass(|| Box::new(get_first::GetFirst));
+    store.register_early_pass(|| Box::new(unused_rounding::UnusedRounding));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/clippy_lints/src/unused_rounding.rs b/clippy_lints/src/unused_rounding.rs
new file mode 100644 (file)
index 0000000..306afe4
--- /dev/null
@@ -0,0 +1,69 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::ast::{Expr, ExprKind, LitFloatType, LitKind};
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+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
+    /// ```rust
+    /// let x = 1f32.ceil();
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// let x = 1f32;
+    /// ```
+    #[clippy::version = "1.62.0"]
+    pub UNUSED_ROUNDING,
+    nursery,
+    "Uselessly rounding a whole number floating-point literal"
+}
+declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);
+
+fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> {
+    if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind
+        && let method_name = name_ident.ident.name.as_str()
+        && (method_name == "ceil" || method_name == "round" || method_name == "floor")
+        && !args.is_empty()
+        && let ExprKind::Lit(spanned) = &args[0].kind
+        && let LitKind::Float(symbol, ty) = spanned.kind {
+            let f = symbol.as_str().parse::<f64>().unwrap();
+            let f_str = symbol.to_string() + if let LitFloatType::Suffixed(ty) = ty {
+                ty.name_str()
+            } else {
+                ""
+            };
+            if f.fract() == 0.0 {
+                Some((method_name, f_str))
+            } else {
+                None
+            }
+        } else {
+            None
+        }
+}
+
+impl EarlyLintPass for UnusedRounding {
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
+        if let Some((method_name, float)) = is_useless_rounding(expr) {
+            span_lint_and_sugg(
+                cx,
+                UNUSED_ROUNDING,
+                expr.span,
+                &format!("used the `{}` method with a whole number float", method_name),
+                &format!("remove the `{}` method call", method_name),
+                float,
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+}
diff --git a/tests/ui/unused_rounding.fixed b/tests/ui/unused_rounding.fixed
new file mode 100644 (file)
index 0000000..54f8580
--- /dev/null
@@ -0,0 +1,9 @@
+// run-rustfix
+#![warn(clippy::unused_rounding)]
+
+fn main() {
+    let _ = 1f32;
+    let _ = 1.0f64;
+    let _ = 1.00f32;
+    let _ = 2e-54f64.floor();
+}
diff --git a/tests/ui/unused_rounding.rs b/tests/ui/unused_rounding.rs
new file mode 100644 (file)
index 0000000..8d007bc
--- /dev/null
@@ -0,0 +1,9 @@
+// run-rustfix
+#![warn(clippy::unused_rounding)]
+
+fn main() {
+    let _ = 1f32.ceil();
+    let _ = 1.0f64.floor();
+    let _ = 1.00f32.round();
+    let _ = 2e-54f64.floor();
+}
diff --git a/tests/ui/unused_rounding.stderr b/tests/ui/unused_rounding.stderr
new file mode 100644 (file)
index 0000000..6cfb02e
--- /dev/null
@@ -0,0 +1,22 @@
+error: used the `ceil` method with a whole number float
+  --> $DIR/unused_rounding.rs:5:13
+   |
+LL |     let _ = 1f32.ceil();
+   |             ^^^^^^^^^^^ help: remove the `ceil` method call: `1f32`
+   |
+   = note: `-D clippy::unused-rounding` implied by `-D warnings`
+
+error: used the `floor` method with a whole number float
+  --> $DIR/unused_rounding.rs:6:13
+   |
+LL |     let _ = 1.0f64.floor();
+   |             ^^^^^^^^^^^^^^ help: remove the `floor` method call: `1.0f64`
+
+error: used the `round` method with a whole number float
+  --> $DIR/unused_rounding.rs:7:13
+   |
+LL |     let _ = 1.00f32.round();
+   |             ^^^^^^^^^^^^^^^ help: remove the `round` method call: `1.00f32`
+
+error: aborting due to 3 previous errors
+