1 /// Asserts that types are equal in size. 2 /// 3 /// When performing operations such as pointer casts or dealing with [`usize`] 4 /// versus [`u64`] versus [`u32`], the size of your types matter. That is where 5 /// this macro comes into play. 6 /// 7 /// # Alternatives 8 /// 9 /// There also exists [`assert_size_eq_val`](macro.assert_size_eq_val.html) and 10 /// [`assert_size_eq_ptr`](macro.assert_size_eq_ptr.html). Instead of specifying 11 /// types to compare, values' sizes can be directly compared against each other. 12 /// 13 /// # Examples 14 /// 15 /// These three types, despite being very different, all have the same size: 16 /// 17 /// ``` 18 /// # #[macro_use] extern crate static_assertions; fn main() {} 19 /// assert_size_eq!([u8; 4], (u16, u16), u32); 20 /// ``` 21 /// 22 /// The following example fails to compile because `u32` has 4 times the size of 23 /// `u8`: 24 /// 25 /// ```compile_fail 26 /// # #[macro_use] extern crate static_assertions; fn main() {} 27 /// assert_size_eq!(u32, u8); 28 /// ``` 29 /// 30 /// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html 31 /// [`u64`]: https://doc.rust-lang.org/std/primitive.u64.html 32 /// [`u32`]: https://doc.rust-lang.org/std/primitive.u32.html 33 #[macro_export] 34 macro_rules! assert_size_eq { 35 ($x:ty, $($xs:ty),+ $(,)?) => { 36 const _: fn() = || { 37 $(let _ = $crate::_core::mem::transmute::<$x, $xs>;)+ 38 }; 39 }; 40 } 41 42 /// Asserts that types are equal in alignment. 43 /// 44 /// This macro has been deprecated in favor of 45 /// [`assert_size_eq!`](macro.assert_size_eq.html). 46 #[deprecated( 47 since = "1.2.0", 48 note = "Please use the 'assert_size_eq' macro instead" 49 )] 50 #[macro_export(local_inner_macros)] 51 macro_rules! assert_eq_size { 52 ($($t:tt)*) => { 53 assert_size_eq!($($t)*); 54 }; 55 } 56 57 /// Asserts that values pointed to are equal in size. 58 /// 59 /// # Examples 60 /// 61 /// This especially is useful for when coercing pointers between different types 62 /// and ensuring the underlying values are the same size. 63 /// 64 /// ``` 65 /// # #[macro_use] extern crate static_assertions; fn main() {} 66 /// fn operation(x: &(u32, u32), y: &[u16; 4]) { 67 /// assert_size_eq_ptr!(x, y); 68 /// // ... 69 /// } 70 /// ``` 71 /// 72 /// The following example fails to compile because byte arrays of different 73 /// lengths have different sizes: 74 /// 75 /// ```compile_fail 76 /// # #[macro_use] extern crate static_assertions; 77 /// # fn main() { 78 /// static BYTES: &[u8; 4] = &[ 79 /// /* ... */ 80 /// # 0; 4 81 /// ]; 82 /// 83 /// static TABLE: &[u8; 16] = &[ 84 /// /* ... */ 85 /// # 0; 16 86 /// ]; 87 /// 88 /// assert_size_eq_ptr!(BYTES, TABLE); 89 /// ``` 90 #[macro_export] 91 macro_rules! assert_size_eq_ptr { 92 ($x:expr, $($xs:expr),+ $(,)?) => { 93 #[allow(unknown_lints, unsafe_code, forget_copy, useless_transmute)] 94 let _ = || unsafe { 95 use $crate::_core::{mem, ptr}; 96 let mut copy = ptr::read($x); 97 $(ptr::write(&mut copy, mem::transmute(ptr::read($xs)));)+ 98 mem::forget(copy); 99 }; 100 } 101 } 102 103 /// Asserts that values pointed to are equal in size. 104 /// 105 /// This macro has been deprecated in favor of 106 /// [`assert_size_eq_ptr!`](macro.assert_size_eq_ptr.html). 107 #[deprecated( 108 since = "1.2.0", 109 note = "Please use the 'assert_size_eq_ptr' macro instead" 110 )] 111 #[macro_export(local_inner_macros)] 112 macro_rules! assert_eq_size_ptr { 113 ($($t:tt)*) => { 114 assert_size_eq_ptr!($($t)*); 115 }; 116 } 117 118 /// Asserts that values are equal in size. 119 /// 120 /// This macro doesn't consume its arguments and thus works for 121 /// non-[`Clone`]able values. 122 /// 123 /// # Examples 124 /// 125 /// ``` 126 /// # #[macro_use] extern crate static_assertions; 127 /// # fn main() { 128 /// struct Byte(u8); 129 /// 130 /// let x = 10u8; 131 /// let y = Byte(42); // Works for non-cloneable types 132 /// 133 /// assert_size_eq_val!(x, y); 134 /// assert_size_eq_val!(x, y, 0u8); 135 /// # } 136 /// ``` 137 /// 138 /// Even though both values are 0, they are of types with different sizes: 139 /// 140 /// ```compile_fail 141 /// # #[macro_use] extern crate static_assertions; 142 /// # fn main() { 143 /// assert_size_eq_val!(0u8, 0u32); 144 /// # } 145 /// ``` 146 /// 147 /// [`Clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html 148 #[macro_export(local_inner_macros)] 149 macro_rules! assert_size_eq_val { 150 ($x:expr, $($xs:expr),+ $(,)?) => { 151 assert_size_eq_ptr!(&$x, $(&$xs),+); 152 } 153 } 154 155 /// Asserts that values pointed to are equal in size. 156 /// 157 /// This macro has been deprecated in favor of 158 /// [`assert_size_eq_val!`](macro.assert_size_eq_val.html). 159 #[deprecated( 160 since = "1.2.0", 161 note = "Please use the 'assert_size_eq_val' macro instead" 162 )] 163 #[macro_export(local_inner_macros)] 164 macro_rules! assert_eq_size_val { 165 ($($t:tt)*) => { 166 assert_size_eq_val!($($t)*); 167 }; 168 } 169