summaryrefslogtreecommitdiff
path: root/rust/pin-init/src
diff options
context:
space:
mode:
authorBenno Lossin <lossin@kernel.org>2026-01-16 11:54:22 +0100
committerBenno Lossin <lossin@kernel.org>2026-01-17 10:51:42 +0100
commit560f6d13c33f9f06ca34c14dc7c0a045d949c4a0 (patch)
treed6110ab42b4afa5a62ca8e9f14730dd8bf1bebc0 /rust/pin-init/src
parenta92f5fd29257d3bb4c62b81aebca0774e5f5c856 (diff)
rust: pin-init: rewrite `#[pin_data]` using `syn`
Rewrite the attribute macro `#[pin_data]` using `syn`. No functional changes intended aside from improved error messages on syntactic and semantical errors. For example if one forgets a comma at the end of a field: #[pin_data] struct Foo { a: Box<Foo> b: Box<Foo> } The declarative macro reports the following errors: error: expected `,`, or `}`, found `b` --> tests/ui/compile-fail/pin_data/missing_comma.rs:5:16 | 5 | a: Box<Foo> | ^ help: try adding a comma: `,` error: recursion limit reached while expanding `$crate::__pin_data!` --> tests/ui/compile-fail/pin_data/missing_comma.rs:3:1 | 3 | #[pin_data] | ^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`$CRATE`) = note: this error originates in the macro `$crate::__pin_data` which comes from the expansion of the attribute macro `pin_data` (in Nightly builds, run with -Z macro-backtrace for more info) The new `syn` version reports: error: expected `,`, or `}`, found `b` --> tests/ui/compile-fail/pin_data/missing_comma.rs:5:16 | 5 | a: Box<Foo> | ^ help: try adding a comma: `,` error: expected `,` --> tests/ui/compile-fail/pin_data/missing_comma.rs:6:5 | 6 | b: Box<Foo> | ^ Tested-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Gary Guo <gary@garyguo.net> Signed-off-by: Benno Lossin <lossin@kernel.org>
Diffstat (limited to 'rust/pin-init/src')
-rw-r--r--rust/pin-init/src/macros.rs574
1 files changed, 0 insertions, 574 deletions
diff --git a/rust/pin-init/src/macros.rs b/rust/pin-init/src/macros.rs
index b80c95612fd6..eea8adc5c7ad 100644
--- a/rust/pin-init/src/macros.rs
+++ b/rust/pin-init/src/macros.rs
@@ -503,580 +503,6 @@ pub use ::macros::paste;
#[cfg(not(kernel))]
pub use ::paste::paste;
-/// This macro first parses the struct definition such that it separates pinned and not pinned
-/// fields. Afterwards it declares the struct and implement the `PinData` trait safely.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! __pin_data {
- // Proc-macro entry point, this is supplied by the proc-macro pre-parsing.
- (parse_input:
- @args($($pinned_drop:ident)?),
- @sig(
- $(#[$($struct_attr:tt)*])*
- $vis:vis struct $name:ident
- $(where $($whr:tt)*)?
- ),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @body({ $($fields:tt)* }),
- ) => {
- // We now use token munching to iterate through all of the fields. While doing this we
- // identify fields marked with `#[pin]`, these fields are the 'pinned fields'. The user
- // wants these to be structurally pinned. The rest of the fields are the
- // 'not pinned fields'. Additionally we collect all fields, since we need them in the right
- // order to declare the struct.
- //
- // In this call we also put some explaining comments for the parameters.
- $crate::__pin_data!(find_pinned_fields:
- // Attributes on the struct itself, these will just be propagated to be put onto the
- // struct definition.
- @struct_attrs($(#[$($struct_attr)*])*),
- // The visibility of the struct.
- @vis($vis),
- // The name of the struct.
- @name($name),
- // The 'impl generics', the generics that will need to be specified on the struct inside
- // of an `impl<$ty_generics>` block.
- @impl_generics($($impl_generics)*),
- // The 'ty generics', the generics that will need to be specified on the impl blocks.
- @ty_generics($($ty_generics)*),
- // The 'decl generics', the generics that need to be specified on the struct
- // definition.
- @decl_generics($($decl_generics)*),
- // The where clause of any impl block and the declaration.
- @where($($($whr)*)?),
- // The remaining fields tokens that need to be processed.
- // We add a `,` at the end to ensure correct parsing.
- @fields_munch($($fields)* ,),
- // The pinned fields.
- @pinned(),
- // The not pinned fields.
- @not_pinned(),
- // All fields.
- @fields(),
- // The accumulator containing all attributes already parsed.
- @accum(),
- // Contains `yes` or `` to indicate if `#[pin]` was found on the current field.
- @is_pinned(),
- // The proc-macro argument, this should be `PinnedDrop` or ``.
- @pinned_drop($($pinned_drop)?),
- );
- };
- (find_pinned_fields:
- @struct_attrs($($struct_attrs:tt)*),
- @vis($vis:vis),
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @where($($whr:tt)*),
- // We found a PhantomPinned field, this should generally be pinned!
- @fields_munch($field:ident : $($($(::)?core::)?marker::)?PhantomPinned, $($rest:tt)*),
- @pinned($($pinned:tt)*),
- @not_pinned($($not_pinned:tt)*),
- @fields($($fields:tt)*),
- @accum($($accum:tt)*),
- // This field is not pinned.
- @is_pinned(),
- @pinned_drop($($pinned_drop:ident)?),
- ) => {
- ::core::compile_error!(concat!(
- "The field `",
- stringify!($field),
- "` of type `PhantomPinned` only has an effect, if it has the `#[pin]` attribute.",
- ));
- $crate::__pin_data!(find_pinned_fields:
- @struct_attrs($($struct_attrs)*),
- @vis($vis),
- @name($name),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @decl_generics($($decl_generics)*),
- @where($($whr)*),
- @fields_munch($($rest)*),
- @pinned($($pinned)* $($accum)* $field: ::core::marker::PhantomPinned,),
- @not_pinned($($not_pinned)*),
- @fields($($fields)* $($accum)* $field: ::core::marker::PhantomPinned,),
- @accum(),
- @is_pinned(),
- @pinned_drop($($pinned_drop)?),
- );
- };
- (find_pinned_fields:
- @struct_attrs($($struct_attrs:tt)*),
- @vis($vis:vis),
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @where($($whr:tt)*),
- // We reached the field declaration.
- @fields_munch($field:ident : $type:ty, $($rest:tt)*),
- @pinned($($pinned:tt)*),
- @not_pinned($($not_pinned:tt)*),
- @fields($($fields:tt)*),
- @accum($($accum:tt)*),
- // This field is pinned.
- @is_pinned(yes),
- @pinned_drop($($pinned_drop:ident)?),
- ) => {
- $crate::__pin_data!(find_pinned_fields:
- @struct_attrs($($struct_attrs)*),
- @vis($vis),
- @name($name),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @decl_generics($($decl_generics)*),
- @where($($whr)*),
- @fields_munch($($rest)*),
- @pinned($($pinned)* $($accum)* $field: $type,),
- @not_pinned($($not_pinned)*),
- @fields($($fields)* $($accum)* $field: $type,),
- @accum(),
- @is_pinned(),
- @pinned_drop($($pinned_drop)?),
- );
- };
- (find_pinned_fields:
- @struct_attrs($($struct_attrs:tt)*),
- @vis($vis:vis),
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @where($($whr:tt)*),
- // We reached the field declaration.
- @fields_munch($field:ident : $type:ty, $($rest:tt)*),
- @pinned($($pinned:tt)*),
- @not_pinned($($not_pinned:tt)*),
- @fields($($fields:tt)*),
- @accum($($accum:tt)*),
- // This field is not pinned.
- @is_pinned(),
- @pinned_drop($($pinned_drop:ident)?),
- ) => {
- $crate::__pin_data!(find_pinned_fields:
- @struct_attrs($($struct_attrs)*),
- @vis($vis),
- @name($name),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @decl_generics($($decl_generics)*),
- @where($($whr)*),
- @fields_munch($($rest)*),
- @pinned($($pinned)*),
- @not_pinned($($not_pinned)* $($accum)* $field: $type,),
- @fields($($fields)* $($accum)* $field: $type,),
- @accum(),
- @is_pinned(),
- @pinned_drop($($pinned_drop)?),
- );
- };
- (find_pinned_fields:
- @struct_attrs($($struct_attrs:tt)*),
- @vis($vis:vis),
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @where($($whr:tt)*),
- // We found the `#[pin]` attr.
- @fields_munch(#[pin] $($rest:tt)*),
- @pinned($($pinned:tt)*),
- @not_pinned($($not_pinned:tt)*),
- @fields($($fields:tt)*),
- @accum($($accum:tt)*),
- @is_pinned($($is_pinned:ident)?),
- @pinned_drop($($pinned_drop:ident)?),
- ) => {
- $crate::__pin_data!(find_pinned_fields:
- @struct_attrs($($struct_attrs)*),
- @vis($vis),
- @name($name),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @decl_generics($($decl_generics)*),
- @where($($whr)*),
- @fields_munch($($rest)*),
- // We do not include `#[pin]` in the list of attributes, since it is not actually an
- // attribute that is defined somewhere.
- @pinned($($pinned)*),
- @not_pinned($($not_pinned)*),
- @fields($($fields)*),
- @accum($($accum)*),
- // Set this to `yes`.
- @is_pinned(yes),
- @pinned_drop($($pinned_drop)?),
- );
- };
- (find_pinned_fields:
- @struct_attrs($($struct_attrs:tt)*),
- @vis($vis:vis),
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @where($($whr:tt)*),
- // We reached the field declaration with visibility, for simplicity we only munch the
- // visibility and put it into `$accum`.
- @fields_munch($fvis:vis $field:ident $($rest:tt)*),
- @pinned($($pinned:tt)*),
- @not_pinned($($not_pinned:tt)*),
- @fields($($fields:tt)*),
- @accum($($accum:tt)*),
- @is_pinned($($is_pinned:ident)?),
- @pinned_drop($($pinned_drop:ident)?),
- ) => {
- $crate::__pin_data!(find_pinned_fields:
- @struct_attrs($($struct_attrs)*),
- @vis($vis),
- @name($name),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @decl_generics($($decl_generics)*),
- @where($($whr)*),
- @fields_munch($field $($rest)*),
- @pinned($($pinned)*),
- @not_pinned($($not_pinned)*),
- @fields($($fields)*),
- @accum($($accum)* $fvis),
- @is_pinned($($is_pinned)?),
- @pinned_drop($($pinned_drop)?),
- );
- };
- (find_pinned_fields:
- @struct_attrs($($struct_attrs:tt)*),
- @vis($vis:vis),
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @where($($whr:tt)*),
- // Some other attribute, just put it into `$accum`.
- @fields_munch(#[$($attr:tt)*] $($rest:tt)*),
- @pinned($($pinned:tt)*),
- @not_pinned($($not_pinned:tt)*),
- @fields($($fields:tt)*),
- @accum($($accum:tt)*),
- @is_pinned($($is_pinned:ident)?),
- @pinned_drop($($pinned_drop:ident)?),
- ) => {
- $crate::__pin_data!(find_pinned_fields:
- @struct_attrs($($struct_attrs)*),
- @vis($vis),
- @name($name),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @decl_generics($($decl_generics)*),
- @where($($whr)*),
- @fields_munch($($rest)*),
- @pinned($($pinned)*),
- @not_pinned($($not_pinned)*),
- @fields($($fields)*),
- @accum($($accum)* #[$($attr)*]),
- @is_pinned($($is_pinned)?),
- @pinned_drop($($pinned_drop)?),
- );
- };
- (find_pinned_fields:
- @struct_attrs($($struct_attrs:tt)*),
- @vis($vis:vis),
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @where($($whr:tt)*),
- // We reached the end of the fields, plus an optional additional comma, since we added one
- // before and the user is also allowed to put a trailing comma.
- @fields_munch($(,)?),
- @pinned($($pinned:tt)*),
- @not_pinned($($not_pinned:tt)*),
- @fields($($fields:tt)*),
- @accum(),
- @is_pinned(),
- @pinned_drop($($pinned_drop:ident)?),
- ) => {
- // Declare the struct with all fields in the correct order.
- $($struct_attrs)*
- $vis struct $name <$($decl_generics)*>
- where $($whr)*
- {
- $($fields)*
- }
-
- $crate::__pin_data!(make_pin_projections:
- @vis($vis),
- @name($name),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @decl_generics($($decl_generics)*),
- @where($($whr)*),
- @pinned($($pinned)*),
- @not_pinned($($not_pinned)*),
- );
-
- // We put the rest into this const item, because it then will not be accessible to anything
- // outside.
- const _: () = {
- // We declare this struct which will host all of the projection function for our type.
- // it will be invariant over all generic parameters which are inherited from the
- // struct.
- $vis struct __ThePinData<$($impl_generics)*>
- where $($whr)*
- {
- __phantom: ::core::marker::PhantomData<
- fn($name<$($ty_generics)*>) -> $name<$($ty_generics)*>
- >,
- }
-
- impl<$($impl_generics)*> ::core::clone::Clone for __ThePinData<$($ty_generics)*>
- where $($whr)*
- {
- fn clone(&self) -> Self { *self }
- }
-
- impl<$($impl_generics)*> ::core::marker::Copy for __ThePinData<$($ty_generics)*>
- where $($whr)*
- {}
-
- // Make all projection functions.
- $crate::__pin_data!(make_pin_data:
- @pin_data(__ThePinData),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @where($($whr)*),
- @pinned($($pinned)*),
- @not_pinned($($not_pinned)*),
- );
-
- // SAFETY: We have added the correct projection functions above to `__ThePinData` and
- // we also use the least restrictive generics possible.
- unsafe impl<$($impl_generics)*>
- $crate::__internal::HasPinData for $name<$($ty_generics)*>
- where $($whr)*
- {
- type PinData = __ThePinData<$($ty_generics)*>;
-
- unsafe fn __pin_data() -> Self::PinData {
- __ThePinData { __phantom: ::core::marker::PhantomData }
- }
- }
-
- // SAFETY: TODO.
- unsafe impl<$($impl_generics)*>
- $crate::__internal::PinData for __ThePinData<$($ty_generics)*>
- where $($whr)*
- {
- type Datee = $name<$($ty_generics)*>;
- }
-
- // This struct will be used for the unpin analysis. Since only structurally pinned
- // fields are relevant whether the struct should implement `Unpin`.
- #[allow(dead_code)]
- struct __Unpin <'__pin, $($impl_generics)*>
- where $($whr)*
- {
- __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
- __phantom: ::core::marker::PhantomData<
- fn($name<$($ty_generics)*>) -> $name<$($ty_generics)*>
- >,
- // Only the pinned fields.
- $($pinned)*
- }
-
- #[doc(hidden)]
- impl<'__pin, $($impl_generics)*> ::core::marker::Unpin for $name<$($ty_generics)*>
- where
- __Unpin<'__pin, $($ty_generics)*>: ::core::marker::Unpin,
- $($whr)*
- {}
-
- // We need to disallow normal `Drop` implementation, the exact behavior depends on
- // whether `PinnedDrop` was specified as the parameter.
- $crate::__pin_data!(drop_prevention:
- @name($name),
- @impl_generics($($impl_generics)*),
- @ty_generics($($ty_generics)*),
- @where($($whr)*),
- @pinned_drop($($pinned_drop)?),
- );
- };
- };
- // When no `PinnedDrop` was specified, then we have to prevent implementing drop.
- (drop_prevention:
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @where($($whr:tt)*),
- @pinned_drop(),
- ) => {
- // We prevent this by creating a trait that will be implemented for all types implementing
- // `Drop`. Additionally we will implement this trait for the struct leading to a conflict,
- // if it also implements `Drop`
- trait MustNotImplDrop {}
- #[expect(drop_bounds)]
- impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
- impl<$($impl_generics)*> MustNotImplDrop for $name<$($ty_generics)*>
- where $($whr)* {}
- // We also take care to prevent users from writing a useless `PinnedDrop` implementation.
- // They might implement `PinnedDrop` correctly for the struct, but forget to give
- // `PinnedDrop` as the parameter to `#[pin_data]`.
- #[expect(non_camel_case_types)]
- trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
- impl<T: $crate::PinnedDrop>
- UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
- impl<$($impl_generics)*>
- UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for $name<$($ty_generics)*>
- where $($whr)* {}
- };
- // When `PinnedDrop` was specified we just implement `Drop` and delegate.
- (drop_prevention:
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @where($($whr:tt)*),
- @pinned_drop(PinnedDrop),
- ) => {
- impl<$($impl_generics)*> ::core::ops::Drop for $name<$($ty_generics)*>
- where $($whr)*
- {
- fn drop(&mut self) {
- // SAFETY: Since this is a destructor, `self` will not move after this function
- // terminates, since it is inaccessible.
- let pinned = unsafe { ::core::pin::Pin::new_unchecked(self) };
- // SAFETY: Since this is a drop function, we can create this token to call the
- // pinned destructor of this type.
- let token = unsafe { $crate::__internal::OnlyCallFromDrop::new() };
- $crate::PinnedDrop::drop(pinned, token);
- }
- }
- };
- // If some other parameter was specified, we emit a readable error.
- (drop_prevention:
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @where($($whr:tt)*),
- @pinned_drop($($rest:tt)*),
- ) => {
- compile_error!(
- "Wrong parameters to `#[pin_data]`, expected nothing or `PinnedDrop`, got '{}'.",
- stringify!($($rest)*),
- );
- };
- (make_pin_projections:
- @vis($vis:vis),
- @name($name:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @decl_generics($($decl_generics:tt)*),
- @where($($whr:tt)*),
- @pinned($($(#[$($p_attr:tt)*])* $pvis:vis $p_field:ident : $p_type:ty),* $(,)?),
- @not_pinned($($(#[$($attr:tt)*])* $fvis:vis $field:ident : $type:ty),* $(,)?),
- ) => {
- $crate::macros::paste! {
- #[doc(hidden)]
- $vis struct [< $name Projection >] <'__pin, $($decl_generics)*> {
- $($(#[$($p_attr)*])* $pvis $p_field : ::core::pin::Pin<&'__pin mut $p_type>,)*
- $($(#[$($attr)*])* $fvis $field : &'__pin mut $type,)*
- ___pin_phantom_data: ::core::marker::PhantomData<&'__pin mut ()>,
- }
-
- impl<$($impl_generics)*> $name<$($ty_generics)*>
- where $($whr)*
- {
- /// Pin-projects all fields of `Self`.
- ///
- /// These fields are structurally pinned:
- $(#[doc = ::core::concat!(" - `", ::core::stringify!($p_field), "`")])*
- ///
- /// These fields are **not** structurally pinned:
- $(#[doc = ::core::concat!(" - `", ::core::stringify!($field), "`")])*
- #[inline]
- $vis fn project<'__pin>(
- self: ::core::pin::Pin<&'__pin mut Self>,
- ) -> [< $name Projection >] <'__pin, $($ty_generics)*> {
- // SAFETY: we only give access to `&mut` for fields not structurally pinned.
- let this = unsafe { ::core::pin::Pin::get_unchecked_mut(self) };
- [< $name Projection >] {
- $(
- // SAFETY: `$p_field` is structurally pinned.
- $(#[$($p_attr)*])*
- $p_field : unsafe { ::core::pin::Pin::new_unchecked(&mut this.$p_field) },
- )*
- $(
- $(#[$($attr)*])*
- $field : &mut this.$field,
- )*
- ___pin_phantom_data: ::core::marker::PhantomData,
- }
- }
- }
- }
- };
- (make_pin_data:
- @pin_data($pin_data:ident),
- @impl_generics($($impl_generics:tt)*),
- @ty_generics($($ty_generics:tt)*),
- @where($($whr:tt)*),
- @pinned($($(#[$($p_attr:tt)*])* $pvis:vis $p_field:ident : $p_type:ty),* $(,)?),
- @not_pinned($($(#[$($attr:tt)*])* $fvis:vis $field:ident : $type:ty),* $(,)?),
- ) => {
- $crate::macros::paste! {
- // For every field, we create a projection function according to its projection type. If a
- // field is structurally pinned, then it must be initialized via `PinInit`, if it is not
- // structurally pinned, then it can be initialized via `Init`.
- //
- // The functions are `unsafe` to prevent accidentally calling them.
- #[allow(dead_code)]
- #[expect(clippy::missing_safety_doc)]
- impl<$($impl_generics)*> $pin_data<$($ty_generics)*>
- where $($whr)*
- {
- $(
- $(#[$($p_attr)*])*
- $pvis unsafe fn $p_field<E>(
- self,
- slot: *mut $p_type,
- init: impl $crate::PinInit<$p_type, E>,
- ) -> ::core::result::Result<(), E> {
- // SAFETY: TODO.
- unsafe { $crate::PinInit::__pinned_init(init, slot) }
- }
-
- $(#[$($p_attr)*])*
- $pvis unsafe fn [<__project_ $p_field>]<'__slot>(
- self,
- slot: &'__slot mut $p_type,
- ) -> ::core::pin::Pin<&'__slot mut $p_type> {
- ::core::pin::Pin::new_unchecked(slot)
- }
- )*
- $(
- $(#[$($attr)*])*
- $fvis unsafe fn $field<E>(
- self,
- slot: *mut $type,
- init: impl $crate::Init<$type, E>,
- ) -> ::core::result::Result<(), E> {
- // SAFETY: TODO.
- unsafe { $crate::Init::__init(init, slot) }
- }
-
- $(#[$($attr)*])*
- $fvis unsafe fn [<__project_ $field>]<'__slot>(
- self,
- slot: &'__slot mut $type,
- ) -> &'__slot mut $type {
- slot
- }
- )*
- }
- }
- };
-}
-
/// The internal init macro. Do not call manually!
///
/// This is called by the `{try_}{pin_}init!` macros with various inputs.