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