// Copyright 2024, Red Hat Inc. // Author(s): Paolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later //! This module provides macros to check the equality of types and //! the type of `struct` fields. This can be useful to ensure that //! types match the expectations of C code. // Based on https://stackoverflow.com/questions/64251852/x/70978292#70978292 // (stackoverflow answers are released under MIT license). #[doc(hidden)] pub trait EqType { type Itself; } impl EqType for T { type Itself = T; } /// Assert that two types are the same. /// /// # Examples /// /// ``` /// # use qemu_api::assert_same_type; /// # use std::ops::Deref; /// assert_same_type!(u32, u32); /// assert_same_type!( as Deref>::Target, u32); /// ``` /// /// Different types will cause a compile failure /// /// ```compile_fail /// # use qemu_api::assert_same_type; /// assert_same_type!(&Box, &u32); /// ``` #[macro_export] macro_rules! assert_same_type { ($t1:ty, $t2:ty) => { const _: () = { #[allow(unused)] fn assert_same_type(v: $t1) { fn types_must_be_equal(_: T) where T: $crate::assertions::EqType, { } types_must_be_equal::<_, $t2>(v); } }; }; } /// Assert that a field of a struct has the given type. /// /// # Examples /// /// ``` /// # use qemu_api::assert_field_type; /// pub struct A { /// field1: u32, /// } /// /// assert_field_type!(A, field1, u32); /// ``` /// /// Different types will cause a compile failure /// /// ```compile_fail /// # use qemu_api::assert_field_type; /// # pub struct A { field1: u32 } /// assert_field_type!(A, field1, i32); /// ``` #[macro_export] macro_rules! assert_field_type { ($t:ty, $i:tt, $ti:ty) => { const _: () = { #[allow(unused)] fn assert_field_type(v: $t) { fn types_must_be_equal(_: T) where T: $crate::assertions::EqType, { } types_must_be_equal::<_, $ti>(v.$i); } }; }; }