]> git.proxmox.com Git - rustc.git/blobdiff - src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
New upstream version 1.52.1+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / casts / cast_possible_truncation.rs
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
new file mode 100644 (file)
index 0000000..33b06b8
--- /dev/null
@@ -0,0 +1,54 @@
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_middle::ty::{self, FloatTy, Ty};
+
+use crate::utils::{is_isize_or_usize, span_lint};
+
+use super::{utils, CAST_POSSIBLE_TRUNCATION};
+
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
+    let msg = match (cast_from.is_integral(), cast_to.is_integral()) {
+        (true, true) => {
+            let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx);
+            let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
+
+            let (should_lint, suffix) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) {
+                (true, true) | (false, false) => (to_nbits < from_nbits, ""),
+                (true, false) => (
+                    to_nbits <= 32,
+                    if to_nbits == 32 {
+                        " on targets with 64-bit wide pointers"
+                    } else {
+                        ""
+                    },
+                ),
+                (false, true) => (from_nbits == 64, " on targets with 32-bit wide pointers"),
+            };
+
+            if !should_lint {
+                return;
+            }
+
+            format!(
+                "casting `{}` to `{}` may truncate the value{}",
+                cast_from, cast_to, suffix,
+            )
+        },
+
+        (false, true) => {
+            format!("casting `{}` to `{}` may truncate the value", cast_from, cast_to)
+        },
+
+        (_, _) => {
+            if matches!(cast_from.kind(), &ty::Float(FloatTy::F64))
+                && matches!(cast_to.kind(), &ty::Float(FloatTy::F32))
+            {
+                "casting `f64` to `f32` may truncate the value".to_string()
+            } else {
+                return;
+            }
+        },
+    };
+
+    span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span, &msg);
+}