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};