Skip to content

Commit 1fa5167

Browse files
committed
rust: pin-init: add code blocks to [try_][pin_]init! macros
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`"); }, }) Tested-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Tested-by: Danilo Krummrich <dakr@kernel.org> Reviewed-by: Danilo Krummrich <dakr@kernel.org> Signed-off-by: Benno Lossin <lossin@kernel.org>
1 parent 619db96 commit 1fa5167

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

rust/pin-init/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,8 @@ macro_rules! stack_try_pin_init {
740740
/// As already mentioned in the examples above, inside of `pin_init!` a `struct` initializer with
741741
/// the following modifications is expected:
742742
/// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
743+
/// - You can use `_: { /* run any user-code here */ },` anywhere where you can place fields in
744+
/// order to run arbitrary code.
743745
/// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]
744746
/// pointer named `this` inside of the initializer.
745747
/// - Using struct update syntax one can place `..Zeroable::init_zeroed()` at the very end of the

rust/pin-init/src/macros.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,21 @@ macro_rules! __init_internal {
12631263
// have been initialized. Therefore we can now dismiss the guards by forgetting them.
12641264
$(::core::mem::forget($guards);)*
12651265
};
1266+
(init_slot($($use_data:ident)?):
1267+
@data($data:ident),
1268+
@slot($slot:ident),
1269+
@guards($($guards:ident,)*),
1270+
// arbitrary code block
1271+
@munch_fields(_: { $($code:tt)* }, $($rest:tt)*),
1272+
) => {
1273+
{ $($code)* }
1274+
$crate::__init_internal!(init_slot($($use_data)?):
1275+
@data($data),
1276+
@slot($slot),
1277+
@guards($($guards,)*),
1278+
@munch_fields($($rest)*),
1279+
);
1280+
};
12661281
(init_slot($use_data:ident): // `use_data` is present, so we use the `data` to init fields.
12671282
@data($data:ident),
12681283
@slot($slot:ident),
@@ -1358,6 +1373,20 @@ macro_rules! __init_internal {
13581373
);
13591374
}
13601375
};
1376+
(make_initializer:
1377+
@slot($slot:ident),
1378+
@type_name($t:path),
1379+
@munch_fields(_: { $($code:tt)* }, $($rest:tt)*),
1380+
@acc($($acc:tt)*),
1381+
) => {
1382+
// code blocks are ignored for the initializer check
1383+
$crate::__init_internal!(make_initializer:
1384+
@slot($slot),
1385+
@type_name($t),
1386+
@munch_fields($($rest)*),
1387+
@acc($($acc)*),
1388+
);
1389+
};
13611390
(make_initializer:
13621391
@slot($slot:ident),
13631392
@type_name($t:path),

0 commit comments

Comments
 (0)