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