Skip to content

Commit 0534bf4

Browse files
committed
Move cast_possible_truncation to its own module
1 parent b12d751 commit 0534bf4

File tree

2 files changed

+68
-62
lines changed

2 files changed

+68
-62
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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+
}

clippy_lints/src/casts/mod.rs

Lines changed: 14 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod cast_lossless;
2+
mod cast_possible_truncation;
23
mod cast_precision_loss;
34
mod utils;
45

@@ -312,52 +313,18 @@ fn check_truncation_and_wrapping(cx: &LateContext<'_>, expr: &Expr<'_>, cast_fro
312313
let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed();
313314
let from_nbits = int_ty_to_nbits(cast_from, cx.tcx);
314315
let to_nbits = int_ty_to_nbits(cast_to, cx.tcx);
315-
let (span_truncation, suffix_truncation, span_wrap, suffix_wrap) =
316-
match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) {
317-
(true, true) | (false, false) => (
318-
to_nbits < from_nbits,
319-
ArchSuffix::None,
320-
to_nbits == from_nbits && cast_unsigned_to_signed,
321-
ArchSuffix::None,
322-
),
323-
(true, false) => (
324-
to_nbits <= 32,
325-
if to_nbits == 32 {
326-
ArchSuffix::_64
327-
} else {
328-
ArchSuffix::None
329-
},
330-
to_nbits <= 32 && cast_unsigned_to_signed,
331-
ArchSuffix::_32,
332-
),
333-
(false, true) => (
334-
from_nbits == 64,
335-
ArchSuffix::_32,
336-
cast_unsigned_to_signed,
337-
if from_nbits == 64 {
338-
ArchSuffix::_64
339-
} else {
340-
ArchSuffix::_32
341-
},
342-
),
343-
};
344-
if span_truncation {
345-
span_lint(
346-
cx,
347-
CAST_POSSIBLE_TRUNCATION,
348-
expr.span,
349-
&format!(
350-
"casting `{}` to `{}` may truncate the value{}",
351-
cast_from,
352-
cast_to,
353-
match suffix_truncation {
354-
ArchSuffix::_32 => arch_32_suffix,
355-
ArchSuffix::_64 => arch_64_suffix,
356-
ArchSuffix::None => "",
357-
}
358-
),
359-
);
360-
}
316+
let (span_wrap, suffix_wrap) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) {
317+
(true, true) | (false, false) => (to_nbits == from_nbits && cast_unsigned_to_signed, ArchSuffix::None),
318+
(true, false) => (to_nbits <= 32 && cast_unsigned_to_signed, ArchSuffix::_32),
319+
(false, true) => (
320+
cast_unsigned_to_signed,
321+
if from_nbits == 64 {
322+
ArchSuffix::_64
323+
} else {
324+
ArchSuffix::_32
325+
},
326+
),
327+
};
361328
if span_wrap {
362329
span_lint(
363330
cx,
@@ -529,14 +496,9 @@ fn lint_numeric_casts<'tcx>(
529496
) {
530497
cast_precision_loss::check(cx, expr, cast_from, cast_to);
531498
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to);
499+
cast_possible_truncation::check(cx, expr, cast_from, cast_to);
532500
match (cast_from.is_integral(), cast_to.is_integral()) {
533501
(false, true) => {
534-
span_lint(
535-
cx,
536-
CAST_POSSIBLE_TRUNCATION,
537-
expr.span,
538-
&format!("casting `{}` to `{}` may truncate the value", cast_from, cast_to),
539-
);
540502
if !cast_to.is_signed() {
541503
span_lint(
542504
cx,
@@ -553,16 +515,6 @@ fn lint_numeric_casts<'tcx>(
553515
check_loss_of_sign(cx, expr, cast_expr, cast_from, cast_to);
554516
check_truncation_and_wrapping(cx, expr, cast_from, cast_to);
555517
},
556-
(false, false) => {
557-
if let (&ty::Float(FloatTy::F64), &ty::Float(FloatTy::F32)) = (&cast_from.kind(), &cast_to.kind()) {
558-
span_lint(
559-
cx,
560-
CAST_POSSIBLE_TRUNCATION,
561-
expr.span,
562-
"casting `f64` to `f32` may truncate the value",
563-
);
564-
}
565-
},
566518
(_, _) => {},
567519
}
568520
}

0 commit comments

Comments
 (0)