diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs index 1915d990c126..470c8c7ea26a 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 68dd1b29845a..908ff822712f 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> { - 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 e8f2fb466659..b77c19f2ba59 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 70aa448af68e..a5a93c6110c6 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