macro_rules! try_pin_init {
    ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
        $($fields:tt)*
    }) => { ... };
    ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
        $($fields:tt)*
    }? $err:ty) => { ... };
    (
        @this($($this:ident)?),
        @typ($t:ident $(::<$($generics:ty),*>)?),
        @fields($($fields:tt)*),
        @error($err:ty),
    ) => { ... };
    (init_slot:
        @data($data:ident),
        @slot($slot:ident),
        @munch_fields($(,)?),
    ) => { ... };
    (init_slot:
        @data($data:ident),
        @slot($slot:ident),
        // In-place initialization syntax.
        @munch_fields($field:ident <- $val:expr, $($rest:tt)*),
    ) => { ... };
    (init_slot:
        @data($data:ident),
        @slot($slot:ident),
        // Direct value init, this is safe for every field.
        @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*),
    ) => { ... };
    (make_initializer:
        @slot($slot:ident),
        @type_name($t:ident),
        @munch_fields($(,)?),
        @acc($($acc:tt)*),
    ) => { ... };
    (make_initializer:
        @slot($slot:ident),
        @type_name($t:ident),
        @munch_fields($field:ident <- $val:expr, $($rest:tt)*),
        @acc($($acc:tt)*),
    ) => { ... };
    (make_initializer:
        @slot($slot:ident),
        @type_name($t:ident),
        @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*),
        @acc($($acc:tt)*),
    ) => { ... };
    (forget_guards:
        @munch_fields($(,)?),
    ) => { ... };
    (forget_guards:
        @munch_fields($field:ident <- $val:expr, $($rest:tt)*),
    ) => { ... };
    (forget_guards:
        @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*),
    ) => { ... };
}
Expand description

Construct an in-place, fallible pinned initializer for structs.

If the initialization can complete without error (or Infallible), then use pin_init!.

You can use the ? operator or use return Err(err) inside the initializer to stop initialization and return the error.

IMPORTANT: if you have unsafe code inside of the initializer you have to ensure that when initialization fails, the memory can be safely deallocated without any further modifications.

This macro defaults the error to Error.

The syntax is identical to pin_init! with the following exception: you can append ? $type after the struct initializer to specify the error type you want to use.

Examples

use kernel::{init::{self, PinInit}, error::Error};
#[pin_data]
struct BigBuf {
    big: Box<[u8; 1024 * 1024 * 1024]>,
    small: [u8; 1024 * 1024],
    ptr: *mut u8,
}

impl BigBuf {
    fn new() -> impl PinInit<Self, Error> {
        try_pin_init!(Self {
            big: Box::init(init::zeroed())?,
            small: [0; 1024 * 1024],
            ptr: core::ptr::null_mut(),
        }? Error)
    }
}