blob: 3729dfd3e86f27e414d62f09a2c3f9df9f5c85f2 [file] [log] [blame]
use super::TRANSMUTE_INT_TO_NON_ZERO;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::sugg;
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::sym;
/// Checks for `transmute_int_to_non_zero` lint.
/// Returns `true` if it's triggered, otherwise returns `false`.
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
e: &'tcx Expr<'_>,
from_ty: Ty<'tcx>,
to_ty: Ty<'tcx>,
arg: &'tcx Expr<'_>,
) -> bool {
let tcx = cx.tcx;
let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else {
return false;
};
if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
return false;
};
let int_ty = substs.type_at(0);
if from_ty != int_ty {
return false;
}
span_lint_and_then(
cx,
TRANSMUTE_INT_TO_NON_ZERO,
e.span,
format!("transmute from a `{from_ty}` to a `{}<{int_ty}>`", sym::NonZero),
|diag| {
let arg = sugg::Sugg::hir(cx, arg, "..");
diag.span_suggestion(
e.span,
"consider using",
format!("{}::{}({arg})", sym::NonZero, sym::new_unchecked),
Applicability::Unspecified,
);
},
);
true
}