[`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
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,
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),
])
mod unsafe_removed_from_name;
mod unused_async;
mod unused_io_amount;
+mod unused_rounding;
mod unused_self;
mod unused_unit;
mod unwrap;
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`
}
--- /dev/null
+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,
+ );
+ }
+ }
+}
--- /dev/null
+// run-rustfix
+#![warn(clippy::unused_rounding)]
+
+fn main() {
+ let _ = 1f32;
+ let _ = 1.0f64;
+ let _ = 1.00f32;
+ let _ = 2e-54f64.floor();
+}
--- /dev/null
+// run-rustfix
+#![warn(clippy::unused_rounding)]
+
+fn main() {
+ let _ = 1f32.ceil();
+ let _ = 1.0f64.floor();
+ let _ = 1.00f32.round();
+ let _ = 2e-54f64.floor();
+}
--- /dev/null
+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
+