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