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 | |