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: Sized + Copy {
48    type UInt: const core::ops::BitOr<Output = Self::UInt>
49        + const core::ops::BitAnd<Output = Self::UInt>
50        + const core::ops::Not<Output = Self::UInt>;
51    const SIGN_MASK: Self::UInt;
52    fn to_bits(self) -> Self::UInt;
53    fn from_bits(bits: Self::UInt) -> Self;
54}
55
56unsafe impl FloatPrimitive for f16 {
57    type UInt = u16;
58    const SIGN_MASK: Self::UInt = f16::SIGN_MASK;
59    #[inline]
60    fn to_bits(self) -> Self::UInt {
61        f16::to_bits(self)
62    }
63    #[inline]
64    fn from_bits(bits: Self::UInt) -> Self {
65        f16::from_bits(bits)
66    }
67}
68
69unsafe impl FloatPrimitive for f32 {
70    type UInt = u32;
71    const SIGN_MASK: Self::UInt = f32::SIGN_MASK;
72    #[inline]
73    fn to_bits(self) -> Self::UInt {
74        f32::to_bits(self)
75    }
76    #[inline]
77    fn from_bits(bits: Self::UInt) -> Self {
78        f32::from_bits(bits)
79    }
80}
81
82unsafe impl FloatPrimitive for f64 {
83    type UInt = u64;
84    const SIGN_MASK: Self::UInt = f64::SIGN_MASK;
85    #[inline]
86    fn to_bits(self) -> Self::UInt {
87        f64::to_bits(self)
88    }
89    #[inline]
90    fn from_bits(bits: Self::UInt) -> Self {
91        f64::from_bits(bits)
92    }
93}
94
95unsafe impl FloatPrimitive for f128 {
96    type UInt = u128;
97    const SIGN_MASK: Self::UInt = f128::SIGN_MASK;
98    #[inline]
99    fn to_bits(self) -> Self::UInt {
100        f128::to_bits(self)
101    }
102    #[inline]
103    fn from_bits(bits: Self::UInt) -> Self {
104        f128::from_bits(bits)
105    }
106}
107
108/// Built-in integer types (i8, i16, .., i128, isize, u8, u16, .., u128, usize).
109///
110/// Intentionally does not include other integer-repr types like `bool` or `char`.
111///
112/// # Safety
113/// Must actually *be* such a type.
114#[rustc_const_unstable(feature = "core_intrinsics", issue = "none")]
115pub const unsafe trait IntegerPrimitive: Copy + [const] Ord {}
116
117macro_rules! impl_integer_primitive {
118    ($($t:ty),*) => {$(
119        #[rustc_const_unstable(feature = "core_intrinsics", issue = "none")]
120        const unsafe impl IntegerPrimitive for $t {}
121    )*};
122}
123impl_integer_primitive!(i8, i16, i32, i64, i128, isize);
124impl_integer_primitive!(u8, u16, u32, u64, u128, usize);