|  | // SPDX-License-Identifier: GPL-2.0-or-later | 
|  |  | 
|  | /// Encapsulates the requirement that | 
|  | /// `MaybeUninit::<Self>::zeroed().assume_init()` does not cause undefined | 
|  | /// behavior.  This trait in principle could be implemented as just: | 
|  | /// | 
|  | /// ``` | 
|  | /// pub unsafe trait Zeroable { | 
|  | ///     const ZERO: Self = unsafe { ::core::mem::MaybeUninit::<Self>::zeroed().assume_init() }; | 
|  | /// } | 
|  | /// ``` | 
|  | /// | 
|  | /// The need for a manual implementation is only because `zeroed()` cannot | 
|  | /// be used as a `const fn` prior to Rust 1.75.0. Once we can assume a new | 
|  | /// enough version of the compiler, we could provide a `#[derive(Zeroable)]` | 
|  | /// macro to check at compile-time that all struct fields are Zeroable, and | 
|  | /// use the above blanket implementation of the `ZERO` constant. | 
|  | /// | 
|  | /// # Safety | 
|  | /// | 
|  | /// Because the implementation of `ZERO` is manual, it does not make | 
|  | /// any assumption on the safety of `zeroed()`.  However, other users of the | 
|  | /// trait could use it that way.  Do not add this trait to a type unless | 
|  | /// all-zeroes is a valid value for the type.  In particular, remember that | 
|  | /// raw pointers can be zero, but references and `NonNull<T>` cannot | 
|  | pub unsafe trait Zeroable: Default { | 
|  | const ZERO: Self; | 
|  | } | 
|  |  | 
|  | /// A macro that acts similarly to [`core::mem::zeroed()`], only is const | 
|  | /// | 
|  | /// ## Safety | 
|  | /// | 
|  | /// Similar to `core::mem::zeroed()`, except this zeroes padding bits. Zeroed | 
|  | /// padding usually isn't relevant to safety, but might be if a C union is used. | 
|  | /// | 
|  | /// Just like for `core::mem::zeroed()`, an all zero byte pattern might not | 
|  | /// be a valid value for a type, as is the case for references `&T` and `&mut | 
|  | /// T`. Reference types trigger a (denied by default) lint and cause immediate | 
|  | /// undefined behavior if the lint is ignored | 
|  | /// | 
|  | /// ```rust compile_fail | 
|  | /// use const_zero::const_zero; | 
|  | /// // error: any use of this value will cause an error | 
|  | /// // note: `#[deny(const_err)]` on by default | 
|  | /// const STR: &str = unsafe{const_zero!(&'static str)}; | 
|  | /// ``` | 
|  | /// | 
|  | /// `const_zero` does not work on unsized types: | 
|  | /// | 
|  | /// ```rust compile_fail | 
|  | /// use const_zero::const_zero; | 
|  | /// // error[E0277]: the size for values of type `[u8]` cannot be known at compilation time | 
|  | /// const BYTES: [u8] = unsafe{const_zero!([u8])}; | 
|  | /// ``` | 
|  | /// ## Differences with `core::mem::zeroed` | 
|  | /// | 
|  | /// `const_zero` zeroes padding bits, while `core::mem::zeroed` doesn't | 
|  | macro_rules! const_zero { | 
|  | // This macro to produce a type-generic zero constant is taken from the | 
|  | // const_zero crate (v0.1.1): | 
|  | // | 
|  | //     https://docs.rs/const-zero/latest/src/const_zero/lib.rs.html | 
|  | // | 
|  | // and used under MIT license | 
|  | ($type_:ty) => {{ | 
|  | const TYPE_SIZE: ::core::primitive::usize = ::core::mem::size_of::<$type_>(); | 
|  | union TypeAsBytes { | 
|  | bytes: [::core::primitive::u8; TYPE_SIZE], | 
|  | inner: ::core::mem::ManuallyDrop<$type_>, | 
|  | } | 
|  | const ZERO_BYTES: TypeAsBytes = TypeAsBytes { | 
|  | bytes: [0; TYPE_SIZE], | 
|  | }; | 
|  | ::core::mem::ManuallyDrop::<$type_>::into_inner(ZERO_BYTES.inner) | 
|  | }}; | 
|  | } | 
|  |  | 
|  | /// A wrapper to implement the `Zeroable` trait through the `const_zero` macro. | 
|  | macro_rules! impl_zeroable { | 
|  | ($type:ty) => { | 
|  | unsafe impl Zeroable for $type { | 
|  | const ZERO: Self = unsafe { const_zero!($type) }; | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | // bindgen does not derive Default here | 
|  | #[allow(clippy::derivable_impls)] | 
|  | impl Default for crate::bindings::VMStateFlags { | 
|  | fn default() -> Self { | 
|  | Self(0) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl_zeroable!(crate::bindings::Property__bindgen_ty_1); | 
|  | impl_zeroable!(crate::bindings::Property); | 
|  | impl_zeroable!(crate::bindings::VMStateFlags); | 
|  | impl_zeroable!(crate::bindings::VMStateField); | 
|  | impl_zeroable!(crate::bindings::VMStateDescription); | 
|  | impl_zeroable!(crate::bindings::MemoryRegionOps__bindgen_ty_1); | 
|  | impl_zeroable!(crate::bindings::MemoryRegionOps__bindgen_ty_2); |