1 use super::*; 2 3 /// Trait for types that can be safely created with 4 /// [`zeroed`](core::mem::zeroed). 5 /// 6 /// An all-zeroes value may or may not be the same value as the 7 /// [Default](core::default::Default) value of the type. 8 /// 9 /// ## Safety 10 /// 11 /// * Your type must be inhabited (eg: no 12 /// [Infallible](core::convert::Infallible)). 13 /// * Your type must be allowed to be an "all zeroes" bit pattern (eg: no 14 /// [`NonNull<T>`](core::ptr::NonNull)). 15 /// 16 /// ## Features 17 /// 18 /// Some `impl`s are feature gated due to the MSRV policy: 19 /// 20 /// * `MaybeUninit<T>` was not available in 1.34.0, but is available under the 21 /// `zeroable_maybe_uninit` feature flag. 22 /// * `Atomic*` types require Rust 1.60.0 or later to work on certain platforms, 23 /// but is available under the `zeroable_atomics` feature flag. 24 /// * `[T; N]` for arbitrary `N` requires the `min_const_generics` feature flag. 25 pub unsafe trait Zeroable: Sized { 26 /// Calls [`zeroed`](core::mem::zeroed). 27 /// 28 /// This is a trait method so that you can write `MyType::zeroed()` in your 29 /// code. It is a contract of this trait that if you implement it on your type 30 /// you **must not** override this method. 31 #[inline] zeroed() -> Self32 fn zeroed() -> Self { 33 unsafe { core::mem::zeroed() } 34 } 35 } 36 unsafe impl Zeroable for () {} 37 unsafe impl Zeroable for bool {} 38 unsafe impl Zeroable for char {} 39 unsafe impl Zeroable for u8 {} 40 unsafe impl Zeroable for i8 {} 41 unsafe impl Zeroable for u16 {} 42 unsafe impl Zeroable for i16 {} 43 unsafe impl Zeroable for u32 {} 44 unsafe impl Zeroable for i32 {} 45 unsafe impl Zeroable for u64 {} 46 unsafe impl Zeroable for i64 {} 47 unsafe impl Zeroable for usize {} 48 unsafe impl Zeroable for isize {} 49 unsafe impl Zeroable for u128 {} 50 unsafe impl Zeroable for i128 {} 51 unsafe impl Zeroable for f32 {} 52 unsafe impl Zeroable for f64 {} 53 unsafe impl<T: Zeroable> Zeroable for Wrapping<T> {} 54 unsafe impl<T: Zeroable> Zeroable for core::cmp::Reverse<T> {} 55 56 // Note: we can't implement this for all `T: ?Sized` types because it would 57 // create NULL pointers for vtables. 58 // Maybe one day this could be changed to be implemented for 59 // `T: ?Sized where <T as core::ptr::Pointee>::Metadata: Zeroable`. 60 unsafe impl<T> Zeroable for *mut T {} 61 unsafe impl<T> Zeroable for *const T {} 62 unsafe impl<T> Zeroable for *mut [T] {} 63 unsafe impl<T> Zeroable for *const [T] {} 64 unsafe impl Zeroable for *mut str {} 65 unsafe impl Zeroable for *const str {} 66 67 unsafe impl<T: ?Sized> Zeroable for PhantomData<T> {} 68 unsafe impl Zeroable for PhantomPinned {} 69 unsafe impl<T: Zeroable> Zeroable for ManuallyDrop<T> {} 70 unsafe impl<T: Zeroable> Zeroable for core::cell::UnsafeCell<T> {} 71 unsafe impl<T: Zeroable> Zeroable for core::cell::Cell<T> {} 72 73 #[cfg(feature = "zeroable_atomics")] 74 #[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "zeroable_atomics")))] 75 mod atomic_impls { 76 use super::Zeroable; 77 78 #[cfg(target_has_atomic = "8")] 79 unsafe impl Zeroable for core::sync::atomic::AtomicBool {} 80 #[cfg(target_has_atomic = "8")] 81 unsafe impl Zeroable for core::sync::atomic::AtomicU8 {} 82 #[cfg(target_has_atomic = "8")] 83 unsafe impl Zeroable for core::sync::atomic::AtomicI8 {} 84 85 #[cfg(target_has_atomic = "16")] 86 unsafe impl Zeroable for core::sync::atomic::AtomicU16 {} 87 #[cfg(target_has_atomic = "16")] 88 unsafe impl Zeroable for core::sync::atomic::AtomicI16 {} 89 90 #[cfg(target_has_atomic = "32")] 91 unsafe impl Zeroable for core::sync::atomic::AtomicU32 {} 92 #[cfg(target_has_atomic = "32")] 93 unsafe impl Zeroable for core::sync::atomic::AtomicI32 {} 94 95 #[cfg(target_has_atomic = "64")] 96 unsafe impl Zeroable for core::sync::atomic::AtomicU64 {} 97 #[cfg(target_has_atomic = "64")] 98 unsafe impl Zeroable for core::sync::atomic::AtomicI64 {} 99 100 #[cfg(target_has_atomic = "ptr")] 101 unsafe impl Zeroable for core::sync::atomic::AtomicUsize {} 102 #[cfg(target_has_atomic = "ptr")] 103 unsafe impl Zeroable for core::sync::atomic::AtomicIsize {} 104 105 #[cfg(target_has_atomic = "ptr")] 106 unsafe impl<T> Zeroable for core::sync::atomic::AtomicPtr<T> {} 107 } 108 109 #[cfg(feature = "zeroable_maybe_uninit")] 110 #[cfg_attr( 111 feature = "nightly_docs", 112 doc(cfg(feature = "zeroable_maybe_uninit")) 113 )] 114 unsafe impl<T> Zeroable for core::mem::MaybeUninit<T> {} 115 116 unsafe impl<A: Zeroable> Zeroable for (A,) {} 117 unsafe impl<A: Zeroable, B: Zeroable> Zeroable for (A, B) {} 118 unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable> Zeroable for (A, B, C) {} 119 unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable> Zeroable 120 for (A, B, C, D) 121 { 122 } 123 unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable, E: Zeroable> 124 Zeroable for (A, B, C, D, E) 125 { 126 } 127 unsafe impl< 128 A: Zeroable, 129 B: Zeroable, 130 C: Zeroable, 131 D: Zeroable, 132 E: Zeroable, 133 F: Zeroable, 134 > Zeroable for (A, B, C, D, E, F) 135 { 136 } 137 unsafe impl< 138 A: Zeroable, 139 B: Zeroable, 140 C: Zeroable, 141 D: Zeroable, 142 E: Zeroable, 143 F: Zeroable, 144 G: Zeroable, 145 > Zeroable for (A, B, C, D, E, F, G) 146 { 147 } 148 unsafe impl< 149 A: Zeroable, 150 B: Zeroable, 151 C: Zeroable, 152 D: Zeroable, 153 E: Zeroable, 154 F: Zeroable, 155 G: Zeroable, 156 H: Zeroable, 157 > Zeroable for (A, B, C, D, E, F, G, H) 158 { 159 } 160 161 #[cfg(feature = "min_const_generics")] 162 #[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "min_const_generics")))] 163 unsafe impl<T, const N: usize> Zeroable for [T; N] where T: Zeroable {} 164 165 #[cfg(not(feature = "min_const_generics"))] 166 impl_unsafe_marker_for_array!( 167 Zeroable, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 168 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256, 169 512, 1024, 2048, 4096 170 ); 171 172 impl_unsafe_marker_for_simd!( 173 #[cfg(all(target_arch = "wasm32", feature = "wasm_simd"))] 174 unsafe impl Zeroable for wasm32::{v128} 175 ); 176 177 impl_unsafe_marker_for_simd!( 178 #[cfg(all(target_arch = "aarch64", feature = "aarch64_simd"))] 179 unsafe impl Zeroable for aarch64::{ 180 float32x2_t, float32x2x2_t, float32x2x3_t, float32x2x4_t, float32x4_t, 181 float32x4x2_t, float32x4x3_t, float32x4x4_t, float64x1_t, float64x1x2_t, 182 float64x1x3_t, float64x1x4_t, float64x2_t, float64x2x2_t, float64x2x3_t, 183 float64x2x4_t, int16x4_t, int16x4x2_t, int16x4x3_t, int16x4x4_t, int16x8_t, 184 int16x8x2_t, int16x8x3_t, int16x8x4_t, int32x2_t, int32x2x2_t, int32x2x3_t, 185 int32x2x4_t, int32x4_t, int32x4x2_t, int32x4x3_t, int32x4x4_t, int64x1_t, 186 int64x1x2_t, int64x1x3_t, int64x1x4_t, int64x2_t, int64x2x2_t, int64x2x3_t, 187 int64x2x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int8x8_t, 188 int8x8x2_t, int8x8x3_t, int8x8x4_t, poly16x4_t, poly16x4x2_t, poly16x4x3_t, 189 poly16x4x4_t, poly16x8_t, poly16x8x2_t, poly16x8x3_t, poly16x8x4_t, 190 poly64x1_t, poly64x1x2_t, poly64x1x3_t, poly64x1x4_t, poly64x2_t, 191 poly64x2x2_t, poly64x2x3_t, poly64x2x4_t, poly8x16_t, poly8x16x2_t, 192 poly8x16x3_t, poly8x16x4_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t, poly8x8x4_t, 193 uint16x4_t, uint16x4x2_t, uint16x4x3_t, uint16x4x4_t, uint16x8_t, 194 uint16x8x2_t, uint16x8x3_t, uint16x8x4_t, uint32x2_t, uint32x2x2_t, 195 uint32x2x3_t, uint32x2x4_t, uint32x4_t, uint32x4x2_t, uint32x4x3_t, 196 uint32x4x4_t, uint64x1_t, uint64x1x2_t, uint64x1x3_t, uint64x1x4_t, 197 uint64x2_t, uint64x2x2_t, uint64x2x3_t, uint64x2x4_t, uint8x16_t, 198 uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint8x8_t, uint8x8x2_t, 199 uint8x8x3_t, uint8x8x4_t, 200 } 201 ); 202 203 impl_unsafe_marker_for_simd!( 204 #[cfg(target_arch = "x86")] 205 unsafe impl Zeroable for x86::{ 206 __m128i, __m128, __m128d, 207 __m256i, __m256, __m256d, 208 } 209 ); 210 211 impl_unsafe_marker_for_simd!( 212 #[cfg(target_arch = "x86_64")] 213 unsafe impl Zeroable for x86_64::{ 214 __m128i, __m128, __m128d, 215 __m256i, __m256, __m256d, 216 } 217 ); 218 219 #[cfg(feature = "nightly_portable_simd")] 220 #[cfg_attr( 221 feature = "nightly_docs", 222 doc(cfg(feature = "nightly_portable_simd")) 223 )] 224 unsafe impl<T, const N: usize> Zeroable for core::simd::Simd<T, N> 225 where 226 T: core::simd::SimdElement + Zeroable, 227 core::simd::LaneCount<N>: core::simd::SupportedLaneCount, 228 { 229 } 230 231 impl_unsafe_marker_for_simd!( 232 #[cfg(all(target_arch = "x86", feature = "nightly_stdsimd"))] 233 unsafe impl Zeroable for x86::{ 234 __m128bh, __m256bh, __m512, 235 __m512bh, __m512d, __m512i, 236 } 237 ); 238 239 impl_unsafe_marker_for_simd!( 240 #[cfg(all(target_arch = "x86_64", feature = "nightly_stdsimd"))] 241 unsafe impl Zeroable for x86_64::{ 242 __m128bh, __m256bh, __m512, 243 __m512bh, __m512d, __m512i, 244 } 245 ); 246