[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250910232133.37ce4fb0.gary@garyguo.net>
Date: Wed, 10 Sep 2025 23:21:33 +0100
From: Gary Guo <gary@...yguo.net>
To: Benno Lossin <lossin@...nel.org>
Cc: Miguel Ojeda <ojeda@...nel.org>, Alex Gaynor <alex.gaynor@...il.com>,
Boqun Feng <boqun.feng@...il.com>, Björn Roy Baron
<bjorn3_gh@...tonmail.com>, Andreas Hindborg <a.hindborg@...nel.org>, Alice
Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>, Danilo
Krummrich <dakr@...nel.org>, Fiona Behrens <me@...enk.dev>, Christian
Schrefl <chrisi.schrefl@...il.com>, Alban Kurti <kurti@...icto.ai>,
rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] rust: pin-init: add code blocks to `[try_][pin_]init!`
macros
On Fri, 5 Sep 2025 16:05:31 +0200
Benno Lossin <lossin@...nel.org> wrote:
> Allow writing `_: { /* any number of statements */ }` in initializers to
> run arbitrary code during initialization.
>
> try_init!(MyStruct {
> _: {
> if check_something() {
> return Err(MyError);
> }
> },
> foo: Foo::new(val),
> _: {
> println!("successfully initialized `MyStruct`");
> },
> })
>
> Link: https://github.com/Rust-for-Linux/pin-init/pull/84/commits/2880a9b898336e2d54f80715f00ce00f21f74d2f
> Signed-off-by: Benno Lossin <lossin@...nel.org>
Reviewed-by: Gary Guo <gary@...yguo.net>
> ---
> I originally wanted to do some more modifications to the syntax of
> initializer macros, but I didn't have the time this cycle. See
>
> https://github.com/Rust-for-Linux/pin-init/pull/69
>
> For the development of that syntax, it's probably going to be like a
> closure where in order to support formatting via rustfmt. But it still
> needs some disucssion around removing `<-`.
>
> That change would allow having a `let` that binds a value for use in the
> initializer. IIRC @Alice, you needed that for something.
> ---
> rust/pin-init/src/lib.rs | 2 ++
> rust/pin-init/src/macros.rs | 29 +++++++++++++++++++++++++++++
> 2 files changed, 31 insertions(+)
>
> diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs
> index 62e013a5cc20..8b556b0e106a 100644
> --- a/rust/pin-init/src/lib.rs
> +++ b/rust/pin-init/src/lib.rs
> @@ -740,6 +740,8 @@ macro_rules! stack_try_pin_init {
> /// As already mentioned in the examples above, inside of `pin_init!` a `struct` initializer with
> /// the following modifications is expected:
> /// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
> +/// - You can use `_: { /* run any user-code here */ },` anywhere where you can place fields in
> +/// order to run arbitrary code.
> /// - 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::init_zeroed()` at the very end of the
> diff --git a/rust/pin-init/src/macros.rs b/rust/pin-init/src/macros.rs
> index 9ced630737b8..752e77db998c 100644
> --- a/rust/pin-init/src/macros.rs
> +++ b/rust/pin-init/src/macros.rs
> @@ -1202,6 +1202,21 @@ fn assert_zeroable<T: $crate::Zeroable>(_: *mut T) {}
> // have been initialized. Therefore we can now dismiss the guards by forgetting them.
> $(::core::mem::forget($guards);)*
> };
> + (init_slot($($use_data:ident)?):
> + @data($data:ident),
> + @slot($slot:ident),
> + @guards($($guards:ident,)*),
> + // arbitrary code block
> + @munch_fields(_: { $($code:tt)* }, $($rest:tt)*),
> + ) => {
> + { $($code)* }
> + $crate::__init_internal!(init_slot($($use_data)?):
> + @data($data),
> + @slot($slot),
> + @guards($($guards,)*),
> + @munch_fields($($rest)*),
> + );
> + };
> (init_slot($use_data:ident): // `use_data` is present, so we use the `data` to init fields.
> @data($data:ident),
> @slot($slot:ident),
> @@ -1351,6 +1366,20 @@ fn assert_zeroable<T: $crate::Zeroable>(_: *mut T) {}
> );
> }
> };
> + (make_initializer:
> + @slot($slot:ident),
> + @type_name($t:path),
> + @munch_fields(_: { $($code:tt)* }, $($rest:tt)*),
> + @acc($($acc:tt)*),
> + ) => {
> + // code blocks are ignored for the initializer check
> + $crate::__init_internal!(make_initializer:
> + @slot($slot),
> + @type_name($t),
> + @munch_fields($($rest)*),
> + @acc($($acc)*),
> + );
> + };
> (make_initializer:
> @slot($slot:ident),
> @type_name($t:path),
>
> base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
Powered by blists - more mailing lists