Skip to content

Commit

Permalink
Auto merge of rust-lang#8866 - botahamec:unused-rounding, r=llogiq
Browse files Browse the repository at this point in the history
Add new lint `[unused_rounding]`

fixes rust-lang#39

changelog: added a ``[`unused_rounding`]`` lint to check for the rounding of whole-number literals
  • Loading branch information
bors committed May 26, 2022
2 parents 45785fe + f489954 commit bc4d39e
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/lib.register_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ store.register_lints(&[
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,
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/lib.register_nursery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
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),
])
2 changes: 2 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ mod unnested_or_patterns;
mod unsafe_removed_from_name;
mod unused_async;
mod unused_io_amount;
mod unused_rounding;
mod unused_self;
mod unused_unit;
mod unwrap;
Expand Down Expand Up @@ -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`
}

Expand Down
69 changes: 69 additions & 0 deletions clippy_lints/src/unused_rounding.rs
Original file line number Diff line number Diff line change
@@ -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,
);
}
}
}
9 changes: 9 additions & 0 deletions tests/ui/unused_rounding.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// run-rustfix
#![warn(clippy::unused_rounding)]

fn main() {
let _ = 1f32;
let _ = 1.0f64;
let _ = 1.00f32;
let _ = 2e-54f64.floor();
}
9 changes: 9 additions & 0 deletions tests/ui/unused_rounding.rs
Original file line number Diff line number Diff line change
@@ -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();
}
22 changes: 22 additions & 0 deletions tests/ui/unused_rounding.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit bc4d39e

Please sign in to comment.