1 // Copyright 2024, Red Hat Inc. 2 // Author(s): Paolo Bonzini <pbonzini@redhat.com> 3 // SPDX-License-Identifier: GPL-2.0-or-later 4 5 //! This module provides macros to check the equality of types and 6 //! the type of `struct` fields. This can be useful to ensure that 7 //! types match the expectations of C code. 8 9 // Based on https://stackoverflow.com/questions/64251852/x/70978292#70978292 10 // (stackoverflow answers are released under MIT license). 11 12 #[doc(hidden)] 13 pub trait EqType { 14 type Itself; 15 } 16 17 impl<T> EqType for T { 18 type Itself = T; 19 } 20 21 /// Assert that two types are the same. 22 /// 23 /// # Examples 24 /// 25 /// ``` 26 /// # use qemu_api::assert_same_type; 27 /// # use std::ops::Deref; 28 /// assert_same_type!(u32, u32); 29 /// assert_same_type!(<Box<u32> as Deref>::Target, u32); 30 /// ``` 31 /// 32 /// Different types will cause a compile failure 33 /// 34 /// ```compile_fail 35 /// # use qemu_api::assert_same_type; 36 /// assert_same_type!(&Box<u32>, &u32); 37 /// ``` 38 #[macro_export] 39 macro_rules! assert_same_type { 40 ($t1:ty, $t2:ty) => { 41 const _: () = { 42 #[allow(unused)] 43 fn assert_same_type(v: $t1) { 44 fn types_must_be_equal<T, U>(_: T) 45 where 46 T: $crate::assertions::EqType<Itself = U>, 47 { 48 } 49 types_must_be_equal::<_, $t2>(v); 50 } 51 }; 52 }; 53 } 54 55 /// Assert that a field of a struct has the given type. 56 /// 57 /// # Examples 58 /// 59 /// ``` 60 /// # use qemu_api::assert_field_type; 61 /// pub struct A { 62 /// field1: u32, 63 /// } 64 /// 65 /// assert_field_type!(A, field1, u32); 66 /// ``` 67 /// 68 /// Different types will cause a compile failure 69 /// 70 /// ```compile_fail 71 /// # use qemu_api::assert_field_type; 72 /// # pub struct A { field1: u32 } 73 /// assert_field_type!(A, field1, i32); 74 /// ``` 75 #[macro_export] 76 macro_rules! assert_field_type { 77 ($t:ty, $i:tt, $ti:ty) => { 78 const _: () = { 79 #[allow(unused)] 80 fn assert_field_type(v: $t) { 81 fn types_must_be_equal<T, U>(_: T) 82 where 83 T: $crate::assertions::EqType<Itself = U>, 84 { 85 } 86 types_must_be_equal::<_, $ti>(v.$i); 87 } 88 }; 89 }; 90 } 91