about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTrevor Gross <tmgross@umich.edu>2025-05-29 03:51:43 +0000
committerTrevor Gross <tmgross@umich.edu>2025-05-29 03:56:08 +0000
commit877feef541542972f1bfeefe14624a17f23cef8d (patch)
tree97699f87e8dde6bcff69026f5def739cb4852016
parent851aa05aa0addf41507967952f1ac2d183751682 (diff)
downloadrust-877feef541542972f1bfeefe14624a17f23cef8d.tar.gz
rust-877feef541542972f1bfeefe14624a17f23cef8d.zip
Reuse `libm`'s `Caat` and `CastFrom` in `compiler-builtins`
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/add.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/conv.rs6
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/div.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/mul.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/trunc.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs6
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/traits.rs43
-rw-r--r--library/compiler-builtins/libm/src/math/support/int_traits.rs5
8 files changed, 16 insertions, 52 deletions
diff --git a/library/compiler-builtins/compiler-builtins/src/float/add.rs b/library/compiler-builtins/compiler-builtins/src/float/add.rs
index 43e3ae931ff..0cc362f705b 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/add.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/add.rs
@@ -168,7 +168,7 @@ where
     }
 
     // Low three bits are round, guard, and sticky.
-    let a_significand_i32: i32 = a_significand.cast();
+    let a_significand_i32: i32 = a_significand.cast_lossy();
     let round_guard_sticky: i32 = a_significand_i32 & 0x7;
 
     // Shift the significand into place, and mask off the implicit bit.
diff --git a/library/compiler-builtins/compiler-builtins/src/float/conv.rs b/library/compiler-builtins/compiler-builtins/src/float/conv.rs
index 9d732f2cdbc..75ea7ce0242 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/conv.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/conv.rs
@@ -74,7 +74,7 @@ mod int_to_float {
         F::Int: CastFrom<I>,
         Conv: Fn(I::Unsigned) -> F::Int,
     {
-        let sign_bit = F::Int::cast_from(i >> (I::BITS - 1)) << (F::BITS - 1);
+        let sign_bit = F::Int::cast_from_lossy(i >> (I::BITS - 1)) << (F::BITS - 1);
         F::from_bits(conv(i.unsigned_abs()) | sign_bit)
     }
 
@@ -166,7 +166,7 @@ mod int_to_float {
 
         // Within the upper `F::BITS`, everything except for the signifcand
         // gets truncated
-        let d1: u32 = (i_m >> (u128::BITS - f32::BITS - f32::SIG_BITS - 1)).cast();
+        let d1: u32 = (i_m >> (u128::BITS - f32::BITS - f32::SIG_BITS - 1)).cast_lossy();
 
         // The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
         // check if it is nonzero.
@@ -371,7 +371,7 @@ where
         let m_base = if I::Unsigned::BITS >= F::Int::BITS {
             I::Unsigned::cast_from(fbits) << (I::BITS - F::SIG_BITS - 1)
         } else {
-            I::Unsigned::cast_from(fbits >> (F::SIG_BITS - I::BITS + 1))
+            I::Unsigned::cast_from_lossy(fbits >> (F::SIG_BITS - I::BITS + 1))
         };
 
         // Set the implicit 1-bit.
diff --git a/library/compiler-builtins/compiler-builtins/src/float/div.rs b/library/compiler-builtins/compiler-builtins/src/float/div.rs
index 3e4f0e20d10..fc1fc085105 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/div.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/div.rs
@@ -482,7 +482,7 @@ where
 
         let ret = quotient.wrapping_shr(u32::cast_from(res_exponent.wrapping_neg()) + 1);
         residual_lo = a_significand
-            .wrapping_shl(significand_bits.wrapping_add(CastInto::<u32>::cast(res_exponent)))
+            .wrapping_shl(significand_bits.wrapping_add(CastInto::<u32>::cast_lossy(res_exponent)))
             .wrapping_sub(ret.wrapping_mul(b_significand) << 1);
         ret
     };
diff --git a/library/compiler-builtins/compiler-builtins/src/float/mul.rs b/library/compiler-builtins/compiler-builtins/src/float/mul.rs
index c811f140670..dbed3095cda 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/mul.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/mul.rs
@@ -143,7 +143,7 @@ where
         // a zero of the appropriate sign.  Mathematically there is no need to
         // handle this case separately, but we make it a special case to
         // simplify the shift logic.
-        let shift: u32 = one.wrapping_sub(product_exponent.cast()).cast();
+        let shift: u32 = one.wrapping_sub(product_exponent.cast_lossy()).cast();
         if shift >= bits {
             return F::from_bits(product_sign);
         }
diff --git a/library/compiler-builtins/compiler-builtins/src/float/trunc.rs b/library/compiler-builtins/compiler-builtins/src/float/trunc.rs
index ca8a0f368b5..93db5d8bbde 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/trunc.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/trunc.rs
@@ -50,7 +50,7 @@ where
         // The exponent of a is within the range of normal numbers in the
         // destination format.  We can convert by simply right-shifting with
         // rounding and adjusting the exponent.
-        abs_result = (a_abs >> sig_bits_delta).cast();
+        abs_result = (a_abs >> sig_bits_delta).cast_lossy();
         // Cast before shifting to prevent overflow.
         let bias_diff: R::Int = src_exp_bias.wrapping_sub(dst_exp_bias).cast();
         let tmp = bias_diff << R::SIG_BITS;
diff --git a/library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs b/library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs
index 8f63c22c8f7..1b0ae5b73ad 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs
@@ -20,18 +20,18 @@ mod implementation {
 
         const { assert!(I::BITS <= 64) };
         if I::BITS >= 64 {
-            r += ((u32::cast_from(x) == 0) as u32) << 5; // if (x has no 32 small bits) t = 32 else 0
+            r += ((u32::cast_from_lossy(x) == 0) as u32) << 5; // if (x has no 32 small bits) t = 32 else 0
             x >>= r; // remove 32 zero bits
         }
 
         if I::BITS >= 32 {
-            t = ((u16::cast_from(x) == 0) as u32) << 4; // if (x has no 16 small bits) t = 16 else 0
+            t = ((u16::cast_from_lossy(x) == 0) as u32) << 4; // if (x has no 16 small bits) t = 16 else 0
             r += t;
             x >>= t; // x = [0 - 0xFFFF] + higher garbage bits
         }
 
         const { assert!(I::BITS >= 16) };
-        t = ((u8::cast_from(x) == 0) as u32) << 3;
+        t = ((u8::cast_from_lossy(x) == 0) as u32) << 3;
         x >>= t; // x = [0 - 0xFF] + higher garbage bits
         r += t;
 
diff --git a/library/compiler-builtins/compiler-builtins/src/int/traits.rs b/library/compiler-builtins/compiler-builtins/src/int/traits.rs
index b474df366eb..25b9718ad53 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/traits.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/traits.rs
@@ -1,4 +1,4 @@
-pub use crate::support::{Int, MinInt};
+pub use crate::support::{CastFrom, CastInto, Int, MinInt};
 
 /// Trait for integers twice the bit width of another integer. This is implemented for all
 /// primitives except for `u8`, because there is not a smaller primitive.
@@ -97,44 +97,3 @@ impl_h_int!(
     i32 u32 i64,
     i64 u64 i128
 );
-
-/// Trait to express (possibly lossy) casting of integers
-pub trait CastInto<T: Copy>: Copy {
-    fn cast(self) -> T;
-}
-
-pub trait CastFrom<T: Copy>: Copy {
-    fn cast_from(value: T) -> Self;
-}
-
-impl<T: Copy, U: CastInto<T> + Copy> CastFrom<U> for T {
-    fn cast_from(value: U) -> Self {
-        value.cast()
-    }
-}
-
-macro_rules! cast_into {
-    ($ty:ty) => {
-        cast_into!($ty; usize, isize, u8, i8, u16, i16, u32, i32, u64, i64, u128, i128);
-    };
-    ($ty:ty; $($into:ty),*) => {$(
-        impl CastInto<$into> for $ty {
-            fn cast(self) -> $into {
-                self as $into
-            }
-        }
-    )*};
-}
-
-cast_into!(usize);
-cast_into!(isize);
-cast_into!(u8);
-cast_into!(i8);
-cast_into!(u16);
-cast_into!(i16);
-cast_into!(u32);
-cast_into!(i32);
-cast_into!(u64);
-cast_into!(i64);
-cast_into!(u128);
-cast_into!(i128);
diff --git a/library/compiler-builtins/libm/src/math/support/int_traits.rs b/library/compiler-builtins/libm/src/math/support/int_traits.rs
index fa9e06066d7..716af748a9f 100644
--- a/library/compiler-builtins/libm/src/math/support/int_traits.rs
+++ b/library/compiler-builtins/libm/src/math/support/int_traits.rs
@@ -374,14 +374,19 @@ impl_h_int!(
 /// Trait to express (possibly lossy) casting of integers
 pub trait CastInto<T: Copy>: Copy {
     /// By default, casts should be exact.
+    #[track_caller]
     fn cast(self) -> T;
 
     /// Call for casts that are expected to truncate.
+    ///
+    /// In practice, this is exactly the same as `cast`; the main difference is to document intent
+    /// in code. `cast` may panic in debug mode.
     fn cast_lossy(self) -> T;
 }
 
 pub trait CastFrom<T: Copy>: Copy {
     /// By default, casts should be exact.
+    #[track_caller]
     fn cast_from(value: T) -> Self;
 
     /// Call for casts that are expected to truncate.