1 /// Asserts that types are equal.
2 ///
3 /// # Examples
4 ///
5 /// On stable Rust, using the macro requires a unique “label” when used in a
6 /// module scope:
7 ///
8 #[cfg_attr(feature = "nightly", doc = "```ignore")]
9 #[cfg_attr(not(feature = "nightly"), doc = "```")]
10 /// # #[macro_use] extern crate static_assertions;
11 /// # fn main() {}
12 /// type A = u8;
13 /// type B = A;
14 ///
15 /// assert_eq_type!(byte; u8, A, B);
16 /// ```
17 ///
18 /// The [labeling limitation](index.html#limitations) is not necessary if
19 /// compiling on nightly Rust with the `nightly` feature enabled:
20 ///
21 #[cfg_attr(feature = "nightly", doc = "```")]
22 #[cfg_attr(not(feature = "nightly"), doc = "```ignore")]
23 /// #![feature(underscore_const_names)]
24 /// # #[macro_use] extern crate static_assertions;
25 /// # type A = u8;
26 /// # type B = A;
27 ///
28 /// assert_eq_type!(u8, A, B);
29 /// ```
30 ///
31 /// This macro can also be used to compare types that involve lifetimes. Just
32 /// use `'static` in that case:
33 ///
34 /// ```
35 /// # #[macro_use] extern crate static_assertions;
36 /// # fn main() {
37 /// type Buf<'a> = &'a [u8];
38 ///
39 /// assert_eq_type!(Buf<'static>, &'static [u8]);
40 /// # }
41 /// ```
42 ///
43 /// The following produces a compilation failure because `String` and `str` do
44 /// not refer to the same type:
45 ///
46 /// ```compile_fail
47 /// # #[macro_use] extern crate static_assertions;
48 /// # fn main() {
49 /// assert_eq_type!(String, str);
50 /// # }
51 /// ```
52 #[macro_export(local_inner_macros)]
53 macro_rules! assert_eq_type {
54     ($($xs:tt)+) => { _assert_eq_type!($($xs)+); };
55 }
56 
57 #[doc(hidden)]
58 #[cfg(feature = "nightly")]
59 #[macro_export(local_inner_macros)]
60 macro_rules! _assert_eq_type {
61     ($x:ty, $($xs:ty),+ $(,)*) => {
62         const _: fn() = || { $( {
63             trait TypeEq {
64                 type This: ?Sized;
65             }
66             impl<T: ?Sized> TypeEq for T {
67                 type This = Self;
68             }
69             fn assert_eq_type<T: ?Sized, U: ?Sized>() where T: TypeEq<This = U> {}
70             assert_eq_type::<$x, $xs>();
71         } )+ };
72     };
73 }
74 
75 #[doc(hidden)]
76 #[cfg(not(feature = "nightly"))]
77 #[macro_export(local_inner_macros)]
78 macro_rules! _assert_eq_type {
79     ($x:ty, $($xs:ty),+ $(,)*) => { $( {
80         trait TypeEq {
81             type This: ?Sized;
82         }
83         impl<T: ?Sized> TypeEq for T {
84             type This = Self;
85         }
86         fn assert_eq_type<T: ?Sized, U: ?Sized>() where T: TypeEq<This = U> {}
87         assert_eq_type::<$x, $xs>();
88     } )+ };
89     ($label:ident; $($xs:tt)+) => {
90         #[allow(dead_code, non_snake_case)]
91         fn $label() { assert_eq_type!($($xs)+); }
92     };
93 }
94