1bcab3026Sopenharmony_ci/// Asserts that the trait is a child of all of the other traits.
2bcab3026Sopenharmony_ci///
3bcab3026Sopenharmony_ci/// Related:
4bcab3026Sopenharmony_ci/// - [`assert_trait_super_all!`]
5bcab3026Sopenharmony_ci///
6bcab3026Sopenharmony_ci/// # Examples
7bcab3026Sopenharmony_ci///
8bcab3026Sopenharmony_ci/// All types that implement [`Copy`] must implement [`Clone`]:
9bcab3026Sopenharmony_ci///
10bcab3026Sopenharmony_ci/// ```
11bcab3026Sopenharmony_ci/// # #[macro_use] extern crate static_assertions; fn main() {}
12bcab3026Sopenharmony_ci/// assert_trait_sub_all!(Copy: Clone);
13bcab3026Sopenharmony_ci/// ```
14bcab3026Sopenharmony_ci///
15bcab3026Sopenharmony_ci/// All types that implement [`Ord`] must implement [`PartialEq`], [`Eq`], and
16bcab3026Sopenharmony_ci/// [`PartialOrd`]:
17bcab3026Sopenharmony_ci///
18bcab3026Sopenharmony_ci/// ```
19bcab3026Sopenharmony_ci/// # #[macro_use] extern crate static_assertions; fn main() {}
20bcab3026Sopenharmony_ci/// assert_trait_sub_all!(Ord: PartialEq, Eq, PartialOrd);
21bcab3026Sopenharmony_ci/// ```
22bcab3026Sopenharmony_ci///
23bcab3026Sopenharmony_ci/// The following example fails to compile because [`Eq`] is not required for
24bcab3026Sopenharmony_ci/// [`PartialOrd`]:
25bcab3026Sopenharmony_ci///
26bcab3026Sopenharmony_ci/// ```compile_fail
27bcab3026Sopenharmony_ci/// # #[macro_use] extern crate static_assertions; fn main() {}
28bcab3026Sopenharmony_ci/// assert_trait_sub_all!(PartialOrd: Eq);
29bcab3026Sopenharmony_ci/// ```
30bcab3026Sopenharmony_ci///
31bcab3026Sopenharmony_ci/// [`assert_trait_super_all!`]: macro.assert_trait_super_all.html
32bcab3026Sopenharmony_ci///
33bcab3026Sopenharmony_ci/// [`Copy`]:       https://doc.rust-lang.org/std/marker/trait.Copy.html
34bcab3026Sopenharmony_ci/// [`Clone`]:      https://doc.rust-lang.org/std/clone/trait.Clone.html
35bcab3026Sopenharmony_ci/// [`Ord`]:        https://doc.rust-lang.org/std/cmp/trait.Ord.html
36bcab3026Sopenharmony_ci/// [`PartialOrd`]: https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html
37bcab3026Sopenharmony_ci/// [`Eq`]:         https://doc.rust-lang.org/std/cmp/trait.Eq.html
38bcab3026Sopenharmony_ci/// [`PartialEq`]:  https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
39bcab3026Sopenharmony_ci#[macro_export]
40bcab3026Sopenharmony_cimacro_rules! assert_trait_sub_all {
41bcab3026Sopenharmony_ci    ($sub:path: $($super:path),+ $(,)?) => {
42bcab3026Sopenharmony_ci        const _: () = {
43bcab3026Sopenharmony_ci            // One scope per super-trait.
44bcab3026Sopenharmony_ci            $({
45bcab3026Sopenharmony_ci                #[allow(non_camel_case_types)]
46bcab3026Sopenharmony_ci                trait __Impl_Implication: $super {}
47bcab3026Sopenharmony_ci
48bcab3026Sopenharmony_ci                // Can only be implemented for `$sub` types if `$super` is
49bcab3026Sopenharmony_ci                // also implemented.
50bcab3026Sopenharmony_ci                impl<T: $sub> __Impl_Implication for T {}
51bcab3026Sopenharmony_ci            })+
52bcab3026Sopenharmony_ci        };
53bcab3026Sopenharmony_ci    };
54bcab3026Sopenharmony_ci}
55bcab3026Sopenharmony_ci
56bcab3026Sopenharmony_ci/// Asserts that the trait is a parent of all of the other traits.
57bcab3026Sopenharmony_ci///
58bcab3026Sopenharmony_ci/// Related:
59bcab3026Sopenharmony_ci/// - [`assert_trait_sub_all!`]
60bcab3026Sopenharmony_ci///
61bcab3026Sopenharmony_ci/// # Examples
62bcab3026Sopenharmony_ci///
63bcab3026Sopenharmony_ci/// With this, traits `A` and `B` can both be tested to require [`Copy`] on a
64bcab3026Sopenharmony_ci/// single line:
65bcab3026Sopenharmony_ci///
66bcab3026Sopenharmony_ci/// ```
67bcab3026Sopenharmony_ci/// # use static_assertions::assert_trait_super_all;
68bcab3026Sopenharmony_ci/// trait A: Copy {}
69bcab3026Sopenharmony_ci/// trait B: Copy {}
70bcab3026Sopenharmony_ci///
71bcab3026Sopenharmony_ci/// assert_trait_super_all!(Copy: A, B);
72bcab3026Sopenharmony_ci/// ```
73bcab3026Sopenharmony_ci///
74bcab3026Sopenharmony_ci/// Otherwise, each sub-trait would require its own call to
75bcab3026Sopenharmony_ci/// [`assert_trait_sub_all!`]:
76bcab3026Sopenharmony_ci///
77bcab3026Sopenharmony_ci/// ```
78bcab3026Sopenharmony_ci/// # #[macro_use] extern crate static_assertions; fn main() {}
79bcab3026Sopenharmony_ci/// # trait A: Copy {}
80bcab3026Sopenharmony_ci/// # trait B: Copy {}
81bcab3026Sopenharmony_ci/// assert_trait_sub_all!(A: Copy);
82bcab3026Sopenharmony_ci/// assert_trait_sub_all!(B: Copy);
83bcab3026Sopenharmony_ci/// ```
84bcab3026Sopenharmony_ci///
85bcab3026Sopenharmony_ci/// The following example fails to compile because trait `C` does not require
86bcab3026Sopenharmony_ci/// [`Copy`]:
87bcab3026Sopenharmony_ci///
88bcab3026Sopenharmony_ci/// ```compile_fail
89bcab3026Sopenharmony_ci/// # use static_assertions::assert_trait_super_all;
90bcab3026Sopenharmony_ci/// # trait A: Copy {}
91bcab3026Sopenharmony_ci/// # trait B: Copy {}
92bcab3026Sopenharmony_ci/// trait C {}
93bcab3026Sopenharmony_ci///
94bcab3026Sopenharmony_ci/// assert_trait_super_all!(Copy: A, B, C);
95bcab3026Sopenharmony_ci/// ```
96bcab3026Sopenharmony_ci///
97bcab3026Sopenharmony_ci/// [`assert_trait_sub_all!`]: macro.assert_trait_sub_all.html
98bcab3026Sopenharmony_ci///
99bcab3026Sopenharmony_ci/// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html
100bcab3026Sopenharmony_ci#[macro_export(local_inner_macros)]
101bcab3026Sopenharmony_cimacro_rules! assert_trait_super_all {
102bcab3026Sopenharmony_ci    ($super:path: $($sub:path),+ $(,)?) => {
103bcab3026Sopenharmony_ci        $(assert_trait_sub_all!($sub: $super);)+
104bcab3026Sopenharmony_ci    };
105bcab3026Sopenharmony_ci}
106