zst/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3#![cfg_attr(
4    const_impl,
5    feature(const_trait_impl),
6    feature(const_default_impls),
7    feature(const_fn_trait_bound)
8)]
9
10#[cfg(feature = "const_default_impls")]
11use const_fn::const_fn;
12#[cfg(not(const_impl))]
13use unconst_trait_impl::unconst_trait_impl;
14use core::{default::Default, marker::PhantomData};
15#[cfg(const_impl)]
16use remove_macro_call::remove_macro_call;
17pub use the_assoc_ty_ext::TheAssocTyExt;
18
19/// [1-ZST](https://github.com/rust-lang/unsafe-code-guidelines/issues/172), i.e. one-aligned
20/// zero-sized type.
21/// 
22/// # Example
23/// ```rust
24/// use zst::ZST;
25/// use core::mem::{size_of, size_of_val};
26/// 
27/// // Repr is necessary to ensure the size of the discriminant
28/// #[repr(u8)]
29/// enum PrimUnsignedIntKinds {
30///     U8(ZST<u8>),
31///     U16(ZST<u16>),
32///     U32(ZST<u32>),
33///     U64(ZST<u64>),
34///     U128(ZST<u128>),
35///     Usize(ZST<usize>),
36/// }
37/// 
38/// assert_eq!(size_of::<ZST<u16>>(), 0);
39/// assert_eq!(
40///     size_of_val(&PrimUnsignedIntKinds::U16(ZST::<u16>::default())),
41///     size_of::<u8>()
42/// );
43/// // Since the ZST<T> is 1-aligned (#[repr(align(1))]), the following is guaranteed to hold
44/// assert_eq!(
45///     size_of::<PrimUnsignedIntKinds>(),
46///     size_of::<core::mem::Discriminant<PrimUnsignedIntKinds>>()
47/// );
48/// ```
49/// 
50// Since ZST is both Eq and and PartialEq, it has structural match
51// https://github.com/rust-lang/rust/issues/63438
52#[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, Copy)]
53#[repr(align(1))]
54pub struct ZST<T: ?Sized>(PhantomData<*const T>);
55
56#[cfg_attr(const_impl, remove_macro_call)]
57unconst_trait_impl! {
58    impl<T: ?Sized> const Default for ZST<T> {
59        fn default() -> Self {
60            ZST(Default::default())
61        }
62    }
63}
64
65#[cfg_attr(const_impl, remove_macro_call)]
66unconst_trait_impl! {
67    impl<T: ?Sized> const TheAssocTyExt for ZST<T> {
68        type TheAssocTy = T;
69    }
70}
71
72impl<T: ?Sized> ZST<T> {
73    #[cfg_attr(feature = "const_default_impls", const_fn)]
74    #[inline(always)]
75    pub fn new() -> ZST<T> {
76        Default::default()
77    }
78}