diff options
author | Benno Lossin <benno.lossin@proton.me> | 2023-08-14 08:47:10 +0000 |
---|---|---|
committer | Miguel Ojeda <ojeda@kernel.org> | 2023-08-21 14:31:48 +0200 |
commit | 35e7fca2ff59d9d8f036aba3dcf5c34beb79fdb8 (patch) | |
tree | fb976465a2dd8e52d3017e10e885e3dc1f976ded /rust/kernel/init.rs | |
parent | 92fd540d62701115b22b1f531c8c86454809931b (diff) | |
download | lwn-35e7fca2ff59d9d8f036aba3dcf5c34beb79fdb8.tar.gz lwn-35e7fca2ff59d9d8f036aba3dcf5c34beb79fdb8.zip |
rust: init: add `..Zeroable::zeroed()` syntax for zeroing all missing fields
Add the struct update syntax to the init macros, but only for
`..Zeroable::zeroed()`. Adding this at the end of the struct initializer
allows one to omit fields from the initializer, these fields will be
initialized with 0x00 set to every byte. Only types that implement the
`Zeroable` trait can utilize this.
Suggested-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20230814084602.25699-8-benno.lossin@proton.me
[ Rebased on `rust-next` and cleaned a few trivial nits. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/kernel/init.rs')
-rw-r--r-- | rust/kernel/init.rs | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/rust/kernel/init.rs b/rust/kernel/init.rs index ecf6a4bd0ce4..33f2666d5bae 100644 --- a/rust/kernel/init.rs +++ b/rust/kernel/init.rs @@ -508,14 +508,18 @@ macro_rules! stack_try_pin_init { /// - Fields that you want to initialize in-place have to use `<-` instead of `:`. /// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`] /// pointer named `this` inside of the initializer. +/// - Using struct update syntax one can place `..Zeroable::zeroed()` at the very end of the +/// struct, this initializes every field with 0 and then runs all initializers specified in the +/// body. This can only be done if [`Zeroable`] is implemented for the struct. /// /// For instance: /// /// ```rust /// # use kernel::pin_init; -/// # use macros::pin_data; +/// # use macros::{Zeroable, pin_data}; /// # use core::{ptr::addr_of_mut, marker::PhantomPinned}; /// #[pin_data] +/// #[derive(Zeroable)] /// struct Buf { /// // `ptr` points into `buf`. /// ptr: *mut u8, @@ -528,6 +532,10 @@ macro_rules! stack_try_pin_init { /// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() }, /// pin: PhantomPinned, /// }); +/// pin_init!(Buf { +/// buf: [1; 64], +/// ..Zeroable::zeroed() +/// }); /// ``` /// /// [`try_pin_init!`]: kernel::try_pin_init @@ -547,6 +555,7 @@ macro_rules! pin_init { @data(PinData, use_data), @has_data(HasPinData, __pin_data), @construct_closure(pin_init_from_closure), + @munch_fields($($fields)*), ) }; } @@ -603,6 +612,7 @@ macro_rules! try_pin_init { @data(PinData, use_data), @has_data(HasPinData, __pin_data), @construct_closure(pin_init_from_closure), + @munch_fields($($fields)*), ) }; ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { @@ -616,6 +626,7 @@ macro_rules! try_pin_init { @data(PinData, use_data), @has_data(HasPinData, __pin_data), @construct_closure(pin_init_from_closure), + @munch_fields($($fields)*), ) }; } @@ -650,6 +661,7 @@ macro_rules! init { @data(InitData, /*no use_data*/), @has_data(HasInitData, __init_data), @construct_closure(init_from_closure), + @munch_fields($($fields)*), ) } } @@ -700,6 +712,7 @@ macro_rules! try_init { @data(InitData, /*no use_data*/), @has_data(HasInitData, __init_data), @construct_closure(init_from_closure), + @munch_fields($($fields)*), ) }; ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { @@ -713,6 +726,7 @@ macro_rules! try_init { @data(InitData, /*no use_data*/), @has_data(HasInitData, __init_data), @construct_closure(init_from_closure), + @munch_fields($($fields)*), ) }; } |