1//! Zero-sized types .
23use std::{cell::Cell, marker::PhantomData, rc::Rc};
45use crate::{
6 abi_stability::PrefixStableAbi,
7 derive_macro_reexports::*,
8 type_layout::{GenericTLData, MonoTLData, MonoTypeLayout, ReprAttr, TypeLayout},
9};
1011#[macro_use]
12mod stable_abi_impls;
1314/////////////////
1516/// Marker type used to mark a type as being `Send + Sync`.
17#[repr(C)]
18#[derive(StableAbi)]
19pub struct SyncSend;
2021const _: () = zst_assert! {SyncSend};
2223/////////////////
2425/// Marker type used to mark a type as being `!Send + !Sync`.
26pub struct UnsyncUnsend {
27 _marker: UnsafeIgnoredType<Rc<()>>,
28}
2930monomorphic_marker_type! {UnsyncUnsend, UnsafeIgnoredType<Rc<()>>}
3132impl UnsyncUnsend {
33/// Constructs a `UnsyncUnsend`
34pub const NEW: Self = Self {
35 _marker: UnsafeIgnoredType::NEW,
36 };
37}
3839/////////////////
4041/// Marker type used to mark a type as being `Send + !Sync`.
42pub struct UnsyncSend {
43 _marker: UnsafeIgnoredType<Cell<()>>,
44}
4546monomorphic_marker_type! {UnsyncSend, UnsafeIgnoredType<Cell<()>>}
4748impl UnsyncSend {
49/// Constructs a `UnsyncSend`
50pub const NEW: Self = Self {
51 _marker: UnsafeIgnoredType::NEW,
52 };
53}
5455/////////////////
5657/// Marker type used to mark a type as being `!Send + Sync`.
58// #[sabi(debug_print)]
59pub struct SyncUnsend {
60 _marker: UnsyncUnsend,
61}
6263monomorphic_marker_type! {SyncUnsend, UnsyncUnsend}
6465impl SyncUnsend {
66/// Constructs a `SyncUnsend`
67pub const NEW: Self = Self {
68 _marker: UnsyncUnsend::NEW,
69 };
70}
7172unsafe impl Sync for SyncUnsend {}
7374/////////////////
7576/// Zero-sized marker type used to signal that even though a type
77/// could implement `Copy` and `Clone`,
78/// it is semantically an error to do so.
79#[repr(C)]
80#[derive(StableAbi)]
81// #[sabi(debug_print)]
82pub struct NotCopyNotClone;
8384const _: () = zst_assert! {NotCopyNotClone};
8586//////////////////////////////////////////////////////////////
8788/// Used by vtables/pointers to signal that the type has been erased.
89///
90#[repr(C)]
91#[derive(StableAbi)]
92pub struct ErasedObject<T = ()> {
93 _marker: NonOwningPhantom<T>,
94}
9596const _: () = zst_assert! {ErasedObject};
9798//////////////////////////////////////////////////////////////
99100/// Used by pointers to vtables/modules to signal that the type has been erased.
101///
102pub struct ErasedPrefix {
103 _priv: PhantomData<u8>,
104}
105106const _: () = zst_assert!(ErasedPrefix);
107108unsafe impl GetStaticEquivalent_ for ErasedPrefix {
109type StaticEquivalent = ErasedPrefix;
110}
111112unsafe impl PrefixStableAbi for ErasedPrefix {
113type IsNonZeroType = False;
114const LAYOUT: &'static TypeLayout = <ErasedObject as StableAbi>::LAYOUT;
115}
116117//////////////////////////////////////////////////////////////
118119/// MarkerType which ignores its type parameter in its [`StableAbi`] implementation.
120///
121/// # Safety
122///
123/// `Unsafe` is part of its name,
124/// because users can violate memory safety
125/// if they depend on the value of the type parameter passed to `UnsafeIgnoredType` for safety,
126/// since the type parameter is ignored when type checking dynamic libraries.
127///
128///
129/// [`StableAbi`]: ../trait.StableAbi.html
130///
131pub struct UnsafeIgnoredType<T: ?Sized> {
132/// This field must be public to promise (for semver) that a repr change would be a breaking
133 /// change (see <https://github.com/rust-lang/rust/issues/78586>), which is important as this is
134 /// used as a zero-sized type in `repr(transparent)` structs.
135pub _inner: PhantomData<T>,
136}
137138impl<T: ?Sized> UnsafeIgnoredType<T> {
139/// Constructs an `UnsafeIgnoredType`.
140pub const DEFAULT: Self = Self {
141 _inner: PhantomData,
142 };
143144/// Constructs an `UnsafeIgnoredType`.
145pub const NEW: Self = Self {
146 _inner: PhantomData,
147 };
148}
149150impl<T: ?Sized> Copy for UnsafeIgnoredType<T> {}
151152impl<T: ?Sized> Default for UnsafeIgnoredType<T> {
153fn default() -> Self {
154Self::DEFAULT
155 }
156}
157158impl<T: ?Sized> Clone for UnsafeIgnoredType<T> {
159fn clone(&self) -> Self {
160*self
161}
162}
163164unsafe impl<T> GetStaticEquivalent_ for UnsafeIgnoredType<T> {
165type StaticEquivalent = ();
166}
167unsafe impl<T> StableAbi for UnsafeIgnoredType<T> {
168type IsNonZeroType = False;
169170const LAYOUT: &'static TypeLayout = {
171const MONO_TYPE_LAYOUT: &MonoTypeLayout = &MonoTypeLayout::new(
172*mono_shared_vars,
173rstr!("UnsafeIgnoredType"),
174make_item_info!(),
175 MonoTLData::struct_(rslice![]),
176tl_genparams!(;;),
177 ReprAttr::C,
178 ModReflMode::Module,
179rslice![],
180 );
181182make_shared_vars! {
183impl[T] UnsafeIgnoredType<T>;
184185let (mono_shared_vars,shared_vars)={};
186 }
187188zst_assert!(Self);
189190&TypeLayout::from_std::<Self>(
191 shared_vars,
192 MONO_TYPE_LAYOUT,
193Self::ABI_CONSTS,
194 GenericTLData::Struct,
195 )
196 };
197}
198199//////////////////////////////////////////////////////////////
200201/// An ffi-safe equivalent of a `PhantomData<fn()->T>`
202pub struct NonOwningPhantom<T: ?Sized> {
203// The StableAbi layout for a `NonOwningPhantom<T>` is the same as `PhantomData<T>`,
204 // the type of this field is purely for variance.
205_marker: PhantomData<extern "C" fn() -> T>,
206}
207208impl<T: ?Sized> NonOwningPhantom<T> {
209/// Constructs a `NonOwningPhantom`
210pub const DEFAULT: Self = Self {
211 _marker: PhantomData,
212 };
213214/// Constructs a `NonOwningPhantom`
215pub const NEW: Self = Self {
216 _marker: PhantomData,
217 };
218}
219220impl<T: ?Sized> Copy for NonOwningPhantom<T> {}
221222impl<T: ?Sized> Default for NonOwningPhantom<T> {
223#[inline(always)]
224fn default() -> Self {
225Self::DEFAULT
226 }
227}
228229impl<T: ?Sized> Clone for NonOwningPhantom<T> {
230#[inline(always)]
231fn clone(&self) -> Self {
232*self
233}
234}
235236unsafe impl<T: ?Sized> GetStaticEquivalent_ for NonOwningPhantom<T>
237where
238PhantomData<T>: GetStaticEquivalent_,
239{
240type StaticEquivalent = GetStaticEquivalent<PhantomData<T>>;
241}
242243unsafe impl<T: ?Sized> StableAbi for NonOwningPhantom<T>
244where
245PhantomData<T>: StableAbi,
246{
247type IsNonZeroType = False;
248249const LAYOUT: &'static TypeLayout = {
250zst_assert!(Self);
251 <PhantomData<T> as StableAbi>::LAYOUT
252 };
253}