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