generic_statics/
zeroable.rs

1use std::{
2    cell::UnsafeCell,
3    marker::PhantomData,
4    mem::{ManuallyDrop, MaybeUninit},
5    sync::atomic::{
6        AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicPtr, AtomicU16,
7        AtomicU32, AtomicU64, AtomicU8, AtomicUsize,
8    },
9};
10
11/// Types that can be safely "zero-initialized".
12///
13/// ## Safety
14///
15/// The type this trait is implemented on must:
16///
17/// - be inhabited (no `!`)
18/// - have a state where all bits are all zeroes
19///
20/// ## Notes
21///
22/// Integral types (`i32`, `i64`, ...), and some other type that fulfill the above safety
23/// requirements have built-in impls that are provided by this crate.
24///
25pub unsafe trait Zeroable: Sized {}
26
27macro_rules! impl_integers {
28    ($t:ty) => {
29        unsafe impl Zeroable for $t {}
30    };
31    ($t1:ty, $($tr:ty),+) => {
32        impl_integers!($t1);
33        impl_integers!($($tr),+);
34    }
35}
36
37impl_integers!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize, bool);
38
39impl_integers!(
40    AtomicBool,
41    AtomicI16,
42    AtomicI32,
43    AtomicI64,
44    AtomicI8,
45    AtomicIsize,
46    AtomicU16,
47    AtomicU32,
48    AtomicU64,
49    AtomicU8,
50    AtomicUsize
51);
52
53unsafe impl<T> Zeroable for AtomicPtr<T> {}
54
55unsafe impl<T: Sized> Zeroable for *const T {}
56unsafe impl<T: Sized> Zeroable for *mut T {}
57
58unsafe impl<T> Zeroable for MaybeUninit<T> {}
59
60unsafe impl<T: Zeroable> Zeroable for ManuallyDrop<T> {}
61unsafe impl<T: Zeroable> Zeroable for UnsafeCell<T> {}
62unsafe impl<T: ?Sized> Zeroable for PhantomData<T> {}
63
64unsafe impl<T: Zeroable, const N: usize> Zeroable for [T; N] {}
65
66macro_rules! impl_tuples {
67    ($t1:ident) => {
68        unsafe impl<$t1: Zeroable> Zeroable for ($t1,) {}
69    };
70    ($t1:ident, $($tr:ident),+) => {
71        impl_tuples!(@impl $t1, $($tr),+);
72        impl_tuples!($($tr),+);
73    };
74    (@impl $($t:ident),+) => {
75        unsafe impl<$($t),+> Zeroable for ($($t),+)
76        where
77            $($t: Zeroable),+
78        {}
79    };
80}
81
82impl_tuples!(A, B, C, D, E, F, G, H);