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