xref: /openbmc/qemu/rust/qemu-api/src/zeroable.rs (revision bb42965d)
16e50bde1SPaolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later
26e50bde1SPaolo Bonzini 
3*bb42965dSPaolo Bonzini use std::ptr;
4*bb42965dSPaolo Bonzini 
56e50bde1SPaolo Bonzini /// Encapsulates the requirement that
6*bb42965dSPaolo Bonzini /// `MaybeUninit::<Self>::zeroed().assume_init()` does not cause undefined
7*bb42965dSPaolo Bonzini /// behavior.  This trait in principle could be implemented as just:
8*bb42965dSPaolo Bonzini ///
9*bb42965dSPaolo Bonzini /// ```
10*bb42965dSPaolo Bonzini ///     const ZERO: Self = unsafe {
11*bb42965dSPaolo Bonzini ///         ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init()
12*bb42965dSPaolo Bonzini ///     },
13*bb42965dSPaolo Bonzini /// ```
14*bb42965dSPaolo Bonzini ///
15*bb42965dSPaolo Bonzini /// The need for a manual implementation is only because `zeroed()` cannot
16*bb42965dSPaolo Bonzini /// be used as a `const fn` prior to Rust 1.75.0. Once we can assume a new
17*bb42965dSPaolo Bonzini /// enough version of the compiler, we could provide a `#[derive(Zeroable)]`
18*bb42965dSPaolo Bonzini /// macro to check at compile-time that all struct fields are Zeroable, and
19*bb42965dSPaolo Bonzini /// use the above blanket implementation of the `ZERO` constant.
206e50bde1SPaolo Bonzini ///
216e50bde1SPaolo Bonzini /// # Safety
226e50bde1SPaolo Bonzini ///
23*bb42965dSPaolo Bonzini /// Because the implementation of `ZERO` is manual, it does not make
24*bb42965dSPaolo Bonzini /// any assumption on the safety of `zeroed()`.  However, other users of the
25*bb42965dSPaolo Bonzini /// trait could use it that way.  Do not add this trait to a type unless
26*bb42965dSPaolo Bonzini /// all-zeroes is a valid value for the type.  In particular, remember that
27*bb42965dSPaolo Bonzini /// raw pointers can be zero, but references and `NonNull<T>` cannot
286e50bde1SPaolo Bonzini pub unsafe trait Zeroable: Default {
29*bb42965dSPaolo Bonzini     const ZERO: Self;
306e50bde1SPaolo Bonzini }
316e50bde1SPaolo Bonzini 
32*bb42965dSPaolo Bonzini unsafe impl Zeroable for crate::bindings::Property__bindgen_ty_1 {
33*bb42965dSPaolo Bonzini     const ZERO: Self = Self { i: 0 };
34*bb42965dSPaolo Bonzini }
35*bb42965dSPaolo Bonzini 
36*bb42965dSPaolo Bonzini unsafe impl Zeroable for crate::bindings::Property {
37*bb42965dSPaolo Bonzini     const ZERO: Self = Self {
38*bb42965dSPaolo Bonzini         name: ptr::null(),
39*bb42965dSPaolo Bonzini         info: ptr::null(),
40*bb42965dSPaolo Bonzini         offset: 0,
41*bb42965dSPaolo Bonzini         bitnr: 0,
42*bb42965dSPaolo Bonzini         bitmask: 0,
43*bb42965dSPaolo Bonzini         set_default: false,
44*bb42965dSPaolo Bonzini         defval: Zeroable::ZERO,
45*bb42965dSPaolo Bonzini         arrayoffset: 0,
46*bb42965dSPaolo Bonzini         arrayinfo: ptr::null(),
47*bb42965dSPaolo Bonzini         arrayfieldsize: 0,
48*bb42965dSPaolo Bonzini         link_type: ptr::null(),
49*bb42965dSPaolo Bonzini     };
50*bb42965dSPaolo Bonzini }
51*bb42965dSPaolo Bonzini 
52*bb42965dSPaolo Bonzini unsafe impl Zeroable for crate::bindings::VMStateDescription {
53*bb42965dSPaolo Bonzini     const ZERO: Self = Self {
54*bb42965dSPaolo Bonzini         name: ptr::null(),
55*bb42965dSPaolo Bonzini         unmigratable: false,
56*bb42965dSPaolo Bonzini         early_setup: false,
57*bb42965dSPaolo Bonzini         version_id: 0,
58*bb42965dSPaolo Bonzini         minimum_version_id: 0,
59*bb42965dSPaolo Bonzini         priority: crate::bindings::MigrationPriority::MIG_PRI_DEFAULT,
60*bb42965dSPaolo Bonzini         pre_load: None,
61*bb42965dSPaolo Bonzini         post_load: None,
62*bb42965dSPaolo Bonzini         pre_save: None,
63*bb42965dSPaolo Bonzini         post_save: None,
64*bb42965dSPaolo Bonzini         needed: None,
65*bb42965dSPaolo Bonzini         dev_unplug_pending: None,
66*bb42965dSPaolo Bonzini         fields: ptr::null(),
67*bb42965dSPaolo Bonzini         subsections: ptr::null(),
68*bb42965dSPaolo Bonzini     };
69*bb42965dSPaolo Bonzini }
70*bb42965dSPaolo Bonzini 
71*bb42965dSPaolo Bonzini unsafe impl Zeroable for crate::bindings::MemoryRegionOps__bindgen_ty_1 {
72*bb42965dSPaolo Bonzini     const ZERO: Self = Self {
73*bb42965dSPaolo Bonzini         min_access_size: 0,
74*bb42965dSPaolo Bonzini         max_access_size: 0,
75*bb42965dSPaolo Bonzini         unaligned: false,
76*bb42965dSPaolo Bonzini         accepts: None,
77*bb42965dSPaolo Bonzini     };
78*bb42965dSPaolo Bonzini }
79*bb42965dSPaolo Bonzini 
80*bb42965dSPaolo Bonzini unsafe impl Zeroable for crate::bindings::MemoryRegionOps__bindgen_ty_2 {
81*bb42965dSPaolo Bonzini     const ZERO: Self = Self {
82*bb42965dSPaolo Bonzini         min_access_size: 0,
83*bb42965dSPaolo Bonzini         max_access_size: 0,
84*bb42965dSPaolo Bonzini         unaligned: false,
85*bb42965dSPaolo Bonzini     };
86*bb42965dSPaolo Bonzini }
87