1 use super::*; 2 3 /// Marker trait for "plain old data". 4 /// 5 /// The point of this trait is that once something is marked "plain old data" 6 /// you can really go to town with the bit fiddling and bit casting. Therefore, 7 /// it's a relatively strong claim to make about a type. Do not add this to your 8 /// type casually. 9 /// 10 /// **Reminder:** The results of casting around bytes between data types are 11 /// _endian dependant_. Little-endian machines are the most common, but 12 /// big-endian machines do exist (and big-endian is also used for "network 13 /// order" bytes). 14 /// 15 /// ## Safety 16 /// 17 /// * The type must be inhabited (eg: no 18 /// [Infallible](core::convert::Infallible)). 19 /// * The type must allow any bit pattern (eg: no `bool` or `char`, which have 20 /// illegal bit patterns). 21 /// * The type must not contain any uninit (or padding) bytes, either in the 22 /// middle or on the end (eg: no `#[repr(C)] struct Foo(u8, u16)`, which has 23 /// padding in the middle, and also no `#[repr(C)] struct Foo(u16, u8)`, which 24 /// has padding on the end). 25 /// * The type needs to have all fields also be `Pod`. 26 /// * The type needs to be `repr(C)` or `repr(transparent)`. In the case of 27 /// `repr(C)`, the `packed` and `align` repr modifiers can be used as long as 28 /// all other rules end up being followed. 29 /// * It is disallowed for types to contain pointer types, `Cell`, `UnsafeCell`, 30 /// atomics, and any other forms of interior mutability. 31 /// * More precisely: A shared reference to the type must allow reads, and 32 /// *only* reads. RustBelt's separation logic is based on the notion that a 33 /// type is allowed to define a sharing predicate, its own invariant that must 34 /// hold for shared references, and this predicate is the reasoning that allow 35 /// it to deal with atomic and cells etc. We require the sharing predicate to 36 /// be trivial and permit only read-only access. 37 pub unsafe trait Pod: Zeroable + Copy + 'static {} 38 39 unsafe impl Pod for () {} 40 unsafe impl Pod for u8 {} 41 unsafe impl Pod for i8 {} 42 unsafe impl Pod for u16 {} 43 unsafe impl Pod for i16 {} 44 unsafe impl Pod for u32 {} 45 unsafe impl Pod for i32 {} 46 unsafe impl Pod for u64 {} 47 unsafe impl Pod for i64 {} 48 unsafe impl Pod for usize {} 49 unsafe impl Pod for isize {} 50 unsafe impl Pod for u128 {} 51 unsafe impl Pod for i128 {} 52 #[cfg(feature = "nightly_float")] 53 unsafe impl Pod for f16 {} 54 unsafe impl Pod for f32 {} 55 unsafe impl Pod for f64 {} 56 #[cfg(feature = "nightly_float")] 57 unsafe impl Pod for f128 {} 58 unsafe impl<T: Pod> Pod for Wrapping<T> {} 59 60 #[cfg(feature = "pod_saturating")] 61 unsafe impl<T: Pod> Pod for core::num::Saturating<T>{} 62 63 #[cfg(feature = "unsound_ptr_pod_impl")] 64 #[cfg_attr( 65 feature = "nightly_docs", 66 doc(cfg(feature = "unsound_ptr_pod_impl")) 67 )] 68 unsafe impl<T: 'static> Pod for *mut T {} 69 #[cfg(feature = "unsound_ptr_pod_impl")] 70 #[cfg_attr( 71 feature = "nightly_docs", 72 doc(cfg(feature = "unsound_ptr_pod_impl")) 73 )] 74 unsafe impl<T: 'static> Pod for *const T {} 75 #[cfg(feature = "unsound_ptr_pod_impl")] 76 #[cfg_attr( 77 feature = "nightly_docs", 78 doc(cfg(feature = "unsound_ptr_pod_impl")) 79 )] 80 unsafe impl<T: 'static> PodInOption for NonNull<T> {} 81 82 unsafe impl<T: ?Sized + 'static> Pod for PhantomData<T> {} 83 unsafe impl Pod for PhantomPinned {} 84 unsafe impl<T: Pod> Pod for core::mem::ManuallyDrop<T> {} 85 86 // Note(Lokathor): MaybeUninit can NEVER be Pod. 87 88 #[cfg(feature = "min_const_generics")] 89 #[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "min_const_generics")))] 90 unsafe impl<T, const N: usize> Pod for [T; N] where T: Pod {} 91 92 #[cfg(not(feature = "min_const_generics"))] 93 impl_unsafe_marker_for_array!( 94 Pod, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 95 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256, 96 512, 1024, 2048, 4096 97 ); 98 99 impl_unsafe_marker_for_simd!( 100 #[cfg(all(target_arch = "wasm32", feature = "wasm_simd"))] 101 unsafe impl Pod for wasm32::{v128} 102 ); 103 104 impl_unsafe_marker_for_simd!( 105 #[cfg(all(target_arch = "aarch64", feature = "aarch64_simd"))] 106 unsafe impl Pod for aarch64::{ 107 float32x2_t, float32x2x2_t, float32x2x3_t, float32x2x4_t, float32x4_t, 108 float32x4x2_t, float32x4x3_t, float32x4x4_t, float64x1_t, float64x1x2_t, 109 float64x1x3_t, float64x1x4_t, float64x2_t, float64x2x2_t, float64x2x3_t, 110 float64x2x4_t, int16x4_t, int16x4x2_t, int16x4x3_t, int16x4x4_t, int16x8_t, 111 int16x8x2_t, int16x8x3_t, int16x8x4_t, int32x2_t, int32x2x2_t, int32x2x3_t, 112 int32x2x4_t, int32x4_t, int32x4x2_t, int32x4x3_t, int32x4x4_t, int64x1_t, 113 int64x1x2_t, int64x1x3_t, int64x1x4_t, int64x2_t, int64x2x2_t, int64x2x3_t, 114 int64x2x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int8x8_t, 115 int8x8x2_t, int8x8x3_t, int8x8x4_t, poly16x4_t, poly16x4x2_t, poly16x4x3_t, 116 poly16x4x4_t, poly16x8_t, poly16x8x2_t, poly16x8x3_t, poly16x8x4_t, 117 poly64x1_t, poly64x1x2_t, poly64x1x3_t, poly64x1x4_t, poly64x2_t, 118 poly64x2x2_t, poly64x2x3_t, poly64x2x4_t, poly8x16_t, poly8x16x2_t, 119 poly8x16x3_t, poly8x16x4_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t, poly8x8x4_t, 120 uint16x4_t, uint16x4x2_t, uint16x4x3_t, uint16x4x4_t, uint16x8_t, 121 uint16x8x2_t, uint16x8x3_t, uint16x8x4_t, uint32x2_t, uint32x2x2_t, 122 uint32x2x3_t, uint32x2x4_t, uint32x4_t, uint32x4x2_t, uint32x4x3_t, 123 uint32x4x4_t, uint64x1_t, uint64x1x2_t, uint64x1x3_t, uint64x1x4_t, 124 uint64x2_t, uint64x2x2_t, uint64x2x3_t, uint64x2x4_t, uint8x16_t, 125 uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint8x8_t, uint8x8x2_t, 126 uint8x8x3_t, uint8x8x4_t, 127 } 128 ); 129 130 impl_unsafe_marker_for_simd!( 131 #[cfg(target_arch = "x86")] 132 unsafe impl Pod for x86::{ 133 __m128i, __m128, __m128d, 134 __m256i, __m256, __m256d, 135 } 136 ); 137 138 impl_unsafe_marker_for_simd!( 139 #[cfg(target_arch = "x86_64")] 140 unsafe impl Pod for x86_64::{ 141 __m128i, __m128, __m128d, 142 __m256i, __m256, __m256d, 143 } 144 ); 145 146 #[cfg(feature = "nightly_portable_simd")] 147 #[cfg_attr( 148 feature = "nightly_docs", 149 doc(cfg(feature = "nightly_portable_simd")) 150 )] 151 unsafe impl<T, const N: usize> Pod for core::simd::Simd<T, N> 152 where 153 T: core::simd::SimdElement + Pod, 154 core::simd::LaneCount<N>: core::simd::SupportedLaneCount, 155 { 156 } 157 158 impl_unsafe_marker_for_simd!( 159 #[cfg(all(target_arch = "x86", any(feature = "nightly_stdsimd", feature = "avx512_simd")))] 160 unsafe impl Pod for x86::{ 161 __m512, __m512d, __m512i 162 } 163 ); 164 165 impl_unsafe_marker_for_simd!( 166 #[cfg(all(target_arch = "x86_64", any(feature = "nightly_stdsimd", feature = "avx512_simd")))] 167 unsafe impl Pod for x86_64::{ 168 __m512, __m512d, __m512i 169 } 170 ); 171 172 impl_unsafe_marker_for_simd!( 173 #[cfg(all(target_arch = "x86", feature = "nightly_stdsimd"))] 174 unsafe impl Pod for x86::{ 175 __m128bh, __m256bh, __m512bh 176 } 177 ); 178 179 impl_unsafe_marker_for_simd!( 180 #[cfg(all(target_arch = "x86_64", feature = "nightly_stdsimd"))] 181 unsafe impl Pod for x86_64::{ 182 __m128bh, __m256bh, __m512bh 183 } 184 ); 185