1pub trait ConstDefault {
11 const DEFAULT: Self;
13}
14
15macro_rules! impl_cdef {
17 (<$A:ident> $def:expr => $($t:ty),+) => { $( $crate::impl_cdef![@<$A> $def => $t]; )+ };
19 (@<$A:ident> $def:expr => $t:ty) => {
20 impl<$A> $crate::ConstDefault for $t {
21 #[allow(clippy::declare_interior_mutable_const)]
22 const DEFAULT: Self = $def;
23 }
24 };
25 (<$A:ident:$A_:ident> $def:expr => $($t:ty),+) => {
27 $( $crate::impl_cdef![@<$A:$A_> $def => $t]; )+
28 };
29 (@<$A:ident:$A_:ident> $def:expr => $t:ty) => {
30 impl<$A: $crate::ConstDefault> $crate::ConstDefault for $t {
31 #[allow(clippy::declare_interior_mutable_const, reason = "FIXME?")]
32 const DEFAULT: Self = $def;
33 }
34 };
35 (<$A:ident, $B:ident> $def:expr => $($t:ty),+) => {
37 $( $crate::impl_cdef![@<$A, $B> $def => $t]; )+
38 };
39 (@<$A:ident, $B:ident> $def:expr => $t:ty) => {
40 impl<$A, $B> $crate::ConstDefault for $t {
41 #[allow(clippy::declare_interior_mutable_const)] const DEFAULT: Self = $def;
43 }
44 };
45 (<$A:ident:$A_:ident, $B:ident:$B_:ident> $def:expr => $($t:ty),+) => {
47 $( $crate::impl_cdef![@<$A:$A_, $B:$B_> $def => $t]; )+ };
48 (@<$A:ident:$A_:ident, $B:ident:$B_:ident> $def:expr => $t:ty) => {
49 impl<$A:$A_, $B:$B_> $crate::ConstDefault for $t {
50 #[allow(clippy::declare_interior_mutable_const)] const DEFAULT: Self = $def;
52 }
53 };
54
55 (<$A:ident, $B:ident, $C:ident> $def:expr => $($t:ty),+) => {
57 $( $crate::impl_cdef![@<$A, $B, $C> $def => $t]; )+
58 };
59 (@<$A:ident, $B:ident, $C:ident> $def:expr => $t:ty) => {
60 impl<$A, $B, $C> $crate::ConstDefault for $t {
61 #[allow(clippy::declare_interior_mutable_const)] const DEFAULT: Self = $def;
63 }
64 };
65 ($def:expr => $($t:ty),+) => { $( $crate::impl_cdef![@$def => $t]; )+ };
67 (@$def:expr => $t:ty) => {
68 impl $crate::ConstDefault for $t {
69 #[allow(clippy::declare_interior_mutable_const)]
70 const DEFAULT: Self = $def;
71 }
72 };
73 (arrays <$A:ident:$BOUND:ident> $($LEN:literal),+) => {
75 $( $crate::impl_cdef![@array:$LEN <$A:$BOUND>]; )+
76 };
77 (@array:$LEN:literal <$A:ident:$BOUND:ident>) => {
78 impl<$A: $crate::ConstDefault> $crate::ConstDefault for [$A; $LEN] {
79 #[allow(clippy::declare_interior_mutable_const)] const DEFAULT: Self = [$A::DEFAULT; $LEN];
81 }
82 };
83 (tuples <$A:ident:$BOUND:ident>) => {
85 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,) => ($A::DEFAULT,)];
87 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,) => ($A::DEFAULT, $A::DEFAULT)];
89 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT)];
91 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT)];
93 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT)];
95 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT)];
97 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT,
99 $A::DEFAULT)];
100 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT,
102 $A::DEFAULT, $A::DEFAULT)];
103 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT,
105 $A::DEFAULT, $A::DEFAULT, $A::DEFAULT)];
106 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT,
108 $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT)];
109 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT,
111 $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT)];
112 $crate::impl_cdef![@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A,$A,$A,$A,$A) => ($A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT,
114 $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT, $A::DEFAULT)];
115 };
116 (@tuple <$A:ident:$BOUND:ident> $type:ty => $value:expr) => {
117 impl<$A: $crate::ConstDefault> $crate::ConstDefault for $type {
118 const DEFAULT: Self = $value;
119 }
120 };
121}
122pub(crate) use impl_cdef;
123
124#[rustfmt::skip]
127mod impl_core {
128 use super::{impl_cdef, ConstDefault};
129 use core::{
130 cmp::Reverse,
131 cell::{Cell, OnceCell, RefCell, UnsafeCell},
132 ffi::CStr,
133 marker::{PhantomData, PhantomPinned},
134 mem::ManuallyDrop,
135 num::{Saturating, Wrapping},
136 ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
137 panic::AssertUnwindSafe,
138 time::Duration,
140 };
141 impl_cdef![false => bool];
147 impl_cdef![Duration::new(0, 0) => Duration];
148 impl_cdef![0 => i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize];
149 impl_cdef![0.0 => f32, f64];
150 impl_cdef!['\x00' => char];
151 impl_cdef![() => ()];
152 impl_cdef![tuples <T: ConstDefault>];
153 impl_cdef![arrays <T: ConstDefault> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
154 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32];
155
156 impl_cdef![<T> core::ptr::null() => *const T];
157 impl_cdef![<T> core::ptr::null_mut() => *mut T];
158
159 impl_cdef![<T> &[] => &[T]]; impl ConstDefault for &CStr {
162 const DEFAULT: Self = {
163 if let Ok(s) = CStr::from_bytes_until_nul(&[0]) { s } else { unreachable![]; }
164 };
165 }
166
167 impl_cdef![Self => PhantomPinned, RangeFull];
168 impl_cdef![<T: ConstDefault>Self { start: T::DEFAULT } => RangeFrom<T>];
169 impl_cdef![<T: ConstDefault>Self { end: T::DEFAULT } => RangeTo<T>, RangeToInclusive<T>];
170 impl_cdef![<T: ConstDefault>Self { start: T::DEFAULT, end: T::DEFAULT } => Range<T>];
171 impl_cdef![<T: ConstDefault>Self::new(T::DEFAULT, T::DEFAULT) => RangeInclusive<T>];
173
174 impl_cdef![<T: ConstDefault> Self::new() => OnceCell<T>];
175 impl_cdef![<T: ConstDefault> Self::new(T::DEFAULT) =>
176 Cell<T>, ManuallyDrop<T>, RefCell<T>, UnsafeCell<T>
177 ];
178 impl_cdef![<T: ConstDefault> Self(T::DEFAULT) =>
179 AssertUnwindSafe<T>, Reverse<T>, Saturating<T>, Wrapping<T>
180 ];
181 impl_cdef![<T> Self => PhantomData<T>]; impl_cdef![<T: ConstDefault> Some(T::DEFAULT) => Option<T>];
183
184 }
191
192#[cfg(feature = "std")]
203#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "std")))]
204mod impl_std {
205 use std::{
206 cell::LazyCell,
207 process::ExitCode,
210 sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock, Weak as ArcWeak},
211 };
212 impl_cdef![Self::SUCCESS => ExitCode];
216 impl_cdef![Self::new() => Condvar, Once];
217 impl_cdef![<T: ConstDefault> Self::new() => ArcWeak<T>, OnceLock<T>];
218 impl_cdef![<T: ConstDefault> Self::new(T::DEFAULT) => Mutex<T>, RwLock<T>];
219 impl_cdef![<T: ConstDefault> Self::new(|| T::DEFAULT) => LazyCell<T>, LazyLock<T>];
220
221 }