Auto merge of #9870 - koka831:unformat-unused-rounding, r=Jarcho

Keep original literal notation in suggestion

While I did some investigation of https://github.com/rust-lang/rust-clippy/issues/9866 (I couldn't reproduce it though) I found that `unused_rounding` formats as follows:

```rust
3.0_f64.round() // => 3.0f64
```

This PR makes them preserve as the original notation.

```rust
3.0_f64.round() // => 3.0_f64
```

changelog: Suggestion Enhancement: [`unused_rounding`]: The suggestion now preserves the original float literal notation
This commit is contained in:
bors 2022-11-20 22:09:25 +00:00
commit a85c8f33ff
4 changed files with 23 additions and 11 deletions

View File

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet};
use rustc_ast::ast::{Expr, ExprKind, LitFloatType, LitKind}; use rustc_ast::ast::{Expr, ExprKind, LitKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -29,19 +29,15 @@ declare_clippy_lint! {
} }
declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]); declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);
fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> { fn is_useless_rounding<'a>(cx: &EarlyContext<'a>, expr: &'a Expr) -> Option<(&'a str, String)> {
if let ExprKind::MethodCall(name_ident, receiver, _, _) = &expr.kind if let ExprKind::MethodCall(name_ident, receiver, _, _) = &expr.kind
&& let method_name = name_ident.ident.name.as_str() && let method_name = name_ident.ident.name.as_str()
&& (method_name == "ceil" || method_name == "round" || method_name == "floor") && (method_name == "ceil" || method_name == "round" || method_name == "floor")
&& let ExprKind::Lit(spanned) = &receiver.kind && let ExprKind::Lit(spanned) = &receiver.kind
&& let LitKind::Float(symbol, ty) = spanned.kind { && let LitKind::Float(symbol, _) = spanned.kind {
let f = symbol.as_str().parse::<f64>().unwrap(); 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 { if f.fract() == 0.0 {
let f_str = snippet(cx, receiver.span, "..").to_string();
Some((method_name, f_str)) Some((method_name, f_str))
} else { } else {
None None
@ -53,7 +49,7 @@ fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> {
impl EarlyLintPass for UnusedRounding { impl EarlyLintPass for UnusedRounding {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
if let Some((method_name, float)) = is_useless_rounding(expr) { if let Some((method_name, float)) = is_useless_rounding(cx, expr) {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
UNUSED_ROUNDING, UNUSED_ROUNDING,

View File

@ -6,4 +6,9 @@ fn main() {
let _ = 1.0f64; let _ = 1.0f64;
let _ = 1.00f32; let _ = 1.00f32;
let _ = 2e-54f64.floor(); let _ = 2e-54f64.floor();
// issue9866
let _ = 3.3_f32.round();
let _ = 3.3_f64.round();
let _ = 3.0_f32;
} }

View File

@ -6,4 +6,9 @@ fn main() {
let _ = 1.0f64.floor(); let _ = 1.0f64.floor();
let _ = 1.00f32.round(); let _ = 1.00f32.round();
let _ = 2e-54f64.floor(); let _ = 2e-54f64.floor();
// issue9866
let _ = 3.3_f32.round();
let _ = 3.3_f64.round();
let _ = 3.0_f32.round();
} }

View File

@ -18,5 +18,11 @@ error: used the `round` method with a whole number float
LL | let _ = 1.00f32.round(); LL | let _ = 1.00f32.round();
| ^^^^^^^^^^^^^^^ help: remove the `round` method call: `1.00f32` | ^^^^^^^^^^^^^^^ help: remove the `round` method call: `1.00f32`
error: aborting due to 3 previous errors error: used the `round` method with a whole number float
--> $DIR/unused_rounding.rs:13:13
|
LL | let _ = 3.0_f32.round();
| ^^^^^^^^^^^^^^^ help: remove the `round` method call: `3.0_f32`
error: aborting due to 4 previous errors