44 lines
1.3 KiB
Rust
44 lines
1.3 KiB
Rust
use clippy_config::msrvs::{self, Msrv};
|
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
|
use clippy_utils::sugg::Sugg;
|
|
use rustc_errors::Applicability;
|
|
use rustc_hir::{Expr, ExprKind};
|
|
use rustc_lint::LateContext;
|
|
use rustc_middle::ty::{self, Ty};
|
|
|
|
use super::CAST_ABS_TO_UNSIGNED;
|
|
|
|
pub(super) fn check(
|
|
cx: &LateContext<'_>,
|
|
expr: &Expr<'_>,
|
|
cast_expr: &Expr<'_>,
|
|
cast_from: Ty<'_>,
|
|
cast_to: Ty<'_>,
|
|
msrv: &Msrv,
|
|
) {
|
|
if msrv.meets(msrvs::UNSIGNED_ABS)
|
|
&& let ty::Int(from) = cast_from.kind()
|
|
&& let ty::Uint(to) = cast_to.kind()
|
|
&& let ExprKind::MethodCall(method_path, receiver, ..) = 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, receiver, "..").maybe_par()),
|
|
Applicability::MachineApplicable,
|
|
);
|
|
}
|
|
}
|