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