]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use rustc_hir::Expr; |
2 | use rustc_lint::LateContext; | |
3 | use rustc_middle::ty::Ty; | |
4 | ||
5 | use crate::utils::{is_isize_or_usize, span_lint}; | |
6 | ||
7 | use super::{utils, CAST_POSSIBLE_WRAP}; | |
8 | ||
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()) { | |
11 | return; | |
12 | } | |
13 | ||
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); | |
19 | ||
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), | |
23 | (false, true) => ( | |
24 | cast_unsigned_to_signed, | |
25 | if from_nbits == 64 { | |
26 | arch_64_suffix | |
27 | } else { | |
28 | arch_32_suffix | |
29 | }, | |
30 | ), | |
31 | }; | |
32 | ||
33 | if should_lint { | |
34 | span_lint( | |
35 | cx, | |
36 | CAST_POSSIBLE_WRAP, | |
37 | expr.span, | |
38 | &format!( | |
39 | "casting `{}` to `{}` may wrap around the value{}", | |
40 | cast_from, cast_to, suffix, | |
41 | ), | |
42 | ); | |
43 | } | |
44 | } |