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 = "unsound_ptr_pod_impl")] 61 #[cfg_attr( 62 feature = "nightly_docs", 63 doc(cfg(feature = "unsound_ptr_pod_impl")) 64 )] 65 unsafe impl<T: 'static> Pod for *mut T {} 66 #[cfg(feature = "unsound_ptr_pod_impl")] 67 #[cfg_attr( 68 feature = "nightly_docs", 69 doc(cfg(feature = "unsound_ptr_pod_impl")) 70 )] 71 unsafe impl<T: 'static> Pod for *const T {} 72 #[cfg(feature = "unsound_ptr_pod_impl")] 73 #[cfg_attr( 74 feature = "nightly_docs", 75 doc(cfg(feature = "unsound_ptr_pod_impl")) 76 )] 77 unsafe impl<T: 'static> PodInOption for NonNull<T> {} 78 79 unsafe impl<T: ?Sized + 'static> Pod for PhantomData<T> {} 80 unsafe impl Pod for PhantomPinned {} 81 unsafe impl<T: Pod> Pod for core::mem::ManuallyDrop<T> {} 82 83 // Note(Lokathor): MaybeUninit can NEVER be Pod. 84 85 #[cfg(feature = "min_const_generics")] 86 #[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "min_const_generics")))] 87 unsafe impl<T, const N: usize> Pod for [T; N] where T: Pod {} 88 89 #[cfg(not(feature = "min_const_generics"))] 90 impl_unsafe_marker_for_array!( 91 Pod, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 92 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256, 93 512, 1024, 2048, 4096 94 ); 95 96 impl_unsafe_marker_for_simd!( 97 #[cfg(all(target_arch = "wasm32", feature = "wasm_simd"))] 98 unsafe impl Pod for wasm32::{v128} 99 ); 100 101 impl_unsafe_marker_for_simd!( 102 #[cfg(all(target_arch = "aarch64", feature = "aarch64_simd"))] 103 unsafe impl Pod for aarch64::{ 104 float32x2_t, float32x2x2_t, float32x2x3_t, float32x2x4_t, float32x4_t, 105 float32x4x2_t, float32x4x3_t, float32x4x4_t, float64x1_t, float64x1x2_t, 106 float64x1x3_t, float64x1x4_t, float64x2_t, float64x2x2_t, float64x2x3_t, 107 float64x2x4_t, int16x4_t, int16x4x2_t, int16x4x3_t, int16x4x4_t, int16x8_t, 108 int16x8x2_t, int16x8x3_t, int16x8x4_t, int32x2_t, int32x2x2_t, int32x2x3_t, 109 int32x2x4_t, int32x4_t, int32x4x2_t, int32x4x3_t, int32x4x4_t, int64x1_t, 110 int64x1x2_t, int64x1x3_t, int64x1x4_t, int64x2_t, int64x2x2_t, int64x2x3_t, 111 int64x2x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int8x8_t, 112 int8x8x2_t, int8x8x3_t, int8x8x4_t, poly16x4_t, poly16x4x2_t, poly16x4x3_t, 113 poly16x4x4_t, poly16x8_t, poly16x8x2_t, poly16x8x3_t, poly16x8x4_t, 114 poly64x1_t, poly64x1x2_t, poly64x1x3_t, poly64x1x4_t, poly64x2_t, 115 poly64x2x2_t, poly64x2x3_t, poly64x2x4_t, poly8x16_t, poly8x16x2_t, 116 poly8x16x3_t, poly8x16x4_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t, poly8x8x4_t, 117 uint16x4_t, uint16x4x2_t, uint16x4x3_t, uint16x4x4_t, uint16x8_t, 118 uint16x8x2_t, uint16x8x3_t, uint16x8x4_t, uint32x2_t, uint32x2x2_t, 119 uint32x2x3_t, uint32x2x4_t, uint32x4_t, uint32x4x2_t, uint32x4x3_t, 120 uint32x4x4_t, uint64x1_t, uint64x1x2_t, uint64x1x3_t, uint64x1x4_t, 121 uint64x2_t, uint64x2x2_t, uint64x2x3_t, uint64x2x4_t, uint8x16_t, 122 uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint8x8_t, uint8x8x2_t, 123 uint8x8x3_t, uint8x8x4_t, 124 } 125 ); 126 127 impl_unsafe_marker_for_simd!( 128 #[cfg(target_arch = "x86")] 129 unsafe impl Pod for x86::{ 130 __m128i, __m128, __m128d, 131 __m256i, __m256, __m256d, 132 } 133 ); 134 135 impl_unsafe_marker_for_simd!( 136 #[cfg(target_arch = "x86_64")] 137 unsafe impl Pod for x86_64::{ 138 __m128i, __m128, __m128d, 139 __m256i, __m256, __m256d, 140 } 141 ); 142 143 #[cfg(feature = "nightly_portable_simd")] 144 #[cfg_attr( 145 feature = "nightly_docs", 146 doc(cfg(feature = "nightly_portable_simd")) 147 )] 148 unsafe impl<T, const N: usize> Pod for core::simd::Simd<T, N> 149 where 150 T: core::simd::SimdElement + Pod, 151 core::simd::LaneCount<N>: core::simd::SupportedLaneCount, 152 { 153 } 154 155 impl_unsafe_marker_for_simd!( 156 #[cfg(all(target_arch = "x86", feature = "nightly_stdsimd"))] 157 unsafe impl Pod for x86::{ 158 __m128bh, __m256bh, __m512, 159 __m512bh, __m512d, __m512i, 160 } 161 ); 162 163 impl_unsafe_marker_for_simd!( 164 #[cfg(all(target_arch = "x86_64", feature = "nightly_stdsimd"))] 165 unsafe impl Pod for x86_64::{ 166 __m128bh, __m256bh, __m512, 167 __m512bh, __m512d, __m512i, 168 } 169 ); 170