Skip to main content

rust_spec/
primitives.rs

1//! Logic related to the conversion of primitives to and from FFI-compatible representation
2
3use 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        // FIXME:
62        //unsafe impl<$($arg,)* R> RustSpec for fn($($arg),*) -> R {
63        //    type Layout = Stable<NonRobust>;
64        //    type Size = size::Sized<crate::Gt<Zero>>;
65        //    type Niche = WithNiche<Stable>;
66        //    type Mutability = Exclusive;
67        //    type __IndirectLayout = Stable<Robust>;
68        //}
69
70        //unsafe impl<$($arg,)* R> RustSpec for unsafe fn($($arg),*) -> R {
71        //    type Layout = Stable<NonRobust>;
72        //    type Size = size::Sized<crate::Gt<Zero>>;
73        //    type Niche = WithNiche<Stable>;
74        //    type Mutability = Exclusive;
75        //    type __IndirectLayout = Stable<Robust>;
76        //}
77
78        //unsafe impl<$($arg,)* R> RustSpec for extern "C" fn($($arg),*) -> R {
79        //    type Layout = Stable<NonRobust>;
80        //    type Size = size::Sized<crate::Gt<Zero>>;
81        //    type Niche = WithNiche<Stable>;
82        //    type Mutability = Exclusive;
83        //    type __IndirectLayout = Stable<Robust>;
84        //}
85
86        //unsafe impl<$($arg,)* R> RustSpec for unsafe extern "C" fn($($arg),*) -> R {
87        //    type Layout = Stable<NonRobust>;
88        //    type Size = size::Sized<crate::Gt<Zero>>;
89        //    type Niche = WithNiche<Stable>;
90        //    type Mutability = Exclusive;
91        //    type __IndirectLayout = Stable<Robust>;
92        //}
93    };
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    // TODO: This should not be set at all
141    // however we set it to help some impls
142    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}