2 use rustc_lint::LateContext;
3 use rustc_middle::ty::Ty;
5 use crate::utils::{is_isize_or_usize, span_lint};
7 use super::{utils, CAST_POSSIBLE_WRAP};
9 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
10 if !(cast_from.is_integral() && cast_to.is_integral()) {
14 let arch_64_suffix = " on targets with 64-bit wide pointers";
15 let arch_32_suffix = " on targets with 32-bit wide pointers";
16 let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed();
17 let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx);
18 let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
20 let (should_lint, suffix) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) {
21 (true, true) | (false, false) => (to_nbits == from_nbits && cast_unsigned_to_signed, ""),
22 (true, false) => (to_nbits <= 32 && cast_unsigned_to_signed, arch_32_suffix),
24 cast_unsigned_to_signed,
39 "casting `{}` to `{}` may wrap around the value{}",
40 cast_from, cast_to, suffix,