mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 21:23:56 +00:00
cast_abs_to_unsigned: do not remove cast if it's required
This commit is contained in:
parent
91644d1f1d
commit
a342f52f91
4 changed files with 157 additions and 23 deletions
|
@ -1,11 +1,10 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
use super::CAST_ABS_TO_UNSIGNED;
|
||||
|
@ -18,25 +17,28 @@ pub(super) fn check(
|
|||
cast_to: Ty<'_>,
|
||||
msrv: Option<RustcVersion>,
|
||||
) {
|
||||
if_chain! {
|
||||
if meets_msrv(msrv, msrvs::UNSIGNED_ABS);
|
||||
if cast_from.is_integral();
|
||||
if cast_to.is_integral();
|
||||
if cast_from.is_signed();
|
||||
if !cast_to.is_signed();
|
||||
if let ExprKind::MethodCall(method_path, args, _) = cast_expr.kind;
|
||||
if let method_name = method_path.ident.name.as_str();
|
||||
if method_name == "abs";
|
||||
then {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
CAST_ABS_TO_UNSIGNED,
|
||||
expr.span,
|
||||
&format!("casting the result of `{}::{}()` to {}", cast_from, method_name, cast_to),
|
||||
"replace with",
|
||||
format!("{}.unsigned_abs()", Sugg::hir(cx, &args[0], "..")),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
if meets_msrv(msrv, msrvs::UNSIGNED_ABS)
|
||||
&& let ty::Int(from) = cast_from.kind()
|
||||
&& let ty::Uint(to) = cast_to.kind()
|
||||
&& let ExprKind::MethodCall(method_path, args, _) = cast_expr.kind
|
||||
&& method_path.ident.name.as_str() == "abs"
|
||||
{
|
||||
let span = if from.bit_width() == to.bit_width() {
|
||||
expr.span
|
||||
} else {
|
||||
// if the result of `.unsigned_abs` would be a different type, keep the cast
|
||||
// e.g. `i64 -> usize`, `i16 -> u8`
|
||||
cast_expr.span
|
||||
};
|
||||
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
CAST_ABS_TO_UNSIGNED,
|
||||
span,
|
||||
&format!("casting the result of `{cast_from}::abs()` to {cast_to}"),
|
||||
"replace with",
|
||||
format!("{}.unsigned_abs()", Sugg::hir(cx, &args[0], "..")),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,4 +5,25 @@ fn main() {
|
|||
let x: i32 = -42;
|
||||
let y: u32 = x.unsigned_abs();
|
||||
println!("The absolute value of {} is {}", x, y);
|
||||
|
||||
let a: i32 = -3;
|
||||
let _: usize = a.unsigned_abs() as usize;
|
||||
let _: usize = a.unsigned_abs() as _;
|
||||
let _ = a.unsigned_abs() as usize;
|
||||
|
||||
let a: i64 = -3;
|
||||
let _ = a.unsigned_abs() as usize;
|
||||
let _ = a.unsigned_abs() as u8;
|
||||
let _ = a.unsigned_abs() as u16;
|
||||
let _ = a.unsigned_abs() as u32;
|
||||
let _ = a.unsigned_abs();
|
||||
let _ = a.unsigned_abs() as u128;
|
||||
|
||||
let a: isize = -3;
|
||||
let _ = a.unsigned_abs();
|
||||
let _ = a.unsigned_abs() as u8;
|
||||
let _ = a.unsigned_abs() as u16;
|
||||
let _ = a.unsigned_abs() as u32;
|
||||
let _ = a.unsigned_abs() as u64;
|
||||
let _ = a.unsigned_abs() as u128;
|
||||
}
|
||||
|
|
|
@ -5,4 +5,25 @@ fn main() {
|
|||
let x: i32 = -42;
|
||||
let y: u32 = x.abs() as u32;
|
||||
println!("The absolute value of {} is {}", x, y);
|
||||
|
||||
let a: i32 = -3;
|
||||
let _: usize = a.abs() as usize;
|
||||
let _: usize = a.abs() as _;
|
||||
let _ = a.abs() as usize;
|
||||
|
||||
let a: i64 = -3;
|
||||
let _ = a.abs() as usize;
|
||||
let _ = a.abs() as u8;
|
||||
let _ = a.abs() as u16;
|
||||
let _ = a.abs() as u32;
|
||||
let _ = a.abs() as u64;
|
||||
let _ = a.abs() as u128;
|
||||
|
||||
let a: isize = -3;
|
||||
let _ = a.abs() as usize;
|
||||
let _ = a.abs() as u8;
|
||||
let _ = a.abs() as u16;
|
||||
let _ = a.abs() as u32;
|
||||
let _ = a.abs() as u64;
|
||||
let _ = a.abs() as u128;
|
||||
}
|
||||
|
|
|
@ -6,5 +6,95 @@ LL | let y: u32 = x.abs() as u32;
|
|||
|
|
||||
= note: `-D clippy::cast-abs-to-unsigned` implied by `-D warnings`
|
||||
|
||||
error: aborting due to previous error
|
||||
error: casting the result of `i32::abs()` to usize
|
||||
--> $DIR/cast_abs_to_unsigned.rs:10:20
|
||||
|
|
||||
LL | let _: usize = a.abs() as usize;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `i32::abs()` to usize
|
||||
--> $DIR/cast_abs_to_unsigned.rs:11:20
|
||||
|
|
||||
LL | let _: usize = a.abs() as _;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `i32::abs()` to usize
|
||||
--> $DIR/cast_abs_to_unsigned.rs:12:13
|
||||
|
|
||||
LL | let _ = a.abs() as usize;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `i64::abs()` to usize
|
||||
--> $DIR/cast_abs_to_unsigned.rs:15:13
|
||||
|
|
||||
LL | let _ = a.abs() as usize;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `i64::abs()` to u8
|
||||
--> $DIR/cast_abs_to_unsigned.rs:16:13
|
||||
|
|
||||
LL | let _ = a.abs() as u8;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `i64::abs()` to u16
|
||||
--> $DIR/cast_abs_to_unsigned.rs:17:13
|
||||
|
|
||||
LL | let _ = a.abs() as u16;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `i64::abs()` to u32
|
||||
--> $DIR/cast_abs_to_unsigned.rs:18:13
|
||||
|
|
||||
LL | let _ = a.abs() as u32;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `i64::abs()` to u64
|
||||
--> $DIR/cast_abs_to_unsigned.rs:19:13
|
||||
|
|
||||
LL | let _ = a.abs() as u64;
|
||||
| ^^^^^^^^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `i64::abs()` to u128
|
||||
--> $DIR/cast_abs_to_unsigned.rs:20:13
|
||||
|
|
||||
LL | let _ = a.abs() as u128;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `isize::abs()` to usize
|
||||
--> $DIR/cast_abs_to_unsigned.rs:23:13
|
||||
|
|
||||
LL | let _ = a.abs() as usize;
|
||||
| ^^^^^^^^^^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `isize::abs()` to u8
|
||||
--> $DIR/cast_abs_to_unsigned.rs:24:13
|
||||
|
|
||||
LL | let _ = a.abs() as u8;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `isize::abs()` to u16
|
||||
--> $DIR/cast_abs_to_unsigned.rs:25:13
|
||||
|
|
||||
LL | let _ = a.abs() as u16;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `isize::abs()` to u32
|
||||
--> $DIR/cast_abs_to_unsigned.rs:26:13
|
||||
|
|
||||
LL | let _ = a.abs() as u32;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `isize::abs()` to u64
|
||||
--> $DIR/cast_abs_to_unsigned.rs:27:13
|
||||
|
|
||||
LL | let _ = a.abs() as u64;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: casting the result of `isize::abs()` to u128
|
||||
--> $DIR/cast_abs_to_unsigned.rs:28:13
|
||||
|
|
||||
LL | let _ = a.abs() as u128;
|
||||
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue