mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-01-03 00:39:07 +00:00
51 lines
1.6 KiB
Rust
51 lines
1.6 KiB
Rust
use clippy_utils::diagnostics::span_lint;
|
|
use clippy_utils::ty::is_isize_or_usize;
|
|
use rustc_hir::Expr;
|
|
use rustc_lint::LateContext;
|
|
use rustc_middle::ty::{self, FloatTy, Ty};
|
|
|
|
use super::{utils, CAST_PRECISION_LOSS};
|
|
|
|
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
|
|
if !cast_from.is_integral() || cast_to.is_integral() {
|
|
return;
|
|
}
|
|
|
|
let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx);
|
|
let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() {
|
|
32
|
|
} else {
|
|
64
|
|
};
|
|
|
|
if !(is_isize_or_usize(cast_from) || from_nbits >= to_nbits) {
|
|
return;
|
|
}
|
|
|
|
let cast_to_f64 = to_nbits == 64;
|
|
let mantissa_nbits = if cast_to_f64 { 52 } else { 23 };
|
|
let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64;
|
|
let arch_dependent_str = "on targets with 64-bit wide pointers ";
|
|
let from_nbits_str = if arch_dependent {
|
|
"64".to_owned()
|
|
} else if is_isize_or_usize(cast_from) {
|
|
"32 or 64".to_owned()
|
|
} else {
|
|
utils::int_ty_to_nbits(cast_from, cx.tcx).to_string()
|
|
};
|
|
|
|
span_lint(
|
|
cx,
|
|
CAST_PRECISION_LOSS,
|
|
expr.span,
|
|
&format!(
|
|
"casting `{0}` to `{1}` causes a loss of precision {2}(`{0}` is {3} bits wide, \
|
|
but `{1}`'s mantissa is only {4} bits wide)",
|
|
cast_from,
|
|
if cast_to_f64 { "f64" } else { "f32" },
|
|
if arch_dependent { arch_dependent_str } else { "" },
|
|
from_nbits_str,
|
|
mantissa_nbits
|
|
),
|
|
);
|
|
}
|