Skip to main content

core/intrinsics/
bounds.rs

1//! Various traits used to restrict intrinsics to not-completely-wrong types.
2
3use crate::marker::PointeeSized;
4
5/// Types with a built-in dereference operator in runtime MIR,
6/// aka references and raw pointers.
7///
8/// # Safety
9/// Must actually *be* such a type.
10pub unsafe trait BuiltinDeref: Sized {
11    type Pointee: PointeeSized;
12}
13
14unsafe impl<T: PointeeSized> BuiltinDeref for &mut T {
15    type Pointee = T;
16}
17unsafe impl<T: PointeeSized> BuiltinDeref for &T {
18    type Pointee = T;
19}
20unsafe impl<T: PointeeSized> BuiltinDeref for *mut T {
21    type Pointee = T;
22}
23unsafe impl<T: PointeeSized> BuiltinDeref for *const T {
24    type Pointee = T;
25}
26
27pub trait ChangePointee<U: PointeeSized>: BuiltinDeref {
28    type Output;
29}
30impl<'a, T: PointeeSized + 'a, U: PointeeSized + 'a> ChangePointee<U> for &'a mut T {
31    type Output = &'a mut U;
32}
33impl<'a, T: PointeeSized + 'a, U: PointeeSized + 'a> ChangePointee<U> for &'a T {
34    type Output = &'a U;
35}
36impl<T: PointeeSized, U: PointeeSized> ChangePointee<U> for *mut T {
37    type Output = *mut U;
38}
39impl<T: PointeeSized, U: PointeeSized> ChangePointee<U> for *const T {
40    type Output = *const U;
41}
42
43/// Built-in float types (f16, f32, f64 and f128).
44///
45/// # Safety
46/// Must actually *be* such a type.
47pub unsafe trait FloatPrimitive:
48    Sized + Copy + core::ops::Mul<Output = Self> + core::ops::Add<Output = Self>
49{
50    type UInt: const core::ops::BitOr<Output = Self::UInt>
51        + const core::ops::BitAnd<Output = Self::UInt>
52        + const core::ops::Not<Output = Self::UInt>;
53    const SIGN_MASK: Self::UInt;
54    fn to_bits(self) -> Self::UInt;
55    fn from_bits(bits: Self::UInt) -> Self;
56}
57
58unsafe impl FloatPrimitive for f16 {
59    type UInt = u16;
60    const SIGN_MASK: Self::UInt = f16::SIGN_MASK;
61    #[inline]
62    fn to_bits(self) -> Self::UInt {
63        f16::to_bits(self)
64    }
65    #[inline]
66    fn from_bits(bits: Self::UInt) -> Self {
67        f16::from_bits(bits)
68    }
69}
70
71unsafe impl FloatPrimitive for f32 {
72    type UInt = u32;
73    const SIGN_MASK: Self::UInt = f32::SIGN_MASK;
74    #[inline]
75    fn to_bits(self) -> Self::UInt {
76        f32::to_bits(self)
77    }
78    #[inline]
79    fn from_bits(bits: Self::UInt) -> Self {
80        f32::from_bits(bits)
81    }
82}
83
84unsafe impl FloatPrimitive for f64 {
85    type UInt = u64;
86    const SIGN_MASK: Self::UInt = f64::SIGN_MASK;
87    #[inline]
88    fn to_bits(self) -> Self::UInt {
89        f64::to_bits(self)
90    }
91    #[inline]
92    fn from_bits(bits: Self::UInt) -> Self {
93        f64::from_bits(bits)
94    }
95}
96
97unsafe impl FloatPrimitive for f128 {
98    type UInt = u128;
99    const SIGN_MASK: Self::UInt = f128::SIGN_MASK;
100    #[inline]
101    fn to_bits(self) -> Self::UInt {
102        f128::to_bits(self)
103    }
104    #[inline]
105    fn from_bits(bits: Self::UInt) -> Self {
106        f128::from_bits(bits)
107    }
108}
109
110/// Built-in integer types (i8, i16, .., i128, isize, u8, u16, .., u128, usize).
111///
112/// Intentionally does not include other integer-repr types like `bool` or `char`.
113///
114/// # Safety
115/// Must actually *be* such a type.
116#[rustc_const_unstable(feature = "core_intrinsics", issue = "none")]
117pub const unsafe trait IntegerPrimitive: Copy + [const] Ord {}
118
119macro_rules! impl_integer_primitive {
120    ($($t:ty),*) => {$(
121        #[rustc_const_unstable(feature = "core_intrinsics", issue = "none")]
122        const unsafe impl IntegerPrimitive for $t {}
123    )*};
124}
125impl_integer_primitive!(i8, i16, i32, i64, i128, isize);
126impl_integer_primitive!(u8, u16, u32, u64, u128, usize);