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    ops::Add,
10};
11
12#[cfg(feature = "alloc")]
13use crate::drop::{AutoDrop, CustomDrop};
14use crate::{
15    NonOpaque, RustSpec, Stable, Unstable,
16    drop::NoDrop,
17    layout::{NonRobust, Robust},
18    mutability::Exclusive,
19    niche::{WithNiche, WithoutNiche},
20    size,
21};
22
23macro_rules! non_zero_derive {
24    ($($primitive:ty),+ $(,)?) => {$(
25        unsafe impl RustSpec for NonZero<$primitive> {
26            type Layout = Stable;
27            type Size = size::Sized<crate::Gt<crate::Zero>>;
28            type Alignment = <$primitive as RustSpec>::Alignment;
29            type Trap = NonRobust;
30            type Niche = WithNiche<Stable>;
31            type Drop = NoDrop;
32            type Mutability = Exclusive;
33            type Opacity = NonOpaque;
34            type __IndirectTrap = Robust;
35        }
36    )+};
37}
38
39macro_rules! stable_robust_zst {
40    (($($generics:tt)*) => $ty:ty) => {
41        unsafe impl<$($generics)*> RustSpec for $ty {
42            type Layout = Stable;
43            type Size = size::Sized<size::Zero>;
44            type Alignment = crate::One;
45            type Trap = Robust;
46            type Niche = WithoutNiche;
47            type Drop = NoDrop;
48            type Mutability = Exclusive;
49            type Opacity = NonOpaque;
50            type __IndirectTrap = Robust;
51        }
52    };
53}
54
55macro_rules! transparent_wrapper {
56    (($($generics:tt)*) => $ty:ty) => {
57        unsafe impl<$($generics)*> RustSpec for $ty
58        where
59            NoDrop: Add<T::Drop>,
60        {
61            type Layout = T::Layout;
62            type Size = T::Size;
63            type Alignment = T::Alignment;
64            type Trap = T::Trap;
65            type Niche = T::Niche;
66            type Drop = <NoDrop as Add<T::Drop>>::Output;
67            type Mutability = T::Mutability;
68            type Opacity = NonOpaque;
69            type __IndirectTrap = T::__IndirectTrap;
70        }
71    };
72}
73
74non_zero_derive!(
75    u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize
76);
77
78stable_robust_zst!(() => ());
79stable_robust_zst!(() => Infallible);
80stable_robust_zst!(() => PhantomPinned);
81stable_robust_zst!((T: ?Sized) => PhantomData<T>);
82
83transparent_wrapper!((T: RustSpec) => Reverse<T>);
84transparent_wrapper!((T: RustSpec) => Wrapping<T>);
85transparent_wrapper!((T: RustSpec) => Saturating<T>);
86
87unsafe impl<T: RustSpec + ?Sized> RustSpec for ManuallyDrop<T> {
88    type Layout = T::Layout;
89    type Size = T::Size;
90    type Alignment = T::Alignment;
91    type Trap = T::Trap;
92    type Niche = T::Niche;
93    type Drop = NoDrop;
94    type Mutability = T::Mutability;
95    type Opacity = NonOpaque;
96    type __IndirectTrap = T::__IndirectTrap;
97}
98
99unsafe impl<T: RustSpec> RustSpec for MaybeUninit<T> {
100    type Layout = T::Layout;
101    type Size = T::Size;
102    type Alignment = T::Alignment;
103    type Trap = Robust;
104    type Niche = WithoutNiche;
105    type Drop = NoDrop;
106    type Mutability = T::Mutability;
107    type Opacity = NonOpaque;
108    type __IndirectTrap = Robust;
109}
110
111unsafe impl RustSpec for str {
112    type Layout = Stable;
113    type Size = size::MetaSized<size::SliceLike>;
114    type Alignment = crate::One;
115    type Trap = NonRobust;
116    // TODO: This should not be set at all
117    type Niche = WithNiche<Unstable>;
118    type Drop = NoDrop;
119    type Mutability = Exclusive;
120    type Opacity = NonOpaque;
121    type __IndirectTrap = Robust;
122}
123#[cfg(feature = "alloc")]
124unsafe impl RustSpec for String {
125    type Layout = Unstable;
126    type Size = size::Sized<crate::Gt<crate::Zero>>;
127    type Alignment = <usize as RustSpec>::Alignment;
128    type Trap = NonRobust;
129    type Niche = WithNiche<Unstable>;
130    type Drop = AutoDrop;
131    type Mutability = Exclusive;
132    type Opacity = NonOpaque;
133    type __IndirectTrap = NonRobust;
134}
135
136#[cfg(feature = "alloc")]
137unsafe impl<T: RustSpec> RustSpec for Vec<T> {
138    type Layout = Unstable;
139    type Size = size::Sized<crate::Gt<crate::Zero>>;
140    type Alignment = <usize as RustSpec>::Alignment;
141    type Trap = NonRobust;
142    type Niche = WithNiche<Unstable>;
143    type Drop = CustomDrop<AutoDrop>;
144    type Mutability = Exclusive;
145    type Opacity = NonOpaque;
146    type __IndirectTrap = T::Trap;
147}