Skip to main content

rust_spec/core_impls/
wrappers.rs

1#[cfg(feature = "alloc")]
2use alloc::{string::String, vec::Vec};
3use core::{
4    cmp::Reverse,
5    convert::Infallible,
6    marker::{PhantomData, PhantomPinned},
7    mem::{ManuallyDrop, MaybeUninit},
8    num::{NonZero, Saturating, Wrapping},
9    ptr::NonNull,
10};
11
12use crate::{
13    RustSpec, Stable, Unstable,
14    layout::{NonRobust, Robust},
15    mutability::Exclusive,
16    niche::{WithNiche, WithoutNiche},
17    size,
18};
19
20macro_rules! non_zero_derive {
21    ($($primitive:ty),+ $(,)?) => {$(
22        unsafe impl RustSpec for NonZero<$primitive> {
23            type Layout = Stable;
24            type Size = size::Sized<crate::Gt<crate::Zero>>;
25            type Alignment = <$primitive as RustSpec>::Alignment;
26            type Trap = NonRobust;
27            type Niche = WithNiche<Stable>;
28            type Mutability = Exclusive;
29            type __IndirectTrap = Robust;
30        }
31    )+};
32}
33
34macro_rules! stable_robust_zst {
35    (($($generics:tt)*) => $ty:ty) => {
36        unsafe impl<$($generics)*> RustSpec for $ty {
37            type Layout = Stable;
38            type Size = size::Sized<size::Zero>;
39            type Alignment = crate::One;
40            type Trap = Robust;
41            type Niche = WithoutNiche;
42            type Mutability = Exclusive;
43            type __IndirectTrap = Robust;
44        }
45    };
46}
47
48macro_rules! transparent_wrapper {
49    (($($generics:tt)*) => $ty:ty) => {
50        unsafe impl<$($generics)*> RustSpec for $ty {
51            type Layout = T::Layout;
52            type Size = T::Size;
53            type Alignment = T::Alignment;
54            type Trap = T::Trap;
55            type Niche = T::Niche;
56            type Mutability = T::Mutability;
57            type __IndirectTrap = T::__IndirectTrap;
58        }
59    };
60}
61
62non_zero_derive!(
63    u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize
64);
65
66stable_robust_zst!(() => ());
67stable_robust_zst!(() => Infallible);
68stable_robust_zst!(() => PhantomPinned);
69stable_robust_zst!((T: ?Sized) => PhantomData<T>);
70
71transparent_wrapper!((T: RustSpec) => Reverse<T>);
72transparent_wrapper!((T: RustSpec) => Wrapping<T>);
73transparent_wrapper!((T: RustSpec) => Saturating<T>);
74transparent_wrapper!((T: RustSpec + ?Sized) => ManuallyDrop<T>);
75
76unsafe impl<T: RustSpec> RustSpec for MaybeUninit<T> {
77    type Layout = T::Layout;
78    type Size = T::Size;
79    type Alignment = T::Alignment;
80    type Trap = Robust;
81    type Niche = WithoutNiche;
82    type Mutability = T::Mutability;
83    type __IndirectTrap = Robust;
84}
85
86unsafe impl<T: ?Sized> RustSpec for NonNull<T> {
87    type Layout = Stable;
88    type Size = size::Sized<crate::Gt<crate::Zero>>;
89    type Alignment = <usize as RustSpec>::Alignment;
90    type Trap = NonRobust;
91    type Niche = WithNiche<Stable>;
92    type Mutability = Exclusive;
93    type __IndirectTrap = Robust;
94}
95
96unsafe impl RustSpec for str {
97    type Layout = Stable;
98    type Size = size::MetaSized<size::SliceLike>;
99    type Alignment = crate::One;
100    type Trap = NonRobust;
101    // TODO: This should not be set at all
102    type Niche = WithNiche<Unstable>;
103    type Mutability = Exclusive;
104    type __IndirectTrap = Robust;
105}
106#[cfg(feature = "alloc")]
107unsafe impl RustSpec for String {
108    type Layout = Unstable;
109    type Size = size::Sized<crate::Gt<crate::Zero>>;
110    type Alignment = <usize as RustSpec>::Alignment;
111    type Trap = NonRobust;
112    type Niche = WithNiche<Unstable>;
113    type Mutability = Exclusive;
114    type __IndirectTrap = Robust;
115}
116
117#[cfg(feature = "alloc")]
118unsafe impl<T: RustSpec> RustSpec for Vec<T> {
119    type Layout = Unstable;
120    type Size = size::Sized<crate::Gt<crate::Zero>>;
121    type Alignment = <usize as RustSpec>::Alignment;
122    type Trap = NonRobust;
123    type Niche = WithNiche<Unstable>;
124    type Mutability = Exclusive;
125    type __IndirectTrap = T::Trap;
126}