about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDharma Saputra Wijaya <dswijj@gmail.com>2022-01-25 22:19:19 +0800
committerdswij <dswijj@gmail.com>2022-01-26 15:02:13 +0800
commit0d7273fef6e2d3861afbb65ca70d21b43ac764fe (patch)
tree0a3c5755aeb372a3c02d072d8c9bd364187d2c23
parenta26c412e2852489abbbd69f53576255c4eac9c25 (diff)
downloadrust-0d7273fef6e2d3861afbb65ca70d21b43ac764fe.tar.gz
rust-0d7273fef6e2d3861afbb65ca70d21b43ac764fe.zip
fix bad suggestion on `numeric_literal`
-rw-r--r--clippy_lints/src/casts/unnecessary_cast.rs11
-rw-r--r--clippy_utils/src/numeric_literal.rs9
-rw-r--r--tests/ui/unnecessary_cast.rs7
-rw-r--r--tests/ui/unnecessary_cast.stderr38
4 files changed, 52 insertions, 13 deletions
diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs
index 1915d990c12..470c8c7ea26 100644
--- a/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/clippy_lints/src/casts/unnecessary_cast.rs
@@ -23,15 +23,14 @@ pub(super) fn check(
 
         if_chain! {
             if let LitKind::Int(n, _) = lit.node;
-            if let Some(src) = snippet_opt(cx, lit.span);
+            if let Some(src) = snippet_opt(cx, cast_expr.span);
             if cast_to.is_floating_point();
             if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node);
             let from_nbits = 128 - n.leading_zeros();
             let to_nbits = fp_ty_mantissa_nbits(cast_to);
             if from_nbits != 0 && to_nbits != 0 && from_nbits <= to_nbits && num_lit.is_decimal();
             then {
-                let literal_str = if is_unary_neg(cast_expr) { format!("-{}", num_lit.integer) } else { num_lit.integer.into() };
-                lint_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to);
+                lint_unnecessary_cast(cx, expr, num_lit.integer, cast_from, cast_to);
                 return true
             }
         }
@@ -48,7 +47,7 @@ pub(super) fn check(
             | LitKind::Float(_, LitFloatType::Suffixed(_))
                 if cast_from.kind() == cast_to.kind() =>
             {
-                if let Some(src) = snippet_opt(cx, lit.span) {
+                if let Some(src) = snippet_opt(cx, cast_expr.span) {
                     if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node) {
                         lint_unnecessary_cast(cx, expr, num_lit.integer, cast_from, cast_to);
                     }
@@ -113,7 +112,3 @@ fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 {
         _ => 0,
     }
 }
-
-fn is_unary_neg(expr: &Expr<'_>) -> bool {
-    matches!(expr.kind, ExprKind::Unary(UnOp::Neg, _))
-}
diff --git a/clippy_utils/src/numeric_literal.rs b/clippy_utils/src/numeric_literal.rs
index 68dd1b29845..908ff822712 100644
--- a/clippy_utils/src/numeric_literal.rs
+++ b/clippy_utils/src/numeric_literal.rs
@@ -51,7 +51,14 @@ impl<'a> NumericLiteral<'a> {
     }
 
     pub fn from_lit_kind(src: &'a str, lit_kind: &LitKind) -> Option<NumericLiteral<'a>> {
-        if lit_kind.is_numeric() && src.chars().next().map_or(false, |c| c.is_digit(10)) {
+        let unsigned_src = src.strip_prefix('-').map_or(src, |s| s);
+        if lit_kind.is_numeric()
+            && unsigned_src
+                .trim_start()
+                .chars()
+                .next()
+                .map_or(false, |c| c.is_digit(10))
+        {
             let (unsuffixed, suffix) = split_suffix(src, lit_kind);
             let float = matches!(lit_kind, LitKind::Float(..));
             Some(NumericLiteral::new(unsuffixed, suffix, float))
diff --git a/tests/ui/unnecessary_cast.rs b/tests/ui/unnecessary_cast.rs
index e8f2fb46665..b77c19f2ba5 100644
--- a/tests/ui/unnecessary_cast.rs
+++ b/tests/ui/unnecessary_cast.rs
@@ -1,6 +1,7 @@
 #![warn(clippy::unnecessary_cast)]
 #![allow(clippy::no_effect)]
 
+#[rustfmt::skip]
 fn main() {
     // Test cast_unnecessary
     1i32 as i32;
@@ -8,6 +9,12 @@ fn main() {
     false as bool;
     &1i32 as &i32;
 
+    -1_i32 as i32;
+    - 1_i32 as i32;
+    -1f32 as f32;
+    1_i32 as i32;
+    1_f32 as f32;
+
     // macro version
     macro_rules! foo {
         ($a:ident, $b:ident) => {
diff --git a/tests/ui/unnecessary_cast.stderr b/tests/ui/unnecessary_cast.stderr
index 70aa448af68..a5a93c6110c 100644
--- a/tests/ui/unnecessary_cast.stderr
+++ b/tests/ui/unnecessary_cast.stderr
@@ -1,5 +1,5 @@
 error: casting integer literal to `i32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:6:5
+  --> $DIR/unnecessary_cast.rs:7:5
    |
 LL |     1i32 as i32;
    |     ^^^^^^^^^^^ help: try: `1_i32`
@@ -7,16 +7,46 @@ LL |     1i32 as i32;
    = note: `-D clippy::unnecessary-cast` implied by `-D warnings`
 
 error: casting float literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:7:5
+  --> $DIR/unnecessary_cast.rs:8:5
    |
 LL |     1f32 as f32;
    |     ^^^^^^^^^^^ help: try: `1_f32`
 
 error: casting to the same type is unnecessary (`bool` -> `bool`)
-  --> $DIR/unnecessary_cast.rs:8:5
+  --> $DIR/unnecessary_cast.rs:9:5
    |
 LL |     false as bool;
    |     ^^^^^^^^^^^^^ help: try: `false`
 
-error: aborting due to 3 previous errors
+error: casting integer literal to `i32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:12:5
+   |
+LL |     -1_i32 as i32;
+   |     ^^^^^^^^^^^^^ help: try: `-1_i32`
+
+error: casting integer literal to `i32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:13:5
+   |
+LL |     - 1_i32 as i32;
+   |     ^^^^^^^^^^^^^^ help: try: `- 1_i32`
+
+error: casting float literal to `f32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:14:5
+   |
+LL |     -1f32 as f32;
+   |     ^^^^^^^^^^^^ help: try: `-1_f32`
+
+error: casting integer literal to `i32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:15:5
+   |
+LL |     1_i32 as i32;
+   |     ^^^^^^^^^^^^ help: try: `1_i32`
+
+error: casting float literal to `f32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:16:5
+   |
+LL |     1_f32 as f32;
+   |     ^^^^^^^^^^^^ help: try: `1_f32`
+
+error: aborting due to 8 previous errors