]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use rustc_hir::Expr; |
2 | use rustc_lint::LateContext; | |
3 | use rustc_middle::ty::{self, FloatTy, Ty}; | |
4 | ||
5 | use crate::utils::{is_isize_or_usize, span_lint}; | |
6 | ||
7 | use super::{utils, CAST_POSSIBLE_TRUNCATION}; | |
8 | ||
9 | pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { | |
10 | let msg = match (cast_from.is_integral(), cast_to.is_integral()) { | |
11 | (true, true) => { | |
12 | let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx); | |
13 | let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); | |
14 | ||
15 | let (should_lint, suffix) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { | |
16 | (true, true) | (false, false) => (to_nbits < from_nbits, ""), | |
17 | (true, false) => ( | |
18 | to_nbits <= 32, | |
19 | if to_nbits == 32 { | |
20 | " on targets with 64-bit wide pointers" | |
21 | } else { | |
22 | "" | |
23 | }, | |
24 | ), | |
25 | (false, true) => (from_nbits == 64, " on targets with 32-bit wide pointers"), | |
26 | }; | |
27 | ||
28 | if !should_lint { | |
29 | return; | |
30 | } | |
31 | ||
32 | format!( | |
33 | "casting `{}` to `{}` may truncate the value{}", | |
34 | cast_from, cast_to, suffix, | |
35 | ) | |
36 | }, | |
37 | ||
38 | (false, true) => { | |
39 | format!("casting `{}` to `{}` may truncate the value", cast_from, cast_to) | |
40 | }, | |
41 | ||
42 | (_, _) => { | |
43 | if matches!(cast_from.kind(), &ty::Float(FloatTy::F64)) | |
44 | && matches!(cast_to.kind(), &ty::Float(FloatTy::F32)) | |
45 | { | |
46 | "casting `f64` to `f32` may truncate the value".to_string() | |
47 | } else { | |
48 | return; | |
49 | } | |
50 | }, | |
51 | }; | |
52 | ||
53 | span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span, &msg); | |
54 | } |