logo
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/// Asserts that the trait is a child of all of the other traits.
///
/// Related:
/// - [`assert_trait_super_all!`]
///
/// # Examples
///
/// All types that implement [`Copy`] must implement [`Clone`]:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_trait_sub_all!(Copy: Clone);
/// ```
///
/// All types that implement [`Ord`] must implement [`PartialEq`], [`Eq`], and
/// [`PartialOrd`]:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_trait_sub_all!(Ord: PartialEq, Eq, PartialOrd);
/// ```
///
/// The following example fails to compile because [`Eq`] is not required for
/// [`PartialOrd`]:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_trait_sub_all!(PartialOrd: Eq);
/// ```
///
/// [`assert_trait_super_all!`]: macro.assert_trait_super_all.html
///
/// [`Copy`]:       https://doc.rust-lang.org/std/marker/trait.Copy.html
/// [`Clone`]:      https://doc.rust-lang.org/std/clone/trait.Clone.html
/// [`Ord`]:        https://doc.rust-lang.org/std/cmp/trait.Ord.html
/// [`PartialOrd`]: https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html
/// [`Eq`]:         https://doc.rust-lang.org/std/cmp/trait.Eq.html
/// [`PartialEq`]:  https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
#[macro_export]
macro_rules! assert_trait_sub_all {
    ($sub:path: $($super:path),+ $(,)?) => {
        const _: () = {
            // One scope per super-trait.
            $({
                #[allow(non_camel_case_types)]
                trait __Impl_Implication: $super {}

                // Can only be implemented for `$sub` types if `$super` is
                // also implemented.
                impl<T: $sub> __Impl_Implication for T {}
            })+
        };
    };
}

/// Asserts that the trait is a parent of all of the other traits.
///
/// Related:
/// - [`assert_trait_sub_all!`]
///
/// # Examples
///
/// With this, traits `A` and `B` can both be tested to require [`Copy`] on a
/// single line:
///
/// ```
/// # use static_assertions::assert_trait_super_all;
/// trait A: Copy {}
/// trait B: Copy {}
///
/// assert_trait_super_all!(Copy: A, B);
/// ```
///
/// Otherwise, each sub-trait would require its own call to
/// [`assert_trait_sub_all!`]:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// # trait A: Copy {}
/// # trait B: Copy {}
/// assert_trait_sub_all!(A: Copy);
/// assert_trait_sub_all!(B: Copy);
/// ```
///
/// The following example fails to compile because trait `C` does not require
/// [`Copy`]:
///
/// ```compile_fail
/// # use static_assertions::assert_trait_super_all;
/// # trait A: Copy {}
/// # trait B: Copy {}
/// trait C {}
///
/// assert_trait_super_all!(Copy: A, B, C);
/// ```
///
/// [`assert_trait_sub_all!`]: macro.assert_trait_sub_all.html
///
/// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html
#[macro_export(local_inner_macros)]
macro_rules! assert_trait_super_all {
    ($super:path: $($sub:path),+ $(,)?) => {
        $(assert_trait_sub_all!($sub: $super);)+
    };
}