1 // SPDX-License-Identifier: GPL-2.0-or-later 2 3 use std::ptr; 4 5 /// Encapsulates the requirement that 6 /// `MaybeUninit::<Self>::zeroed().assume_init()` does not cause undefined 7 /// behavior. This trait in principle could be implemented as just: 8 /// 9 /// ``` 10 /// pub unsafe trait Zeroable: Default { 11 /// const ZERO: Self = unsafe { ::core::mem::MaybeUninit::<Self>::zeroed().assume_init() }; 12 /// } 13 /// ``` 14 /// 15 /// The need for a manual implementation is only because `zeroed()` cannot 16 /// be used as a `const fn` prior to Rust 1.75.0. Once we can assume a new 17 /// enough version of the compiler, we could provide a `#[derive(Zeroable)]` 18 /// macro to check at compile-time that all struct fields are Zeroable, and 19 /// use the above blanket implementation of the `ZERO` constant. 20 /// 21 /// # Safety 22 /// 23 /// Because the implementation of `ZERO` is manual, it does not make 24 /// any assumption on the safety of `zeroed()`. However, other users of the 25 /// trait could use it that way. Do not add this trait to a type unless 26 /// all-zeroes is a valid value for the type. In particular, remember that 27 /// raw pointers can be zero, but references and `NonNull<T>` cannot 28 pub unsafe trait Zeroable: Default { 29 const ZERO: Self; 30 } 31 32 unsafe impl Zeroable for crate::bindings::Property__bindgen_ty_1 { 33 const ZERO: Self = Self { i: 0 }; 34 } 35 36 unsafe impl Zeroable for crate::bindings::Property { 37 const ZERO: Self = Self { 38 name: ptr::null(), 39 info: ptr::null(), 40 offset: 0, 41 bitnr: 0, 42 bitmask: 0, 43 set_default: false, 44 defval: Zeroable::ZERO, 45 arrayoffset: 0, 46 arrayinfo: ptr::null(), 47 arrayfieldsize: 0, 48 link_type: ptr::null(), 49 }; 50 } 51 52 // bindgen does not derive Default here 53 #[allow(clippy::derivable_impls)] 54 impl Default for crate::bindings::VMStateFlags { 55 fn default() -> Self { 56 Self(0) 57 } 58 } 59 60 unsafe impl Zeroable for crate::bindings::VMStateFlags { 61 const ZERO: Self = Self(0); 62 } 63 64 unsafe impl Zeroable for crate::bindings::VMStateField { 65 const ZERO: Self = Self { 66 name: ptr::null(), 67 err_hint: ptr::null(), 68 offset: 0, 69 size: 0, 70 start: 0, 71 num: 0, 72 num_offset: 0, 73 size_offset: 0, 74 info: ptr::null(), 75 flags: Zeroable::ZERO, 76 vmsd: ptr::null(), 77 version_id: 0, 78 struct_version_id: 0, 79 field_exists: None, 80 }; 81 } 82 83 unsafe impl Zeroable for crate::bindings::VMStateDescription { 84 const ZERO: Self = Self { 85 name: ptr::null(), 86 unmigratable: false, 87 early_setup: false, 88 version_id: 0, 89 minimum_version_id: 0, 90 priority: crate::bindings::MigrationPriority::MIG_PRI_DEFAULT, 91 pre_load: None, 92 post_load: None, 93 pre_save: None, 94 post_save: None, 95 needed: None, 96 dev_unplug_pending: None, 97 fields: ptr::null(), 98 subsections: ptr::null(), 99 }; 100 } 101 102 unsafe impl Zeroable for crate::bindings::MemoryRegionOps__bindgen_ty_1 { 103 const ZERO: Self = Self { 104 min_access_size: 0, 105 max_access_size: 0, 106 unaligned: false, 107 accepts: None, 108 }; 109 } 110 111 unsafe impl Zeroable for crate::bindings::MemoryRegionOps__bindgen_ty_2 { 112 const ZERO: Self = Self { 113 min_access_size: 0, 114 max_access_size: 0, 115 unaligned: false, 116 }; 117 } 118