| 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 ]
|
| 32 | 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 | #[cfg (feature = "nightly_float" )]
|
| 52 | unsafe impl Zeroable for f16 {}
|
| 53 | unsafe impl Zeroable for f32 {}
|
| 54 | unsafe impl Zeroable for f64 {}
|
| 55 | #[cfg (feature = "nightly_float" )]
|
| 56 | unsafe impl Zeroable for f128 {}
|
| 57 | unsafe impl<T: Zeroable> Zeroable for Wrapping<T> {}
|
| 58 | unsafe impl<T: Zeroable> Zeroable for core::cmp::Reverse<T> {}
|
| 59 | #[cfg (feature = "pod_saturating" )]
|
| 60 | unsafe impl<T: Zeroable> Zeroable for core::num::Saturating<T> {}
|
| 61 |
|
| 62 | // Note: we can't implement this for all `T: ?Sized` types because it would
|
| 63 | // create NULL pointers for vtables.
|
| 64 | // Maybe one day this could be changed to be implemented for
|
| 65 | // `T: ?Sized where <T as core::ptr::Pointee>::Metadata: Zeroable`.
|
| 66 | unsafe impl<T> Zeroable for *mut T {}
|
| 67 | unsafe impl<T> Zeroable for *const T {}
|
| 68 | unsafe impl<T> Zeroable for *mut [T] {}
|
| 69 | unsafe impl<T> Zeroable for *const [T] {}
|
| 70 | unsafe impl Zeroable for *mut str {}
|
| 71 | unsafe impl Zeroable for *const str {}
|
| 72 |
|
| 73 | unsafe impl<T: ?Sized> Zeroable for PhantomData<T> {}
|
| 74 | unsafe impl Zeroable for PhantomPinned {}
|
| 75 | unsafe impl<T: Zeroable> Zeroable for core::mem::ManuallyDrop<T> {}
|
| 76 | unsafe impl<T: Zeroable> Zeroable for core::cell::UnsafeCell<T> {}
|
| 77 | unsafe impl<T: Zeroable> Zeroable for core::cell::Cell<T> {}
|
| 78 |
|
| 79 | #[cfg (feature = "zeroable_atomics" )]
|
| 80 | #[cfg_attr (feature = "nightly_docs" , doc(cfg(feature = "zeroable_atomics" )))]
|
| 81 | mod atomic_impls {
|
| 82 | use super::Zeroable;
|
| 83 |
|
| 84 | #[cfg (target_has_atomic = "8" )]
|
| 85 | unsafe impl Zeroable for core::sync::atomic::AtomicBool {}
|
| 86 | #[cfg (target_has_atomic = "8" )]
|
| 87 | unsafe impl Zeroable for core::sync::atomic::AtomicU8 {}
|
| 88 | #[cfg (target_has_atomic = "8" )]
|
| 89 | unsafe impl Zeroable for core::sync::atomic::AtomicI8 {}
|
| 90 |
|
| 91 | #[cfg (target_has_atomic = "16" )]
|
| 92 | unsafe impl Zeroable for core::sync::atomic::AtomicU16 {}
|
| 93 | #[cfg (target_has_atomic = "16" )]
|
| 94 | unsafe impl Zeroable for core::sync::atomic::AtomicI16 {}
|
| 95 |
|
| 96 | #[cfg (target_has_atomic = "32" )]
|
| 97 | unsafe impl Zeroable for core::sync::atomic::AtomicU32 {}
|
| 98 | #[cfg (target_has_atomic = "32" )]
|
| 99 | unsafe impl Zeroable for core::sync::atomic::AtomicI32 {}
|
| 100 |
|
| 101 | #[cfg (target_has_atomic = "64" )]
|
| 102 | unsafe impl Zeroable for core::sync::atomic::AtomicU64 {}
|
| 103 | #[cfg (target_has_atomic = "64" )]
|
| 104 | unsafe impl Zeroable for core::sync::atomic::AtomicI64 {}
|
| 105 |
|
| 106 | #[cfg (target_has_atomic = "ptr" )]
|
| 107 | unsafe impl Zeroable for core::sync::atomic::AtomicUsize {}
|
| 108 | #[cfg (target_has_atomic = "ptr" )]
|
| 109 | unsafe impl Zeroable for core::sync::atomic::AtomicIsize {}
|
| 110 |
|
| 111 | #[cfg (target_has_atomic = "ptr" )]
|
| 112 | unsafe impl<T> Zeroable for core::sync::atomic::AtomicPtr<T> {}
|
| 113 | }
|
| 114 |
|
| 115 | #[cfg (feature = "zeroable_maybe_uninit" )]
|
| 116 | #[cfg_attr (
|
| 117 | feature = "nightly_docs" ,
|
| 118 | doc(cfg(feature = "zeroable_maybe_uninit" ))
|
| 119 | )]
|
| 120 | unsafe impl<T> Zeroable for core::mem::MaybeUninit<T> {}
|
| 121 |
|
| 122 | unsafe impl<A: Zeroable> Zeroable for (A,) {}
|
| 123 | unsafe impl<A: Zeroable, B: Zeroable> Zeroable for (A, B) {}
|
| 124 | unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable> Zeroable for (A, B, C) {}
|
| 125 | unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable> Zeroable
|
| 126 | for (A, B, C, D)
|
| 127 | {
|
| 128 | }
|
| 129 | unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable, E: Zeroable>
|
| 130 | Zeroable for (A, B, C, D, E)
|
| 131 | {
|
| 132 | }
|
| 133 | unsafe impl<
|
| 134 | A: Zeroable,
|
| 135 | B: Zeroable,
|
| 136 | C: Zeroable,
|
| 137 | D: Zeroable,
|
| 138 | E: Zeroable,
|
| 139 | F: Zeroable,
|
| 140 | > Zeroable for (A, B, C, D, E, F)
|
| 141 | {
|
| 142 | }
|
| 143 | unsafe impl<
|
| 144 | A: Zeroable,
|
| 145 | B: Zeroable,
|
| 146 | C: Zeroable,
|
| 147 | D: Zeroable,
|
| 148 | E: Zeroable,
|
| 149 | F: Zeroable,
|
| 150 | G: Zeroable,
|
| 151 | > Zeroable for (A, B, C, D, E, F, G)
|
| 152 | {
|
| 153 | }
|
| 154 | unsafe impl<
|
| 155 | A: Zeroable,
|
| 156 | B: Zeroable,
|
| 157 | C: Zeroable,
|
| 158 | D: Zeroable,
|
| 159 | E: Zeroable,
|
| 160 | F: Zeroable,
|
| 161 | G: Zeroable,
|
| 162 | H: Zeroable,
|
| 163 | > Zeroable for (A, B, C, D, E, F, G, H)
|
| 164 | {
|
| 165 | }
|
| 166 |
|
| 167 | #[cfg (feature = "min_const_generics" )]
|
| 168 | #[cfg_attr (feature = "nightly_docs" , doc(cfg(feature = "min_const_generics" )))]
|
| 169 | unsafe impl<T, const N: usize> Zeroable for [T; N] where T: Zeroable {}
|
| 170 |
|
| 171 | #[cfg (not(feature = "min_const_generics" ))]
|
| 172 | impl_unsafe_marker_for_array!(
|
| 173 | Zeroable, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
| 174 | 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256,
|
| 175 | 512, 1024, 2048, 4096
|
| 176 | );
|
| 177 |
|
| 178 | impl_unsafe_marker_for_simd!(
|
| 179 | #[cfg(all(target_arch = "wasm32" , feature = "wasm_simd" ))]
|
| 180 | unsafe impl Zeroable for wasm32::{v128}
|
| 181 | );
|
| 182 |
|
| 183 | impl_unsafe_marker_for_simd!(
|
| 184 | #[cfg(all(target_arch = "aarch64" , feature = "aarch64_simd" ))]
|
| 185 | unsafe impl Zeroable for aarch64::{
|
| 186 | float32x2_t, float32x2x2_t, float32x2x3_t, float32x2x4_t, float32x4_t,
|
| 187 | float32x4x2_t, float32x4x3_t, float32x4x4_t, float64x1_t, float64x1x2_t,
|
| 188 | float64x1x3_t, float64x1x4_t, float64x2_t, float64x2x2_t, float64x2x3_t,
|
| 189 | float64x2x4_t, int16x4_t, int16x4x2_t, int16x4x3_t, int16x4x4_t, int16x8_t,
|
| 190 | int16x8x2_t, int16x8x3_t, int16x8x4_t, int32x2_t, int32x2x2_t, int32x2x3_t,
|
| 191 | int32x2x4_t, int32x4_t, int32x4x2_t, int32x4x3_t, int32x4x4_t, int64x1_t,
|
| 192 | int64x1x2_t, int64x1x3_t, int64x1x4_t, int64x2_t, int64x2x2_t, int64x2x3_t,
|
| 193 | int64x2x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int8x8_t,
|
| 194 | int8x8x2_t, int8x8x3_t, int8x8x4_t, poly16x4_t, poly16x4x2_t, poly16x4x3_t,
|
| 195 | poly16x4x4_t, poly16x8_t, poly16x8x2_t, poly16x8x3_t, poly16x8x4_t,
|
| 196 | poly64x1_t, poly64x1x2_t, poly64x1x3_t, poly64x1x4_t, poly64x2_t,
|
| 197 | poly64x2x2_t, poly64x2x3_t, poly64x2x4_t, poly8x16_t, poly8x16x2_t,
|
| 198 | poly8x16x3_t, poly8x16x4_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t, poly8x8x4_t,
|
| 199 | uint16x4_t, uint16x4x2_t, uint16x4x3_t, uint16x4x4_t, uint16x8_t,
|
| 200 | uint16x8x2_t, uint16x8x3_t, uint16x8x4_t, uint32x2_t, uint32x2x2_t,
|
| 201 | uint32x2x3_t, uint32x2x4_t, uint32x4_t, uint32x4x2_t, uint32x4x3_t,
|
| 202 | uint32x4x4_t, uint64x1_t, uint64x1x2_t, uint64x1x3_t, uint64x1x4_t,
|
| 203 | uint64x2_t, uint64x2x2_t, uint64x2x3_t, uint64x2x4_t, uint8x16_t,
|
| 204 | uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint8x8_t, uint8x8x2_t,
|
| 205 | uint8x8x3_t, uint8x8x4_t,
|
| 206 | }
|
| 207 | );
|
| 208 |
|
| 209 | impl_unsafe_marker_for_simd!(
|
| 210 | #[cfg(target_arch = "x86" )]
|
| 211 | unsafe impl Zeroable for x86::{
|
| 212 | __m128i, __m128, __m128d,
|
| 213 | __m256i, __m256, __m256d,
|
| 214 | }
|
| 215 | );
|
| 216 |
|
| 217 | impl_unsafe_marker_for_simd!(
|
| 218 | #[cfg(target_arch = "x86_64" )]
|
| 219 | unsafe impl Zeroable for x86_64::{
|
| 220 | __m128i, __m128, __m128d,
|
| 221 | __m256i, __m256, __m256d,
|
| 222 | }
|
| 223 | );
|
| 224 |
|
| 225 | #[cfg (feature = "nightly_portable_simd" )]
|
| 226 | #[cfg_attr (
|
| 227 | feature = "nightly_docs" ,
|
| 228 | doc(cfg(feature = "nightly_portable_simd" ))
|
| 229 | )]
|
| 230 | unsafe impl<T, const N: usize> Zeroable for core::simd::Simd<T, N>
|
| 231 | where
|
| 232 | T: core::simd::SimdElement + Zeroable,
|
| 233 | core::simd::LaneCount<N>: core::simd::SupportedLaneCount,
|
| 234 | {
|
| 235 | }
|
| 236 |
|
| 237 | impl_unsafe_marker_for_simd!(
|
| 238 | #[cfg(all(target_arch = "x86" , any(feature = "nightly_stdsimd" , feature = "avx512_simd" )))]
|
| 239 | unsafe impl Zeroable for x86::{
|
| 240 | __m512, __m512d, __m512i
|
| 241 | }
|
| 242 | );
|
| 243 |
|
| 244 | impl_unsafe_marker_for_simd!(
|
| 245 | #[cfg(all(target_arch = "x86_64" , any(feature = "nightly_stdsimd" , feature = "avx512_simd" )))]
|
| 246 | unsafe impl Zeroable for x86_64::{
|
| 247 | __m512, __m512d, __m512i
|
| 248 | }
|
| 249 | );
|
| 250 |
|
| 251 | impl_unsafe_marker_for_simd!(
|
| 252 | #[cfg(all(target_arch = "x86" , feature = "nightly_stdsimd" ))]
|
| 253 | unsafe impl Zeroable for x86::{
|
| 254 | __m128bh, __m256bh, __m512bh
|
| 255 | }
|
| 256 | );
|
| 257 |
|
| 258 | impl_unsafe_marker_for_simd!(
|
| 259 | #[cfg(all(target_arch = "x86_64" , feature = "nightly_stdsimd" ))]
|
| 260 | unsafe impl Zeroable for x86_64::{
|
| 261 | __m128bh, __m256bh, __m512bh
|
| 262 | }
|
| 263 | );
|
| 264 | |