const_type_layout/inhabited.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
//! Helper module to compute whether a combination of types implementing
//! [`crate::TypeLayout`] are [inhabited] or [uninhabited].
//!
//! [inhabited]: https://doc.rust-lang.org/reference/glossary.html#inhabited
//! [uninhabited]: https://doc.rust-lang.org/reference/glossary.html#uninhabited
/// Helper macro to compute whether
///
/// - all of a list of types, all implementing [`crate::TypeLayout`], e.g. `[T,
/// U, V]`,
/// - all of a list of braced expressions of type [`crate::MaybeUninhabited`],
/// e.g. `[{ all![] }, { any![] }, { all![] }]`,
///
/// are [inhabited].
///
/// `all![]` resolves to [`crate::MaybeUninhabited::Inhabited`].
///
/// For instance, a struct is inhabited iff all of its fields are inhabited.
/// The empty list of types is inhabited. This macro resolves into either
/// [`crate::MaybeUninhabited::Inhabited`] or
/// [`crate::MaybeUninhabited::Uninhabited`].
///
/// [inhabited]: https://doc.rust-lang.org/reference/glossary.html#inhabited
#[macro_export]
#[doc(hidden)]
macro_rules! all {
() => { $crate::MaybeUninhabited::Inhabited(()) };
($L:ty $(, $R:ty)*) => {
<$L as $crate::TypeLayout>::INHABITED.and(
$crate::inhabited::all![$($R),*]
)
};
({ $L:expr } $(, { $R:expr })*) => {
$crate::MaybeUninhabited::and(
$L, $crate::inhabited::all![$({ $R }),*]
)
};
}
/// Helper macro to compute whether
///
/// - any of a list of types, all implementing [`crate::TypeLayout`], e.g. `[T,
/// U, V]`,
/// - any of a list of braced expressions of type [`crate::MaybeUninhabited`],
/// e.g. `[{ all![] }, { any![] }, { all![] }]`,
///
/// is [inhabited].
///
/// `any![]` resolves to [`crate::MaybeUninhabited::Uninhabited`].
///
/// For instance, an enum is inhabited iff any of its variants is inhabited.
/// The empty list of types is [uninhabited]. This macro resolves into either
/// [`crate::MaybeUninhabited::Inhabited`] or
/// [`crate::MaybeUninhabited::Uninhabited`].
///
/// [inhabited]: https://doc.rust-lang.org/reference/glossary.html#inhabited
/// [uninhabited]: https://doc.rust-lang.org/reference/glossary.html#uninhabited
#[macro_export]
#[doc(hidden)]
macro_rules! any {
() => { $crate::MaybeUninhabited::Uninhabited };
($L:ty $(, $R:ty)*) => {
<$L as $crate::TypeLayout>::INHABITED.or(
$crate::inhabited::any![$($R),*]
)
};
({ $L:expr } $(, { $R:expr })*) => {
$crate::MaybeUninhabited::or(
$L, $crate::inhabited::any![$({ $R }),*]
)
};
}
#[doc(inline)]
pub use {all, any};