]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs
Merge commit '0eff589afc83e21a03a168497bbab6b4dfbb4ef6' into clippyup
[rust.git] / src / tools / clippy / clippy_lints / src / casts / cast_possible_wrap.rs
1 use clippy_utils::diagnostics::span_lint;
2 use clippy_utils::ty::is_isize_or_usize;
3 use rustc_hir::Expr;
4 use rustc_lint::LateContext;
5 use rustc_middle::ty::Ty;
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 }