1use core::{cmp::Ordering, ops::Add};
4
5use crate::{
6 RustSpec, Stable, Unstable, Zero,
7 layout::{NonRobust, Robust},
8 mutability::Exclusive,
9 niche::{WithNiche, WithoutNiche},
10 size::{self, MetaSized, SliceLike},
11};
12
13macro_rules! primitive_derive {
14 ( $primitive:ty => $alignment:ty ) => {
15 unsafe impl RustSpec for $primitive {
16 type Layout = Stable;
17 type Size = size::Sized<crate::Gt<Zero>>;
18 type Alignment = $alignment;
19 type Trap = Robust;
20 type Niche = WithoutNiche;
21 type Mutability = Exclusive;
22 type __IndirectTrap = Robust;
23 }
24 };
25}
26
27macro_rules! raw_pointer_derive {
28 ( $mutability:tt ) => {
29 unsafe impl<R: ?Sized> RustSpec for *$mutability R {
30 type Layout = Stable;
31 type Size = size::Sized<crate::Gt<Zero>>;
32 type Alignment = <usize as RustSpec>::Alignment;
33 type Trap = Robust;
34 type Niche = WithoutNiche;
35 type Mutability = Exclusive;
36 type __IndirectTrap = Robust;
37
38 }
39 };
40}
41
42macro_rules! impl_nonempty_array {
43 ($($n:literal),* $(,)?) => { $(
44 unsafe impl<R: RustSpec> RustSpec for [R; $n]
45 where
46 WithoutNiche: Add<R::Niche>,
47 {
48 type Layout = R::Layout;
49 type Size = R::Size;
50 type Alignment = R::Alignment;
51 type Trap = R::Trap;
52 type Niche = <WithoutNiche as Add<R::Niche>>::Output;
53 type Mutability = R::Mutability;
54 type __IndirectTrap = R::__IndirectTrap;
55 })*
56 };
57}
58
59macro_rules! impl_fn_types {
60 ( $( ( $( $arg:ident ),* ) ),* $(,)? ) => {
61 };
94}
95
96macro_rules! fieldless_enum_derive {
97 ( $src:ty => $alignment:ty ) => {
98 unsafe impl RustSpec for $src {
99 type Layout = Stable;
100 type Size = size::Sized<crate::Gt<Zero>>;
101 type Alignment = $alignment;
102 type Trap = NonRobust;
103 type Niche = WithNiche<Unstable>;
104 type Mutability = Exclusive;
105 type __IndirectTrap = Robust;
106 }
107 };
108}
109
110primitive_derive! { u8 => crate::One }
111primitive_derive! { i8 => crate::One }
112primitive_derive! { u16 => crate::Gt<crate::One> }
113primitive_derive! { i16 => crate::Gt<crate::One> }
114primitive_derive! { u32 => crate::Gt<crate::One> }
115primitive_derive! { i32 => crate::Gt<crate::One> }
116primitive_derive! { u64 => crate::Gt<crate::One> }
117primitive_derive! { i64 => crate::Gt<crate::One> }
118primitive_derive! { u128 => crate::Gt<crate::One> }
119primitive_derive! { i128 => crate::Gt<crate::One> }
120primitive_derive! { f32 => crate::Gt<crate::One> }
121primitive_derive! { f64 => crate::Gt<crate::One> }
122
123#[cfg(target_pointer_width = "16")]
124primitive_derive! { usize => crate::Gt<crate::One> }
125#[cfg(target_pointer_width = "32")]
126primitive_derive! { usize => crate::Gt<crate::One> }
127#[cfg(target_pointer_width = "64")]
128primitive_derive! { usize => crate::Gt<crate::One> }
129
130primitive_derive! { isize => <usize as RustSpec>::Alignment }
131
132raw_pointer_derive! { const }
133raw_pointer_derive! { mut }
134
135unsafe impl<R: RustSpec> RustSpec for [R] {
136 type Layout = R::Layout;
137 type Size = MetaSized<SliceLike>;
138 type Alignment = R::Alignment;
139 type Trap = R::Trap;
140 type Niche = WithoutNiche;
143 type Mutability = Exclusive;
144 type __IndirectTrap = R::__IndirectTrap;
145}
146
147unsafe impl<R: RustSpec> RustSpec for [R; 0] {
148 type Layout = R::Layout;
149 type Size = size::Sized<Zero>;
150 type Alignment = R::Alignment;
151 type Trap = Robust;
152 type Niche = WithoutNiche;
153 type Mutability = Exclusive;
154 type __IndirectTrap = Robust;
155}
156
157impl_nonempty_array!(
158 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
159 27, 28, 29, 30, 31, 32
160);
161
162impl_fn_types! {
163 (),
164 (A),
165 (A, B),
166 (A, B, C),
167 (A, B, C, D),
168 (A, B, C, D, E),
169 (A, B, C, D, E, F),
170 (A, B, C, D, E, F, G),
171 (A, B, C, D, E, F, G, H),
172 (A, B, C, D, E, F, G, H, I),
173 (A, B, C, D, E, F, G, H, I, J),
174 (A, B, C, D, E, F, G, H, I, J, K),
175 (A, B, C, D, E, F, G, H, I, J, K, L),
176}
177
178fieldless_enum_derive! { char => crate::Gt<crate::One> }
179fieldless_enum_derive! { bool => crate::One }
180fieldless_enum_derive! { Ordering => crate::One }
181
182#[cfg(test)]
183mod tests {
184 #[cfg(feature = "alloc")]
185 use alloc::{boxed::Box, vec::Vec};
186 use static_assertions::assert_impl_all;
187
188 use super::*;
189 use crate::{
190 Unstable,
191 layout::{NonRobust, Robust},
192 niche::WithNiche,
193 };
194
195 #[test]
196 fn robust_u8() {
197 assert_impl_all!(u8:
198 RustSpec<
199 Layout = Stable,
200 Size = size::Sized<crate::Gt<Zero>>,
201 Alignment = crate::One,
202 Trap = Robust,
203 Niche = WithoutNiche,
204 Mutability = Exclusive,
205 __IndirectTrap = Robust,
206 >,
207 );
208 assert_impl_all!(&u8:
209 RustSpec<
210 Layout = Stable,
211 Size = size::Sized<crate::Gt<Zero>>,
212 Alignment = <usize as RustSpec>::Alignment,
213 Trap = NonRobust,
214 Niche = WithNiche<crate::Stable>,
215 Mutability = Exclusive,
216 __IndirectTrap = Robust,
217 >,
218 );
219 assert_impl_all!(&mut u8:
220 RustSpec<
221 Layout = Stable,
222 Size = size::Sized<crate::Gt<Zero>>,
223 Alignment = <usize as RustSpec>::Alignment,
224 Trap = NonRobust,
225 Niche = WithNiche<crate::Stable>,
226 Mutability = Exclusive,
227 __IndirectTrap = Robust,
228 >,
229 );
230 #[cfg(feature = "alloc")]
231 assert_impl_all!(Box<u8>:
232 RustSpec<
233 Layout = Stable,
234 Size = size::Sized<crate::Gt<Zero>>,
235 Alignment = <usize as RustSpec>::Alignment,
236 Trap = NonRobust,
237 Niche = WithNiche<crate::Stable>,
238 Mutability = Exclusive,
239 __IndirectTrap = Robust,
240 >,
241 );
242 assert_impl_all!(&[u8]:
243 RustSpec<
244 Layout = Unstable,
245 Size = size::Sized<crate::Gt<Zero>>,
246 Alignment = <usize as RustSpec>::Alignment,
247 Trap = NonRobust,
248 Niche = WithNiche<crate::Unstable>,
249 Mutability = Exclusive,
250 __IndirectTrap = Robust,
251 >,
252 );
253 assert_impl_all!(&mut [u8]:
254 RustSpec<
255 Layout = Unstable,
256 Size = size::Sized<crate::Gt<Zero>>,
257 Alignment = <usize as RustSpec>::Alignment,
258 Trap = NonRobust,
259 Niche = WithNiche<crate::Unstable>,
260 Mutability = Exclusive,
261 __IndirectTrap = Robust,
262 >,
263 );
264 #[cfg(feature = "alloc")]
265 assert_impl_all!(Box<[u8]>:
266 RustSpec<
267 Layout = Unstable,
268 Size = size::Sized<crate::Gt<Zero>>,
269 Alignment = <usize as RustSpec>::Alignment,
270 Trap = NonRobust,
271 Niche = WithNiche<crate::Unstable>,
272 Mutability = Exclusive,
273 __IndirectTrap = Robust,
274 >,
275 );
276 #[cfg(feature = "alloc")]
277 assert_impl_all!(Vec<u8>:
278 RustSpec<
279 Layout = Unstable,
280 Size = size::Sized<crate::Gt<Zero>>,
281 Alignment = <usize as RustSpec>::Alignment,
282 Trap = NonRobust,
283 Niche = WithNiche<crate::Unstable>,
284 Mutability = Exclusive,
285 __IndirectTrap = Robust,
286 >,
287 );
288 assert_impl_all!([u8; 2]:
289 RustSpec<
290 Layout = Stable,
291 Size = size::Sized<crate::Gt<Zero>>,
292 Alignment = crate::One,
293 Trap = Robust,
294 Niche = WithoutNiche,
295 Mutability = Exclusive,
296 __IndirectTrap = Robust,
297 >,
298 );
299 assert_impl_all!(Option<u8>:
300 RustSpec<
301 Layout = Unstable,
302 Size = size::Sized<crate::Gt<Zero>>,
303 Alignment = crate::One,
304 Trap = NonRobust,
305 Niche = WithNiche<crate::Unstable>,
306 Mutability = Exclusive,
307 __IndirectTrap = Robust,
308 >,
309 );
310 }
311}