summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/pin-init/src/lib.rs2
-rw-r--r--rust/pin-init/src/macros.rs29
2 files changed, 31 insertions, 0 deletions
diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs
index 2d0d9fd12524..dd553212836e 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 668dcee9b7af..c3462080b7b6 100644
--- a/rust/pin-init/src/macros.rs
+++ b/rust/pin-init/src/macros.rs
@@ -1263,6 +1263,21 @@ macro_rules! __init_internal {
// 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),
@@ -1361,6 +1376,20 @@ macro_rules! __init_internal {
(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),
@munch_fields(..Zeroable::init_zeroed() $(,)?),
@acc($($acc:tt)*),
) => {