// SPDX-License-Identifier: Apache-2.0 OR MIT12//! This module provides the macros that actually implement the proc-macros `pin_data` and3//! `pinned_drop`. It also contains `__init_internal`, the implementation of the4//! `{try_}{pin_}init!` macros.5//!6//! These macros should never be called directly, since they expect their input to be7//! in a certain format which is internal. If used incorrectly, these macros can lead to UB even in8//! safe code! Use the public facing macros instead.9//!10//! This architecture has been chosen because the kernel does not yet have access to `syn` which11//! would make matters a lot easier for implementing these as proc-macros.12//!13//! Since this library and the kernel implementation should diverge as little as possible, the same14//! approach has been taken here.15//!16//! # Macro expansion example17//!18//! This section is intended for readers trying to understand the macros in this module and the19//! `[try_][pin_]init!` macros from `lib.rs`.20//!21//! We will look at the following example:22//!23//! ```rust,ignore24//! #[pin_data]25//! #[repr(C)]26//! struct Bar<T> {27//! #[pin]28//! t: T,29//! pub x: usize,30//! }31//!32//! impl<T> Bar<T> {33//! fn new(t: T) -> impl PinInit<Self> {34//! pin_init!(Self { t, x: 0 })35//! }36//! }37//!38//! #[pin_data(PinnedDrop)]39//! struct Foo {40//! a: usize,41//! #[pin]42//! b: Bar<u32>,43//! }44//!45//! #[pinned_drop]46//! impl PinnedDrop for Foo {47//! fn drop(self: Pin<&mut Self>) {48//! println!("{self:p} is getting dropped.");49//! }50//! }51//!52//! let a = 42;53//! let initializer = pin_init!(Foo {54//! a,55//! b <- Bar::new(36),56//! });57//! ```58//!59//! This example includes the most common and important features of the pin-init API.60//!61//! Below you can find individual section about the different macro invocations. Here are some62//! general things we need to take into account when designing macros:63//! - use global paths, similarly to file paths, these start with the separator: `::core::panic!()`64//! this ensures that the correct item is used, since users could define their own `mod core {}`65//! and then their own `panic!` inside to execute arbitrary code inside of our macro.66//! - macro `unsafe` hygiene: we need to ensure that we do not expand arbitrary, user-supplied67//! expressions inside of an `unsafe` block in the macro, because this would allow users to do68//! `unsafe` operations without an associated `unsafe` block.69//!70//! ## `#[pin_data]` on `Bar`71//!72//! This macro is used to specify which fields are structurally pinned and which fields are not. It73//! is placed on the struct definition and allows `#[pin]` to be placed on the fields.74//!75//! Here is the definition of `Bar` from our example:76//!77//! ```rust,ignore78//! #[pin_data]79//! #[repr(C)]80//! struct Bar<T> {81//! #[pin]82//! t: T,83//! pub x: usize,84//! }85//! ```86//!87//! This expands to the following code:88//!89//! ```rust,ignore90//! // Firstly the normal definition of the struct, attributes are preserved:91//! #[repr(C)]92//! struct Bar<T> {93//! t: T,94//! pub x: usize,95//! }96//! // Then an anonymous constant is defined, this is because we do not want any code to access the97//! // types that we define inside:98//! const _: () = {99//! // We define the pin-data carrying struct, it is a ZST and needs to have the same generics,100//! // since we need to implement access functions for each field and thus need to know its101//! // type.102//! struct __ThePinData<T> {103//! __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,104//! }105//! // We implement `Copy` for the pin-data struct, since all functions it defines will take106//! // `self` by value.107//! impl<T> ::core::clone::Clone for __ThePinData<T> {108//! fn clone(&self) -> Self {109//! *self110//! }111//! }112//! impl<T> ::core::marker::Copy for __ThePinData<T> {}113//! // For every field of `Bar`, the pin-data struct will define a function with the same name114//! // and accessor (`pub` or `pub(crate)` etc.). This function will take a pointer to the115//! // field (`slot`) and a `PinInit` or `Init` depending on the projection kind of the field116//! // (if pinning is structural for the field, then `PinInit` otherwise `Init`).117//! #[allow(dead_code)]118//! impl<T> __ThePinData<T> {119//! unsafe fn t<E>(120//! self,121//! slot: *mut T,122//! // Since `t` is `#[pin]`, this is `PinInit`.123//! init: impl ::pin_init::PinInit<T, E>,124//! ) -> ::core::result::Result<(), E> {125//! unsafe { ::pin_init::PinInit::__pinned_init(init, slot) }126//! }127//! pub unsafe fn x<E>(128//! self,129//! slot: *mut usize,130//! // Since `x` is not `#[pin]`, this is `Init`.131//! init: impl ::pin_init::Init<usize, E>,132//! ) -> ::core::result::Result<(), E> {133//! unsafe { ::pin_init::Init::__init(init, slot) }134//! }135//! }136//! // Implement the internal `HasPinData` trait that associates `Bar` with the pin-data struct137//! // that we constructed above.138//! unsafe impl<T> ::pin_init::__internal::HasPinData for Bar<T> {139//! type PinData = __ThePinData<T>;140//! unsafe fn __pin_data() -> Self::PinData {141//! __ThePinData {142//! __phantom: ::core::marker::PhantomData,143//! }144//! }145//! }146//! // Implement the internal `PinData` trait that marks the pin-data struct as a pin-data147//! // struct. This is important to ensure that no user can implement a rogue `__pin_data`148//! // function without using `unsafe`.149//! unsafe impl<T> ::pin_init::__internal::PinData for __ThePinData<T> {150//! type Datee = Bar<T>;151//! }152//! // Now we only want to implement `Unpin` for `Bar` when every structurally pinned field is153//! // `Unpin`. In other words, whether `Bar` is `Unpin` only depends on structurally pinned154//! // fields (those marked with `#[pin]`). These fields will be listed in this struct, in our155//! // case no such fields exist, hence this is almost empty. The two phantomdata fields exist156//! // for two reasons:157//! // - `__phantom`: every generic must be used, since we cannot really know which generics158//! // are used, we declare all and then use everything here once.159//! // - `__phantom_pin`: uses the `'__pin` lifetime and ensures that this struct is invariant160//! // over it. The lifetime is needed to work around the limitation that trait bounds must161//! // not be trivial, e.g. the user has a `#[pin] PhantomPinned` field -- this is162//! // unconditionally `!Unpin` and results in an error. The lifetime tricks the compiler163//! // into accepting these bounds regardless.164//! #[allow(dead_code)]165//! struct __Unpin<'__pin, T> {166//! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,167//! __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,168//! // Our only `#[pin]` field is `t`.169//! t: T,170//! }171//! #[doc(hidden)]172//! impl<'__pin, T> ::core::marker::Unpin for Bar<T>173//! where174//! __Unpin<'__pin, T>: ::core::marker::Unpin,175//! {}176//! // Now we need to ensure that `Bar` does not implement `Drop`, since that would give users177//! // access to `&mut self` inside of `drop` even if the struct was pinned. This could lead to178//! // UB with only safe code, so we disallow this by giving a trait implementation error using179//! // a direct impl and a blanket implementation.180//! trait MustNotImplDrop {}181//! // Normally `Drop` bounds do not have the correct semantics, but for this purpose they do182//! // (normally people want to know if a type has any kind of drop glue at all, here we want183//! // to know if it has any kind of custom drop glue, which is exactly what this bound does).184//! #[expect(drop_bounds)]185//! impl<T: ::core::ops::Drop> MustNotImplDrop for T {}186//! impl<T> MustNotImplDrop for Bar<T> {}187//! // Here comes a convenience check, if one implemented `PinnedDrop`, but forgot to add it to188//! // `#[pin_data]`, then this will error with the same mechanic as above, this is not needed189//! // for safety, but a good sanity check, since no normal code calls `PinnedDrop::drop`.190//! #[expect(non_camel_case_types)]191//! trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}192//! impl<193//! T: ::pin_init::PinnedDrop,194//! > UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}195//! impl<T> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for Bar<T> {}196//! };197//! ```198//!199//! ## `pin_init!` in `impl Bar`200//!201//! This macro creates an pin-initializer for the given struct. It requires that the struct is202//! annotated by `#[pin_data]`.203//!204//! Here is the impl on `Bar` defining the new function:205//!206//! ```rust,ignore207//! impl<T> Bar<T> {208//! fn new(t: T) -> impl PinInit<Self> {209//! pin_init!(Self { t, x: 0 })210//! }211//! }212//! ```213//!214//! This expands to the following code:215//!216//! ```rust,ignore217//! impl<T> Bar<T> {218//! fn new(t: T) -> impl PinInit<Self> {219//! {220//! // We do not want to allow arbitrary returns, so we declare this type as the `Ok`221//! // return type and shadow it later when we insert the arbitrary user code. That way222//! // there will be no possibility of returning without `unsafe`.223//! struct __InitOk;224//! // Get the data about fields from the supplied type.225//! // - the function is unsafe, hence the unsafe block226//! // - we `use` the `HasPinData` trait in the block, it is only available in that227//! // scope.228//! let data = unsafe {229//! use ::pin_init::__internal::HasPinData;230//! Self::__pin_data()231//! };232//! // Ensure that `data` really is of type `PinData` and help with type inference:233//! let init = ::pin_init::__internal::PinData::make_closure::<234//! _,235//! __InitOk,236//! ::core::convert::Infallible,237//! >(data, move |slot| {238//! {239//! // Shadow the structure so it cannot be used to return early. If a user240//! // tries to write `return Ok(__InitOk)`, then they get a type error,241//! // since that will refer to this struct instead of the one defined242//! // above.243//! struct __InitOk;244//! // This is the expansion of `t,`, which is syntactic sugar for `t: t,`.245//! {246//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).t), t) };247//! }248//! // Since initialization could fail later (not in this case, since the249//! // error type is `Infallible`) we will need to drop this field if there250//! // is an error later. This `DropGuard` will drop the field when it gets251//! // dropped and has not yet been forgotten.252//! let __t_guard = unsafe {253//! ::pin_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).t))254//! };255//! // Expansion of `x: 0,`:256//! // Since this can be an arbitrary expression we cannot place it inside257//! // of the `unsafe` block, so we bind it here.258//! {259//! let x = 0;260//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).x), x) };261//! }262//! // We again create a `DropGuard`.263//! let __x_guard = unsafe {264//! ::pin_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).x))265//! };266//! // Since initialization has successfully completed, we can now forget267//! // the guards. This is not `mem::forget`, since we only have268//! // `&DropGuard`.269//! ::core::mem::forget(__x_guard);270//! ::core::mem::forget(__t_guard);271//! // Here we use the type checker to ensure that every field has been272//! // initialized exactly once, since this is `if false` it will never get273//! // executed, but still type-checked.274//! // Additionally we abuse `slot` to automatically infer the correct type275//! // for the struct. This is also another check that every field is276//! // accessible from this scope.277//! #[allow(unreachable_code, clippy::diverging_sub_expression)]278//! let _ = || {279//! unsafe {280//! ::core::ptr::write(281//! slot,282//! Self {283//! // We only care about typecheck finding every field284//! // here, the expression does not matter, just conjure285//! // one using `panic!()`:286//! t: ::core::panic!(),287//! x: ::core::panic!(),288//! },289//! );290//! };291//! };292//! }293//! // We leave the scope above and gain access to the previously shadowed294//! // `__InitOk` that we need to return.295//! Ok(__InitOk)296//! });297//! // Change the return type from `__InitOk` to `()`.298//! let init = move |299//! slot,300//! | -> ::core::result::Result<(), ::core::convert::Infallible> {301//! init(slot).map(|__InitOk| ())302//! };303//! // Construct the initializer.304//! let init = unsafe {305//! ::pin_init::pin_init_from_closure::<306//! _,307//! ::core::convert::Infallible,308//! >(init)309//! };310//! init311//! }312//! }313//! }314//! ```315//!316//! ## `#[pin_data]` on `Foo`317//!318//! Since we already took a look at `#[pin_data]` on `Bar`, this section will only explain the319//! differences/new things in the expansion of the `Foo` definition:320//!321//! ```rust,ignore322//! #[pin_data(PinnedDrop)]323//! struct Foo {324//! a: usize,325//! #[pin]326//! b: Bar<u32>,327//! }328//! ```329//!330//! This expands to the following code:331//!332//! ```rust,ignore333//! struct Foo {334//! a: usize,335//! b: Bar<u32>,336//! }337//! const _: () = {338//! struct __ThePinData {339//! __phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,340//! }341//! impl ::core::clone::Clone for __ThePinData {342//! fn clone(&self) -> Self {343//! *self344//! }345//! }346//! impl ::core::marker::Copy for __ThePinData {}347//! #[allow(dead_code)]348//! impl __ThePinData {349//! unsafe fn b<E>(350//! self,351//! slot: *mut Bar<u32>,352//! init: impl ::pin_init::PinInit<Bar<u32>, E>,353//! ) -> ::core::result::Result<(), E> {354//! unsafe { ::pin_init::PinInit::__pinned_init(init, slot) }355//! }356//! unsafe fn a<E>(357//! self,358//! slot: *mut usize,359//! init: impl ::pin_init::Init<usize, E>,360//! ) -> ::core::result::Result<(), E> {361//! unsafe { ::pin_init::Init::__init(init, slot) }362//! }363//! }364//! unsafe impl ::pin_init::__internal::HasPinData for Foo {365//! type PinData = __ThePinData;366//! unsafe fn __pin_data() -> Self::PinData {367//! __ThePinData {368//! __phantom: ::core::marker::PhantomData,369//! }370//! }371//! }372//! unsafe impl ::pin_init::__internal::PinData for __ThePinData {373//! type Datee = Foo;374//! }375//! #[allow(dead_code)]376//! struct __Unpin<'__pin> {377//! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,378//! __phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,379//! b: Bar<u32>,380//! }381//! #[doc(hidden)]382//! impl<'__pin> ::core::marker::Unpin for Foo383//! where384//! __Unpin<'__pin>: ::core::marker::Unpin,385//! {}386//! // Since we specified `PinnedDrop` as the argument to `#[pin_data]`, we expect `Foo` to387//! // implement `PinnedDrop`. Thus we do not need to prevent `Drop` implementations like388//! // before, instead we implement `Drop` here and delegate to `PinnedDrop`.389//! impl ::core::ops::Drop for Foo {390//! fn drop(&mut self) {391//! // Since we are getting dropped, no one else has a reference to `self` and thus we392//! // can assume that we never move.393//! let pinned = unsafe { ::core::pin::Pin::new_unchecked(self) };394//! // Create the unsafe token that proves that we are inside of a destructor, this395//! // type is only allowed to be created in a destructor.396//! let token = unsafe { ::pin_init::__internal::OnlyCallFromDrop::new() };397//! ::pin_init::PinnedDrop::drop(pinned, token);398//! }399//! }400//! };401//! ```402//!403//! ## `#[pinned_drop]` on `impl PinnedDrop for Foo`404//!405//! This macro is used to implement the `PinnedDrop` trait, since that trait is `unsafe` and has an406//! extra parameter that should not be used at all. The macro hides that parameter.407//!408//! Here is the `PinnedDrop` impl for `Foo`:409//!410//! ```rust,ignore411//! #[pinned_drop]412//! impl PinnedDrop for Foo {413//! fn drop(self: Pin<&mut Self>) {414//! println!("{self:p} is getting dropped.");415//! }416//! }417//! ```418//!419//! This expands to the following code:420//!421//! ```rust,ignore422//! // `unsafe`, full path and the token parameter are added, everything else stays the same.423//! unsafe impl ::pin_init::PinnedDrop for Foo {424//! fn drop(self: Pin<&mut Self>, _: ::pin_init::__internal::OnlyCallFromDrop) {425//! println!("{self:p} is getting dropped.");426//! }427//! }428//! ```429//!430//! ## `pin_init!` on `Foo`431//!432//! Since we already took a look at `pin_init!` on `Bar`, this section will only show the expansion433//! of `pin_init!` on `Foo`:434//!435//! ```rust,ignore436//! let a = 42;437//! let initializer = pin_init!(Foo {438//! a,439//! b <- Bar::new(36),440//! });441//! ```442//!443//! This expands to the following code:444//!445//! ```rust,ignore446//! let a = 42;447//! let initializer = {448//! struct __InitOk;449//! let data = unsafe {450//! use ::pin_init::__internal::HasPinData;451//! Foo::__pin_data()452//! };453//! let init = ::pin_init::__internal::PinData::make_closure::<454//! _,455//! __InitOk,456//! ::core::convert::Infallible,457//! >(data, move |slot| {458//! {459//! struct __InitOk;460//! {461//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).a), a) };462//! }463//! let __a_guard = unsafe {464//! ::pin_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).a))465//! };466//! let init = Bar::new(36);467//! unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? };468//! let __b_guard = unsafe {469//! ::pin_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).b))470//! };471//! ::core::mem::forget(__b_guard);472//! ::core::mem::forget(__a_guard);473//! #[allow(unreachable_code, clippy::diverging_sub_expression)]474//! let _ = || {475//! unsafe {476//! ::core::ptr::write(477//! slot,478//! Foo {479//! a: ::core::panic!(),480//! b: ::core::panic!(),481//! },482//! );483//! };484//! };485//! }486//! Ok(__InitOk)487//! });488//! let init = move |489//! slot,490//! | -> ::core::result::Result<(), ::core::convert::Infallible> {491//! init(slot).map(|__InitOk| ())492//! };493//! let init = unsafe {494//! ::pin_init::pin_init_from_closure::<_, ::core::convert::Infallible>(init)495//! };496//! init497//! };498//! ```499500#[cfg(kernel)]501pub use ::macros::paste;502#[cfg(not(kernel))]503pub use ::paste::paste;504505/// Creates a `unsafe impl<...> PinnedDrop for $type` block.506///507/// See [`PinnedDrop`] for more information.508///509/// [`PinnedDrop`]: crate::PinnedDrop510#[doc(hidden)]511#[macro_export]512macro_rules! __pinned_drop {513(514@impl_sig($($impl_sig:tt)*),515@impl_body(516$(#[$($attr:tt)*])*517fn drop($($sig:tt)*) {518$($inner:tt)*519}520),521) => {522// SAFETY: TODO.523unsafe $($impl_sig)* {524// Inherit all attributes and the type/ident tokens for the signature.525$(#[$($attr)*])*526fn drop($($sig)*, _: $crate::__internal::OnlyCallFromDrop) {527$($inner)*528}529}530}531}532533/// This macro first parses the struct definition such that it separates pinned and not pinned534/// fields. Afterwards it declares the struct and implement the `PinData` trait safely.535#[doc(hidden)]536#[macro_export]537macro_rules! __pin_data {538// Proc-macro entry point, this is supplied by the proc-macro pre-parsing.539(parse_input:540@args($($pinned_drop:ident)?),541@sig(542$(#[$($struct_attr:tt)*])*543$vis:vis struct $name:ident544$(where $($whr:tt)*)?545),546@impl_generics($($impl_generics:tt)*),547@ty_generics($($ty_generics:tt)*),548@decl_generics($($decl_generics:tt)*),549@body({ $($fields:tt)* }),550) => {551// We now use token munching to iterate through all of the fields. While doing this we552// identify fields marked with `#[pin]`, these fields are the 'pinned fields'. The user553// wants these to be structurally pinned. The rest of the fields are the554// 'not pinned fields'. Additionally we collect all fields, since we need them in the right555// order to declare the struct.556//557// In this call we also put some explaining comments for the parameters.558$crate::__pin_data!(find_pinned_fields:559// Attributes on the struct itself, these will just be propagated to be put onto the560// struct definition.561@struct_attrs($(#[$($struct_attr)*])*),562// The visibility of the struct.563@vis($vis),564// The name of the struct.565@name($name),566// The 'impl generics', the generics that will need to be specified on the struct inside567// of an `impl<$ty_generics>` block.568@impl_generics($($impl_generics)*),569// The 'ty generics', the generics that will need to be specified on the impl blocks.570@ty_generics($($ty_generics)*),571// The 'decl generics', the generics that need to be specified on the struct572// definition.573@decl_generics($($decl_generics)*),574// The where clause of any impl block and the declaration.575@where($($($whr)*)?),576// The remaining fields tokens that need to be processed.577// We add a `,` at the end to ensure correct parsing.578@fields_munch($($fields)* ,),579// The pinned fields.580@pinned(),581// The not pinned fields.582@not_pinned(),583// All fields.584@fields(),585// The accumulator containing all attributes already parsed.586@accum(),587// Contains `yes` or `` to indicate if `#[pin]` was found on the current field.588@is_pinned(),589// The proc-macro argument, this should be `PinnedDrop` or ``.590@pinned_drop($($pinned_drop)?),591);592};593(find_pinned_fields:594@struct_attrs($($struct_attrs:tt)*),595@vis($vis:vis),596@name($name:ident),597@impl_generics($($impl_generics:tt)*),598@ty_generics($($ty_generics:tt)*),599@decl_generics($($decl_generics:tt)*),600@where($($whr:tt)*),601// We found a PhantomPinned field, this should generally be pinned!602@fields_munch($field:ident : $($($(::)?core::)?marker::)?PhantomPinned, $($rest:tt)*),603@pinned($($pinned:tt)*),604@not_pinned($($not_pinned:tt)*),605@fields($($fields:tt)*),606@accum($($accum:tt)*),607// This field is not pinned.608@is_pinned(),609@pinned_drop($($pinned_drop:ident)?),610) => {611::core::compile_error!(concat!(612"The field `",613stringify!($field),614"` of type `PhantomPinned` only has an effect, if it has the `#[pin]` attribute.",615));616$crate::__pin_data!(find_pinned_fields:617@struct_attrs($($struct_attrs)*),618@vis($vis),619@name($name),620@impl_generics($($impl_generics)*),621@ty_generics($($ty_generics)*),622@decl_generics($($decl_generics)*),623@where($($whr)*),624@fields_munch($($rest)*),625@pinned($($pinned)* $($accum)* $field: ::core::marker::PhantomPinned,),626@not_pinned($($not_pinned)*),627@fields($($fields)* $($accum)* $field: ::core::marker::PhantomPinned,),628@accum(),629@is_pinned(),630@pinned_drop($($pinned_drop)?),631);632};633(find_pinned_fields:634@struct_attrs($($struct_attrs:tt)*),635@vis($vis:vis),636@name($name:ident),637@impl_generics($($impl_generics:tt)*),638@ty_generics($($ty_generics:tt)*),639@decl_generics($($decl_generics:tt)*),640@where($($whr:tt)*),641// We reached the field declaration.642@fields_munch($field:ident : $type:ty, $($rest:tt)*),643@pinned($($pinned:tt)*),644@not_pinned($($not_pinned:tt)*),645@fields($($fields:tt)*),646@accum($($accum:tt)*),647// This field is pinned.648@is_pinned(yes),649@pinned_drop($($pinned_drop:ident)?),650) => {651$crate::__pin_data!(find_pinned_fields:652@struct_attrs($($struct_attrs)*),653@vis($vis),654@name($name),655@impl_generics($($impl_generics)*),656@ty_generics($($ty_generics)*),657@decl_generics($($decl_generics)*),658@where($($whr)*),659@fields_munch($($rest)*),660@pinned($($pinned)* $($accum)* $field: $type,),661@not_pinned($($not_pinned)*),662@fields($($fields)* $($accum)* $field: $type,),663@accum(),664@is_pinned(),665@pinned_drop($($pinned_drop)?),666);667};668(find_pinned_fields:669@struct_attrs($($struct_attrs:tt)*),670@vis($vis:vis),671@name($name:ident),672@impl_generics($($impl_generics:tt)*),673@ty_generics($($ty_generics:tt)*),674@decl_generics($($decl_generics:tt)*),675@where($($whr:tt)*),676// We reached the field declaration.677@fields_munch($field:ident : $type:ty, $($rest:tt)*),678@pinned($($pinned:tt)*),679@not_pinned($($not_pinned:tt)*),680@fields($($fields:tt)*),681@accum($($accum:tt)*),682// This field is not pinned.683@is_pinned(),684@pinned_drop($($pinned_drop:ident)?),685) => {686$crate::__pin_data!(find_pinned_fields:687@struct_attrs($($struct_attrs)*),688@vis($vis),689@name($name),690@impl_generics($($impl_generics)*),691@ty_generics($($ty_generics)*),692@decl_generics($($decl_generics)*),693@where($($whr)*),694@fields_munch($($rest)*),695@pinned($($pinned)*),696@not_pinned($($not_pinned)* $($accum)* $field: $type,),697@fields($($fields)* $($accum)* $field: $type,),698@accum(),699@is_pinned(),700@pinned_drop($($pinned_drop)?),701);702};703(find_pinned_fields:704@struct_attrs($($struct_attrs:tt)*),705@vis($vis:vis),706@name($name:ident),707@impl_generics($($impl_generics:tt)*),708@ty_generics($($ty_generics:tt)*),709@decl_generics($($decl_generics:tt)*),710@where($($whr:tt)*),711// We found the `#[pin]` attr.712@fields_munch(#[pin] $($rest:tt)*),713@pinned($($pinned:tt)*),714@not_pinned($($not_pinned:tt)*),715@fields($($fields:tt)*),716@accum($($accum:tt)*),717@is_pinned($($is_pinned:ident)?),718@pinned_drop($($pinned_drop:ident)?),719) => {720$crate::__pin_data!(find_pinned_fields:721@struct_attrs($($struct_attrs)*),722@vis($vis),723@name($name),724@impl_generics($($impl_generics)*),725@ty_generics($($ty_generics)*),726@decl_generics($($decl_generics)*),727@where($($whr)*),728@fields_munch($($rest)*),729// We do not include `#[pin]` in the list of attributes, since it is not actually an730// attribute that is defined somewhere.731@pinned($($pinned)*),732@not_pinned($($not_pinned)*),733@fields($($fields)*),734@accum($($accum)*),735// Set this to `yes`.736@is_pinned(yes),737@pinned_drop($($pinned_drop)?),738);739};740(find_pinned_fields:741@struct_attrs($($struct_attrs:tt)*),742@vis($vis:vis),743@name($name:ident),744@impl_generics($($impl_generics:tt)*),745@ty_generics($($ty_generics:tt)*),746@decl_generics($($decl_generics:tt)*),747@where($($whr:tt)*),748// We reached the field declaration with visibility, for simplicity we only munch the749// visibility and put it into `$accum`.750@fields_munch($fvis:vis $field:ident $($rest:tt)*),751@pinned($($pinned:tt)*),752@not_pinned($($not_pinned:tt)*),753@fields($($fields:tt)*),754@accum($($accum:tt)*),755@is_pinned($($is_pinned:ident)?),756@pinned_drop($($pinned_drop:ident)?),757) => {758$crate::__pin_data!(find_pinned_fields:759@struct_attrs($($struct_attrs)*),760@vis($vis),761@name($name),762@impl_generics($($impl_generics)*),763@ty_generics($($ty_generics)*),764@decl_generics($($decl_generics)*),765@where($($whr)*),766@fields_munch($field $($rest)*),767@pinned($($pinned)*),768@not_pinned($($not_pinned)*),769@fields($($fields)*),770@accum($($accum)* $fvis),771@is_pinned($($is_pinned)?),772@pinned_drop($($pinned_drop)?),773);774};775(find_pinned_fields:776@struct_attrs($($struct_attrs:tt)*),777@vis($vis:vis),778@name($name:ident),779@impl_generics($($impl_generics:tt)*),780@ty_generics($($ty_generics:tt)*),781@decl_generics($($decl_generics:tt)*),782@where($($whr:tt)*),783// Some other attribute, just put it into `$accum`.784@fields_munch(#[$($attr:tt)*] $($rest:tt)*),785@pinned($($pinned:tt)*),786@not_pinned($($not_pinned:tt)*),787@fields($($fields:tt)*),788@accum($($accum:tt)*),789@is_pinned($($is_pinned:ident)?),790@pinned_drop($($pinned_drop:ident)?),791) => {792$crate::__pin_data!(find_pinned_fields:793@struct_attrs($($struct_attrs)*),794@vis($vis),795@name($name),796@impl_generics($($impl_generics)*),797@ty_generics($($ty_generics)*),798@decl_generics($($decl_generics)*),799@where($($whr)*),800@fields_munch($($rest)*),801@pinned($($pinned)*),802@not_pinned($($not_pinned)*),803@fields($($fields)*),804@accum($($accum)* #[$($attr)*]),805@is_pinned($($is_pinned)?),806@pinned_drop($($pinned_drop)?),807);808};809(find_pinned_fields:810@struct_attrs($($struct_attrs:tt)*),811@vis($vis:vis),812@name($name:ident),813@impl_generics($($impl_generics:tt)*),814@ty_generics($($ty_generics:tt)*),815@decl_generics($($decl_generics:tt)*),816@where($($whr:tt)*),817// We reached the end of the fields, plus an optional additional comma, since we added one818// before and the user is also allowed to put a trailing comma.819@fields_munch($(,)?),820@pinned($($pinned:tt)*),821@not_pinned($($not_pinned:tt)*),822@fields($($fields:tt)*),823@accum(),824@is_pinned(),825@pinned_drop($($pinned_drop:ident)?),826) => {827// Declare the struct with all fields in the correct order.828$($struct_attrs)*829$vis struct $name <$($decl_generics)*>830where $($whr)*831{832$($fields)*833}834835$crate::__pin_data!(make_pin_projections:836@vis($vis),837@name($name),838@impl_generics($($impl_generics)*),839@ty_generics($($ty_generics)*),840@decl_generics($($decl_generics)*),841@where($($whr)*),842@pinned($($pinned)*),843@not_pinned($($not_pinned)*),844);845846// We put the rest into this const item, because it then will not be accessible to anything847// outside.848const _: () = {849// We declare this struct which will host all of the projection function for our type.850// it will be invariant over all generic parameters which are inherited from the851// struct.852$vis struct __ThePinData<$($impl_generics)*>853where $($whr)*854{855__phantom: ::core::marker::PhantomData<856fn($name<$($ty_generics)*>) -> $name<$($ty_generics)*>857>,858}859860impl<$($impl_generics)*> ::core::clone::Clone for __ThePinData<$($ty_generics)*>861where $($whr)*862{863fn clone(&self) -> Self { *self }864}865866impl<$($impl_generics)*> ::core::marker::Copy for __ThePinData<$($ty_generics)*>867where $($whr)*868{}869870// Make all projection functions.871$crate::__pin_data!(make_pin_data:872@pin_data(__ThePinData),873@impl_generics($($impl_generics)*),874@ty_generics($($ty_generics)*),875@where($($whr)*),876@pinned($($pinned)*),877@not_pinned($($not_pinned)*),878);879880// SAFETY: We have added the correct projection functions above to `__ThePinData` and881// we also use the least restrictive generics possible.882unsafe impl<$($impl_generics)*>883$crate::__internal::HasPinData for $name<$($ty_generics)*>884where $($whr)*885{886type PinData = __ThePinData<$($ty_generics)*>;887888unsafe fn __pin_data() -> Self::PinData {889__ThePinData { __phantom: ::core::marker::PhantomData }890}891}892893// SAFETY: TODO.894unsafe impl<$($impl_generics)*>895$crate::__internal::PinData for __ThePinData<$($ty_generics)*>896where $($whr)*897{898type Datee = $name<$($ty_generics)*>;899}900901// This struct will be used for the unpin analysis. Since only structurally pinned902// fields are relevant whether the struct should implement `Unpin`.903#[allow(dead_code)]904struct __Unpin <'__pin, $($impl_generics)*>905where $($whr)*906{907__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,908__phantom: ::core::marker::PhantomData<909fn($name<$($ty_generics)*>) -> $name<$($ty_generics)*>910>,911// Only the pinned fields.912$($pinned)*913}914915#[doc(hidden)]916impl<'__pin, $($impl_generics)*> ::core::marker::Unpin for $name<$($ty_generics)*>917where918__Unpin<'__pin, $($ty_generics)*>: ::core::marker::Unpin,919$($whr)*920{}921922// We need to disallow normal `Drop` implementation, the exact behavior depends on923// whether `PinnedDrop` was specified as the parameter.924$crate::__pin_data!(drop_prevention:925@name($name),926@impl_generics($($impl_generics)*),927@ty_generics($($ty_generics)*),928@where($($whr)*),929@pinned_drop($($pinned_drop)?),930);931};932};933// When no `PinnedDrop` was specified, then we have to prevent implementing drop.934(drop_prevention:935@name($name:ident),936@impl_generics($($impl_generics:tt)*),937@ty_generics($($ty_generics:tt)*),938@where($($whr:tt)*),939@pinned_drop(),940) => {941// We prevent this by creating a trait that will be implemented for all types implementing942// `Drop`. Additionally we will implement this trait for the struct leading to a conflict,943// if it also implements `Drop`944trait MustNotImplDrop {}945#[expect(drop_bounds)]946impl<T: ::core::ops::Drop> MustNotImplDrop for T {}947impl<$($impl_generics)*> MustNotImplDrop for $name<$($ty_generics)*>948where $($whr)* {}949// We also take care to prevent users from writing a useless `PinnedDrop` implementation.950// They might implement `PinnedDrop` correctly for the struct, but forget to give951// `PinnedDrop` as the parameter to `#[pin_data]`.952#[expect(non_camel_case_types)]953trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}954impl<T: $crate::PinnedDrop>955UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}956impl<$($impl_generics)*>957UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for $name<$($ty_generics)*>958where $($whr)* {}959};960// When `PinnedDrop` was specified we just implement `Drop` and delegate.961(drop_prevention:962@name($name:ident),963@impl_generics($($impl_generics:tt)*),964@ty_generics($($ty_generics:tt)*),965@where($($whr:tt)*),966@pinned_drop(PinnedDrop),967) => {968impl<$($impl_generics)*> ::core::ops::Drop for $name<$($ty_generics)*>969where $($whr)*970{971fn drop(&mut self) {972// SAFETY: Since this is a destructor, `self` will not move after this function973// terminates, since it is inaccessible.974let pinned = unsafe { ::core::pin::Pin::new_unchecked(self) };975// SAFETY: Since this is a drop function, we can create this token to call the976// pinned destructor of this type.977let token = unsafe { $crate::__internal::OnlyCallFromDrop::new() };978$crate::PinnedDrop::drop(pinned, token);979}980}981};982// If some other parameter was specified, we emit a readable error.983(drop_prevention:984@name($name:ident),985@impl_generics($($impl_generics:tt)*),986@ty_generics($($ty_generics:tt)*),987@where($($whr:tt)*),988@pinned_drop($($rest:tt)*),989) => {990compile_error!(991"Wrong parameters to `#[pin_data]`, expected nothing or `PinnedDrop`, got '{}'.",992stringify!($($rest)*),993);994};995(make_pin_projections:996@vis($vis:vis),997@name($name:ident),998@impl_generics($($impl_generics:tt)*),999@ty_generics($($ty_generics:tt)*),1000@decl_generics($($decl_generics:tt)*),1001@where($($whr:tt)*),1002@pinned($($(#[$($p_attr:tt)*])* $pvis:vis $p_field:ident : $p_type:ty),* $(,)?),1003@not_pinned($($(#[$($attr:tt)*])* $fvis:vis $field:ident : $type:ty),* $(,)?),1004) => {1005$crate::macros::paste! {1006#[doc(hidden)]1007$vis struct [< $name Projection >] <'__pin, $($decl_generics)*> {1008$($(#[$($p_attr)*])* $pvis $p_field : ::core::pin::Pin<&'__pin mut $p_type>,)*1009$($(#[$($attr)*])* $fvis $field : &'__pin mut $type,)*1010___pin_phantom_data: ::core::marker::PhantomData<&'__pin mut ()>,1011}10121013impl<$($impl_generics)*> $name<$($ty_generics)*>1014where $($whr)*1015{1016/// Pin-projects all fields of `Self`.1017///1018/// These fields are structurally pinned:1019$(#[doc = ::core::concat!(" - `", ::core::stringify!($p_field), "`")])*1020///1021/// These fields are **not** structurally pinned:1022$(#[doc = ::core::concat!(" - `", ::core::stringify!($field), "`")])*1023#[inline]1024$vis fn project<'__pin>(1025self: ::core::pin::Pin<&'__pin mut Self>,1026) -> [< $name Projection >] <'__pin, $($ty_generics)*> {1027// SAFETY: we only give access to `&mut` for fields not structurally pinned.1028let this = unsafe { ::core::pin::Pin::get_unchecked_mut(self) };1029[< $name Projection >] {1030$(1031// SAFETY: `$p_field` is structurally pinned.1032$(#[$($p_attr)*])*1033$p_field : unsafe { ::core::pin::Pin::new_unchecked(&mut this.$p_field) },1034)*1035$(1036$(#[$($attr)*])*1037$field : &mut this.$field,1038)*1039___pin_phantom_data: ::core::marker::PhantomData,1040}1041}1042}1043}1044};1045(make_pin_data:1046@pin_data($pin_data:ident),1047@impl_generics($($impl_generics:tt)*),1048@ty_generics($($ty_generics:tt)*),1049@where($($whr:tt)*),1050@pinned($($(#[$($p_attr:tt)*])* $pvis:vis $p_field:ident : $p_type:ty),* $(,)?),1051@not_pinned($($(#[$($attr:tt)*])* $fvis:vis $field:ident : $type:ty),* $(,)?),1052) => {1053$crate::macros::paste! {1054// For every field, we create a projection function according to its projection type. If a1055// field is structurally pinned, then it must be initialized via `PinInit`, if it is not1056// structurally pinned, then it can be initialized via `Init`.1057//1058// The functions are `unsafe` to prevent accidentally calling them.1059#[allow(dead_code)]1060#[expect(clippy::missing_safety_doc)]1061impl<$($impl_generics)*> $pin_data<$($ty_generics)*>1062where $($whr)*1063{1064$(1065$(#[$($p_attr)*])*1066$pvis unsafe fn $p_field<E>(1067self,1068slot: *mut $p_type,1069init: impl $crate::PinInit<$p_type, E>,1070) -> ::core::result::Result<(), E> {1071// SAFETY: TODO.1072unsafe { $crate::PinInit::__pinned_init(init, slot) }1073}10741075$(#[$($p_attr)*])*1076$pvis unsafe fn [<__project_ $p_field>]<'__slot>(1077self,1078slot: &'__slot mut $p_type,1079) -> ::core::pin::Pin<&'__slot mut $p_type> {1080::core::pin::Pin::new_unchecked(slot)1081}1082)*1083$(1084$(#[$($attr)*])*1085$fvis unsafe fn $field<E>(1086self,1087slot: *mut $type,1088init: impl $crate::Init<$type, E>,1089) -> ::core::result::Result<(), E> {1090// SAFETY: TODO.1091unsafe { $crate::Init::__init(init, slot) }1092}10931094$(#[$($attr)*])*1095$fvis unsafe fn [<__project_ $field>]<'__slot>(1096self,1097slot: &'__slot mut $type,1098) -> &'__slot mut $type {1099slot1100}1101)*1102}1103}1104};1105}11061107/// The internal init macro. Do not call manually!1108///1109/// This is called by the `{try_}{pin_}init!` macros with various inputs.1110///1111/// This macro has multiple internal call configurations, these are always the very first ident:1112/// - nothing: this is the base case and called by the `{try_}{pin_}init!` macros.1113/// - `with_update_parsed`: when the `..Zeroable::init_zeroed()` syntax has been handled.1114/// - `init_slot`: recursively creates the code that initializes all fields in `slot`.1115/// - `make_initializer`: recursively create the struct initializer that guarantees that every1116/// field has been initialized exactly once.1117#[doc(hidden)]1118#[macro_export]1119macro_rules! __init_internal {1120(1121@this($($this:ident)?),1122@typ($t:path),1123@fields($($fields:tt)*),1124@error($err:ty),1125// Either `PinData` or `InitData`, `$use_data` should only be present in the `PinData`1126// case.1127@data($data:ident, $($use_data:ident)?),1128// `HasPinData` or `HasInitData`.1129@has_data($has_data:ident, $get_data:ident),1130// `pin_init_from_closure` or `init_from_closure`.1131@construct_closure($construct_closure:ident),1132@munch_fields(),1133) => {1134$crate::__init_internal!(with_update_parsed:1135@this($($this)?),1136@typ($t),1137@fields($($fields)*),1138@error($err),1139@data($data, $($use_data)?),1140@has_data($has_data, $get_data),1141@construct_closure($construct_closure),1142@init_zeroed(), // Nothing means default behavior.1143)1144};1145(1146@this($($this:ident)?),1147@typ($t:path),1148@fields($($fields:tt)*),1149@error($err:ty),1150// Either `PinData` or `InitData`, `$use_data` should only be present in the `PinData`1151// case.1152@data($data:ident, $($use_data:ident)?),1153// `HasPinData` or `HasInitData`.1154@has_data($has_data:ident, $get_data:ident),1155// `pin_init_from_closure` or `init_from_closure`.1156@construct_closure($construct_closure:ident),1157@munch_fields(..Zeroable::init_zeroed()),1158) => {1159$crate::__init_internal!(with_update_parsed:1160@this($($this)?),1161@typ($t),1162@fields($($fields)*),1163@error($err),1164@data($data, $($use_data)?),1165@has_data($has_data, $get_data),1166@construct_closure($construct_closure),1167@init_zeroed(()), // `()` means zero all fields not mentioned.1168)1169};1170(1171@this($($this:ident)?),1172@typ($t:path),1173@fields($($fields:tt)*),1174@error($err:ty),1175// Either `PinData` or `InitData`, `$use_data` should only be present in the `PinData`1176// case.1177@data($data:ident, $($use_data:ident)?),1178// `HasPinData` or `HasInitData`.1179@has_data($has_data:ident, $get_data:ident),1180// `pin_init_from_closure` or `init_from_closure`.1181@construct_closure($construct_closure:ident),1182@munch_fields($ignore:tt $($rest:tt)*),1183) => {1184$crate::__init_internal!(1185@this($($this)?),1186@typ($t),1187@fields($($fields)*),1188@error($err),1189@data($data, $($use_data)?),1190@has_data($has_data, $get_data),1191@construct_closure($construct_closure),1192@munch_fields($($rest)*),1193)1194};1195(with_update_parsed:1196@this($($this:ident)?),1197@typ($t:path),1198@fields($($fields:tt)*),1199@error($err:ty),1200// Either `PinData` or `InitData`, `$use_data` should only be present in the `PinData`1201// case.1202@data($data:ident, $($use_data:ident)?),1203// `HasPinData` or `HasInitData`.1204@has_data($has_data:ident, $get_data:ident),1205// `pin_init_from_closure` or `init_from_closure`.1206@construct_closure($construct_closure:ident),1207@init_zeroed($($init_zeroed:expr)?),1208) => {{1209// We do not want to allow arbitrary returns, so we declare this type as the `Ok` return1210// type and shadow it later when we insert the arbitrary user code. That way there will be1211// no possibility of returning without `unsafe`.1212struct __InitOk;1213// Get the data about fields from the supplied type.1214//1215// SAFETY: TODO.1216let data = unsafe {1217use $crate::__internal::$has_data;1218// Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal1219// information that is associated to already parsed fragments, so a path fragment1220// cannot be used in this position. Doing the retokenization results in valid rust1221// code.1222$crate::macros::paste!($t::$get_data())1223};1224// Ensure that `data` really is of type `$data` and help with type inference:1225let init = $crate::__internal::$data::make_closure::<_, __InitOk, $err>(1226data,1227move |slot| {1228{1229// Shadow the structure so it cannot be used to return early.1230struct __InitOk;1231// If `$init_zeroed` is present we should zero the slot now and not emit an1232// error when fields are missing (since they will be zeroed). We also have to1233// check that the type actually implements `Zeroable`.1234$({1235fn assert_zeroable<T: $crate::Zeroable>(_: *mut T) {}1236// Ensure that the struct is indeed `Zeroable`.1237assert_zeroable(slot);1238// SAFETY: The type implements `Zeroable` by the check above.1239unsafe { ::core::ptr::write_bytes(slot, 0, 1) };1240$init_zeroed // This will be `()` if set.1241})?1242// Create the `this` so it can be referenced by the user inside of the1243// expressions creating the individual fields.1244$(let $this = unsafe { ::core::ptr::NonNull::new_unchecked(slot) };)?1245// Initialize every field.1246$crate::__init_internal!(init_slot($($use_data)?):1247@data(data),1248@slot(slot),1249@guards(),1250@munch_fields($($fields)*,),1251);1252// We use unreachable code to ensure that all fields have been mentioned exactly1253// once, this struct initializer will still be type-checked and complain with a1254// very natural error message if a field is forgotten/mentioned more than once.1255#[allow(unreachable_code, clippy::diverging_sub_expression)]1256let _ = || {1257$crate::__init_internal!(make_initializer:1258@slot(slot),1259@type_name($t),1260@munch_fields($($fields)*,),1261@acc(),1262);1263};1264}1265Ok(__InitOk)1266}1267);1268let init = move |slot| -> ::core::result::Result<(), $err> {1269init(slot).map(|__InitOk| ())1270};1271// SAFETY: TODO.1272let init = unsafe { $crate::$construct_closure::<_, $err>(init) };1273init1274}};1275(init_slot($($use_data:ident)?):1276@data($data:ident),1277@slot($slot:ident),1278@guards($($guards:ident,)*),1279@munch_fields($(..Zeroable::init_zeroed())? $(,)?),1280) => {1281// Endpoint of munching, no fields are left. If execution reaches this point, all fields1282// have been initialized. Therefore we can now dismiss the guards by forgetting them.1283$(::core::mem::forget($guards);)*1284};1285(init_slot($($use_data:ident)?):1286@data($data:ident),1287@slot($slot:ident),1288@guards($($guards:ident,)*),1289// arbitrary code block1290@munch_fields(_: { $($code:tt)* }, $($rest:tt)*),1291) => {1292{ $($code)* }1293$crate::__init_internal!(init_slot($($use_data)?):1294@data($data),1295@slot($slot),1296@guards($($guards,)*),1297@munch_fields($($rest)*),1298);1299};1300(init_slot($use_data:ident): // `use_data` is present, so we use the `data` to init fields.1301@data($data:ident),1302@slot($slot:ident),1303@guards($($guards:ident,)*),1304// In-place initialization syntax.1305@munch_fields($field:ident <- $val:expr, $($rest:tt)*),1306) => {1307let init = $val;1308// Call the initializer.1309//1310// SAFETY: `slot` is valid, because we are inside of an initializer closure, we1311// return when an error/panic occurs.1312// We also use the `data` to require the correct trait (`Init` or `PinInit`) for `$field`.1313unsafe { $data.$field(::core::ptr::addr_of_mut!((*$slot).$field), init)? };1314// SAFETY:1315// - the project function does the correct field projection,1316// - the field has been initialized,1317// - the reference is only valid until the end of the initializer.1318#[allow(unused_variables)]1319let $field = $crate::macros::paste!(unsafe { $data.[< __project_ $field >](&mut (*$slot).$field) });13201321// Create the drop guard:1322//1323// We rely on macro hygiene to make it impossible for users to access this local variable.1324// We use `paste!` to create new hygiene for `$field`.1325$crate::macros::paste! {1326// SAFETY: We forget the guard later when initialization has succeeded.1327let [< __ $field _guard >] = unsafe {1328$crate::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field))1329};13301331$crate::__init_internal!(init_slot($use_data):1332@data($data),1333@slot($slot),1334@guards([< __ $field _guard >], $($guards,)*),1335@munch_fields($($rest)*),1336);1337}1338};1339(init_slot(): // No `use_data`, so we use `Init::__init` directly.1340@data($data:ident),1341@slot($slot:ident),1342@guards($($guards:ident,)*),1343// In-place initialization syntax.1344@munch_fields($field:ident <- $val:expr, $($rest:tt)*),1345) => {1346let init = $val;1347// Call the initializer.1348//1349// SAFETY: `slot` is valid, because we are inside of an initializer closure, we1350// return when an error/panic occurs.1351unsafe { $crate::Init::__init(init, ::core::ptr::addr_of_mut!((*$slot).$field))? };13521353// SAFETY:1354// - the field is not structurally pinned, since the line above must compile,1355// - the field has been initialized,1356// - the reference is only valid until the end of the initializer.1357#[allow(unused_variables)]1358let $field = unsafe { &mut (*$slot).$field };13591360// Create the drop guard:1361//1362// We rely on macro hygiene to make it impossible for users to access this local variable.1363// We use `paste!` to create new hygiene for `$field`.1364$crate::macros::paste! {1365// SAFETY: We forget the guard later when initialization has succeeded.1366let [< __ $field _guard >] = unsafe {1367$crate::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field))1368};13691370$crate::__init_internal!(init_slot():1371@data($data),1372@slot($slot),1373@guards([< __ $field _guard >], $($guards,)*),1374@munch_fields($($rest)*),1375);1376}1377};1378(init_slot(): // No `use_data`, so all fields are not structurally pinned1379@data($data:ident),1380@slot($slot:ident),1381@guards($($guards:ident,)*),1382// Init by-value.1383@munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*),1384) => {1385{1386$(let $field = $val;)?1387// Initialize the field.1388//1389// SAFETY: The memory at `slot` is uninitialized.1390unsafe { ::core::ptr::write(::core::ptr::addr_of_mut!((*$slot).$field), $field) };1391}13921393#[allow(unused_variables)]1394// SAFETY:1395// - the field is not structurally pinned, since no `use_data` was required to create this1396// initializer,1397// - the field has been initialized,1398// - the reference is only valid until the end of the initializer.1399let $field = unsafe { &mut (*$slot).$field };14001401// Create the drop guard:1402//1403// We rely on macro hygiene to make it impossible for users to access this local variable.1404// We use `paste!` to create new hygiene for `$field`.1405$crate::macros::paste! {1406// SAFETY: We forget the guard later when initialization has succeeded.1407let [< __ $field _guard >] = unsafe {1408$crate::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field))1409};14101411$crate::__init_internal!(init_slot():1412@data($data),1413@slot($slot),1414@guards([< __ $field _guard >], $($guards,)*),1415@munch_fields($($rest)*),1416);1417}1418};1419(init_slot($use_data:ident):1420@data($data:ident),1421@slot($slot:ident),1422@guards($($guards:ident,)*),1423// Init by-value.1424@munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*),1425) => {1426{1427$(let $field = $val;)?1428// Initialize the field.1429//1430// SAFETY: The memory at `slot` is uninitialized.1431unsafe { ::core::ptr::write(::core::ptr::addr_of_mut!((*$slot).$field), $field) };1432}1433// SAFETY:1434// - the project function does the correct field projection,1435// - the field has been initialized,1436// - the reference is only valid until the end of the initializer.1437#[allow(unused_variables)]1438let $field = $crate::macros::paste!(unsafe { $data.[< __project_ $field >](&mut (*$slot).$field) });14391440// Create the drop guard:1441//1442// We rely on macro hygiene to make it impossible for users to access this local variable.1443// We use `paste!` to create new hygiene for `$field`.1444$crate::macros::paste! {1445// SAFETY: We forget the guard later when initialization has succeeded.1446let [< __ $field _guard >] = unsafe {1447$crate::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field))1448};14491450$crate::__init_internal!(init_slot($use_data):1451@data($data),1452@slot($slot),1453@guards([< __ $field _guard >], $($guards,)*),1454@munch_fields($($rest)*),1455);1456}1457};1458(make_initializer:1459@slot($slot:ident),1460@type_name($t:path),1461@munch_fields(_: { $($code:tt)* }, $($rest:tt)*),1462@acc($($acc:tt)*),1463) => {1464// code blocks are ignored for the initializer check1465$crate::__init_internal!(make_initializer:1466@slot($slot),1467@type_name($t),1468@munch_fields($($rest)*),1469@acc($($acc)*),1470);1471};1472(make_initializer:1473@slot($slot:ident),1474@type_name($t:path),1475@munch_fields(..Zeroable::init_zeroed() $(,)?),1476@acc($($acc:tt)*),1477) => {1478// Endpoint, nothing more to munch, create the initializer. Since the users specified1479// `..Zeroable::init_zeroed()`, the slot will already have been zeroed and all field that have1480// not been overwritten are thus zero and initialized. We still check that all fields are1481// actually accessible by using the struct update syntax ourselves.1482// We are inside of a closure that is never executed and thus we can abuse `slot` to1483// get the correct type inference here:1484#[allow(unused_assignments)]1485unsafe {1486let mut zeroed = ::core::mem::zeroed();1487// We have to use type inference here to make zeroed have the correct type. This does1488// not get executed, so it has no effect.1489::core::ptr::write($slot, zeroed);1490zeroed = ::core::mem::zeroed();1491// Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal1492// information that is associated to already parsed fragments, so a path fragment1493// cannot be used in this position. Doing the retokenization results in valid rust1494// code.1495$crate::macros::paste!(1496::core::ptr::write($slot, $t {1497$($acc)*1498..zeroed1499});1500);1501}1502};1503(make_initializer:1504@slot($slot:ident),1505@type_name($t:path),1506@munch_fields($(,)?),1507@acc($($acc:tt)*),1508) => {1509// Endpoint, nothing more to munch, create the initializer.1510// Since we are in the closure that is never called, this will never get executed.1511// We abuse `slot` to get the correct type inference here:1512//1513// SAFETY: TODO.1514unsafe {1515// Here we abuse `paste!` to retokenize `$t`. Declarative macros have some internal1516// information that is associated to already parsed fragments, so a path fragment1517// cannot be used in this position. Doing the retokenization results in valid rust1518// code.1519$crate::macros::paste!(1520::core::ptr::write($slot, $t {1521$($acc)*1522});1523);1524}1525};1526(make_initializer:1527@slot($slot:ident),1528@type_name($t:path),1529@munch_fields($field:ident <- $val:expr, $($rest:tt)*),1530@acc($($acc:tt)*),1531) => {1532$crate::__init_internal!(make_initializer:1533@slot($slot),1534@type_name($t),1535@munch_fields($($rest)*),1536@acc($($acc)* $field: ::core::panic!(),),1537);1538};1539(make_initializer:1540@slot($slot:ident),1541@type_name($t:path),1542@munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*),1543@acc($($acc:tt)*),1544) => {1545$crate::__init_internal!(make_initializer:1546@slot($slot),1547@type_name($t),1548@munch_fields($($rest)*),1549@acc($($acc)* $field: ::core::panic!(),),1550);1551};1552}15531554#[doc(hidden)]1555#[macro_export]1556macro_rules! __derive_zeroable {1557(parse_input:1558@sig(1559$(#[$($struct_attr:tt)*])*1560$vis:vis struct $name:ident1561$(where $($whr:tt)*)?1562),1563@impl_generics($($impl_generics:tt)*),1564@ty_generics($($ty_generics:tt)*),1565@body({1566$(1567$(#[$($field_attr:tt)*])*1568$field_vis:vis $field:ident : $field_ty:ty1569),* $(,)?1570}),1571) => {1572// SAFETY: Every field type implements `Zeroable` and padding bytes may be zero.1573#[automatically_derived]1574unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*>1575where1576$($($whr)*)?1577{}1578const _: () = {1579fn assert_zeroable<T: ?::core::marker::Sized + $crate::Zeroable>() {}1580fn ensure_zeroable<$($impl_generics)*>()1581where $($($whr)*)?1582{1583$(assert_zeroable::<$field_ty>();)*1584}1585};1586};1587(parse_input:1588@sig(1589$(#[$($struct_attr:tt)*])*1590$vis:vis union $name:ident1591$(where $($whr:tt)*)?1592),1593@impl_generics($($impl_generics:tt)*),1594@ty_generics($($ty_generics:tt)*),1595@body({1596$(1597$(#[$($field_attr:tt)*])*1598$field_vis:vis $field:ident : $field_ty:ty1599),* $(,)?1600}),1601) => {1602// SAFETY: Every field type implements `Zeroable` and padding bytes may be zero.1603#[automatically_derived]1604unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*>1605where1606$($($whr)*)?1607{}1608const _: () = {1609fn assert_zeroable<T: ?::core::marker::Sized + $crate::Zeroable>() {}1610fn ensure_zeroable<$($impl_generics)*>()1611where $($($whr)*)?1612{1613$(assert_zeroable::<$field_ty>();)*1614}1615};1616};1617}16181619#[doc(hidden)]1620#[macro_export]1621macro_rules! __maybe_derive_zeroable {1622(parse_input:1623@sig(1624$(#[$($struct_attr:tt)*])*1625$vis:vis struct $name:ident1626$(where $($whr:tt)*)?1627),1628@impl_generics($($impl_generics:tt)*),1629@ty_generics($($ty_generics:tt)*),1630@body({1631$(1632$(#[$($field_attr:tt)*])*1633$field_vis:vis $field:ident : $field_ty:ty1634),* $(,)?1635}),1636) => {1637// SAFETY: Every field type implements `Zeroable` and padding bytes may be zero.1638#[automatically_derived]1639unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*>1640where1641$(1642// the `for<'__dummy>` HRTB makes this not error without the `trivial_bounds`1643// feature <https://github.com/rust-lang/rust/issues/48214#issuecomment-2557829956>.1644$field_ty: for<'__dummy> $crate::Zeroable,1645)*1646$($($whr)*)?1647{}1648};1649(parse_input:1650@sig(1651$(#[$($struct_attr:tt)*])*1652$vis:vis union $name:ident1653$(where $($whr:tt)*)?1654),1655@impl_generics($($impl_generics:tt)*),1656@ty_generics($($ty_generics:tt)*),1657@body({1658$(1659$(#[$($field_attr:tt)*])*1660$field_vis:vis $field:ident : $field_ty:ty1661),* $(,)?1662}),1663) => {1664// SAFETY: Every field type implements `Zeroable` and padding bytes may be zero.1665#[automatically_derived]1666unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*>1667where1668$(1669// the `for<'__dummy>` HRTB makes this not error without the `trivial_bounds`1670// feature <https://github.com/rust-lang/rust/issues/48214#issuecomment-2557829956>.1671$field_ty: for<'__dummy> $crate::Zeroable,1672)*1673$($($whr)*)?1674{}1675};1676}167716781679