xref: /openbmc/linux/rust/kernel/init/macros.rs (revision 309786c2393c7b3375c232b137e52613c8099327)
1fc6c6baaSBenno Lossin // SPDX-License-Identifier: Apache-2.0 OR MIT
2fc6c6baaSBenno Lossin 
3fc6c6baaSBenno Lossin //! This module provides the macros that actually implement the proc-macros `pin_data` and
4fc6c6baaSBenno Lossin //! `pinned_drop`.
5fc6c6baaSBenno Lossin //!
6fc6c6baaSBenno Lossin //! These macros should never be called directly, since they expect their input to be
7fc6c6baaSBenno Lossin //! in a certain format which is internal. Use the proc-macros instead.
8fc6c6baaSBenno Lossin //!
9fc6c6baaSBenno Lossin //! This architecture has been chosen because the kernel does not yet have access to `syn` which
10fc6c6baaSBenno Lossin //! would make matters a lot easier for implementing these as proc-macros.
11fc6c6baaSBenno Lossin //!
12fc6c6baaSBenno Lossin //! # Macro expansion example
13fc6c6baaSBenno Lossin //!
14fc6c6baaSBenno Lossin //! This section is intended for readers trying to understand the macros in this module and the
15fc6c6baaSBenno Lossin //! `pin_init!` macros from `init.rs`.
16fc6c6baaSBenno Lossin //!
17fc6c6baaSBenno Lossin //! We will look at the following example:
18fc6c6baaSBenno Lossin //!
19*309786c2SBenno Lossin //! ```rust,ignore
20fc6c6baaSBenno Lossin //! # use kernel::init::*;
21*309786c2SBenno Lossin //! # use core::pin::Pin;
22fc6c6baaSBenno Lossin //! #[pin_data]
23fc6c6baaSBenno Lossin //! #[repr(C)]
24fc6c6baaSBenno Lossin //! struct Bar<T> {
25fc6c6baaSBenno Lossin //!     #[pin]
26fc6c6baaSBenno Lossin //!     t: T,
27fc6c6baaSBenno Lossin //!     pub x: usize,
28fc6c6baaSBenno Lossin //! }
29fc6c6baaSBenno Lossin //!
30fc6c6baaSBenno Lossin //! impl<T> Bar<T> {
31fc6c6baaSBenno Lossin //!     fn new(t: T) -> impl PinInit<Self> {
32fc6c6baaSBenno Lossin //!         pin_init!(Self { t, x: 0 })
33fc6c6baaSBenno Lossin //!     }
34fc6c6baaSBenno Lossin //! }
35d0fdc396SBenno Lossin //!
36d0fdc396SBenno Lossin //! #[pin_data(PinnedDrop)]
37d0fdc396SBenno Lossin //! struct Foo {
38d0fdc396SBenno Lossin //!     a: usize,
39d0fdc396SBenno Lossin //!     #[pin]
40d0fdc396SBenno Lossin //!     b: Bar<u32>,
41d0fdc396SBenno Lossin //! }
42d0fdc396SBenno Lossin //!
43d0fdc396SBenno Lossin //! #[pinned_drop]
44d0fdc396SBenno Lossin //! impl PinnedDrop for Foo {
45d0fdc396SBenno Lossin //!     fn drop(self: Pin<&mut Self>) {
46d0fdc396SBenno Lossin //!         println!("{self:p} is getting dropped.");
47d0fdc396SBenno Lossin //!     }
48d0fdc396SBenno Lossin //! }
49d0fdc396SBenno Lossin //!
50d0fdc396SBenno Lossin //! let a = 42;
51d0fdc396SBenno Lossin //! let initializer = pin_init!(Foo {
52d0fdc396SBenno Lossin //!     a,
53d0fdc396SBenno Lossin //!     b <- Bar::new(36),
54d0fdc396SBenno Lossin //! });
55fc6c6baaSBenno Lossin //! ```
56fc6c6baaSBenno Lossin //!
57fc6c6baaSBenno Lossin //! This example includes the most common and important features of the pin-init API.
58fc6c6baaSBenno Lossin //!
59fc6c6baaSBenno Lossin //! Below you can find individual section about the different macro invocations. Here are some
60fc6c6baaSBenno Lossin //! general things we need to take into account when designing macros:
61fc6c6baaSBenno Lossin //! - use global paths, similarly to file paths, these start with the separator: `::core::panic!()`
62fc6c6baaSBenno Lossin //!   this ensures that the correct item is used, since users could define their own `mod core {}`
63fc6c6baaSBenno Lossin //!   and then their own `panic!` inside to execute arbitrary code inside of our macro.
64fc6c6baaSBenno Lossin //! - macro `unsafe` hygiene: we need to ensure that we do not expand arbitrary, user-supplied
65fc6c6baaSBenno Lossin //!   expressions inside of an `unsafe` block in the macro, because this would allow users to do
66fc6c6baaSBenno Lossin //!   `unsafe` operations without an associated `unsafe` block.
67fc6c6baaSBenno Lossin //!
68fc6c6baaSBenno Lossin //! ## `#[pin_data]` on `Bar`
69fc6c6baaSBenno Lossin //!
70fc6c6baaSBenno Lossin //! This macro is used to specify which fields are structurally pinned and which fields are not. It
71fc6c6baaSBenno Lossin //! is placed on the struct definition and allows `#[pin]` to be placed on the fields.
72fc6c6baaSBenno Lossin //!
73fc6c6baaSBenno Lossin //! Here is the definition of `Bar` from our example:
74fc6c6baaSBenno Lossin //!
75*309786c2SBenno Lossin //! ```rust,ignore
76fc6c6baaSBenno Lossin //! # use kernel::init::*;
77fc6c6baaSBenno Lossin //! #[pin_data]
78fc6c6baaSBenno Lossin //! #[repr(C)]
79fc6c6baaSBenno Lossin //! struct Bar<T> {
80*309786c2SBenno Lossin //!     #[pin]
81fc6c6baaSBenno Lossin //!     t: T,
82fc6c6baaSBenno Lossin //!     pub x: usize,
83fc6c6baaSBenno Lossin //! }
84fc6c6baaSBenno Lossin //! ```
85fc6c6baaSBenno Lossin //!
86fc6c6baaSBenno Lossin //! This expands to the following code:
87fc6c6baaSBenno Lossin //!
88*309786c2SBenno Lossin //! ```rust,ignore
89fc6c6baaSBenno Lossin //! // Firstly the normal definition of the struct, attributes are preserved:
90fc6c6baaSBenno Lossin //! #[repr(C)]
91fc6c6baaSBenno Lossin //! struct Bar<T> {
92fc6c6baaSBenno Lossin //!     t: T,
93fc6c6baaSBenno Lossin //!     pub x: usize,
94fc6c6baaSBenno Lossin //! }
95fc6c6baaSBenno Lossin //! // Then an anonymous constant is defined, this is because we do not want any code to access the
96fc6c6baaSBenno Lossin //! // types that we define inside:
97fc6c6baaSBenno Lossin //! const _: () = {
98fc6c6baaSBenno Lossin //!     // We define the pin-data carrying struct, it is a ZST and needs to have the same generics,
99fc6c6baaSBenno Lossin //!     // since we need to implement access functions for each field and thus need to know its
100fc6c6baaSBenno Lossin //!     // type.
101fc6c6baaSBenno Lossin //!     struct __ThePinData<T> {
102fc6c6baaSBenno Lossin //!         __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,
103fc6c6baaSBenno Lossin //!     }
104fc6c6baaSBenno Lossin //!     // We implement `Copy` for the pin-data struct, since all functions it defines will take
105fc6c6baaSBenno Lossin //!     // `self` by value.
106fc6c6baaSBenno Lossin //!     impl<T> ::core::clone::Clone for __ThePinData<T> {
107fc6c6baaSBenno Lossin //!         fn clone(&self) -> Self {
108fc6c6baaSBenno Lossin //!             *self
109fc6c6baaSBenno Lossin //!         }
110fc6c6baaSBenno Lossin //!     }
111fc6c6baaSBenno Lossin //!     impl<T> ::core::marker::Copy for __ThePinData<T> {}
112fc6c6baaSBenno Lossin //!     // For every field of `Bar`, the pin-data struct will define a function with the same name
113fc6c6baaSBenno Lossin //!     // and accessor (`pub` or `pub(crate)` etc.). This function will take a pointer to the
114fc6c6baaSBenno Lossin //!     // field (`slot`) and a `PinInit` or `Init` depending on the projection kind of the field
115fc6c6baaSBenno Lossin //!     // (if pinning is structural for the field, then `PinInit` otherwise `Init`).
116fc6c6baaSBenno Lossin //!     #[allow(dead_code)]
117fc6c6baaSBenno Lossin //!     impl<T> __ThePinData<T> {
118fc6c6baaSBenno Lossin //!         unsafe fn t<E>(
119fc6c6baaSBenno Lossin //!             self,
120fc6c6baaSBenno Lossin //!             slot: *mut T,
121*309786c2SBenno Lossin //!             // Since `t` is `#[pin]`, this is `PinInit`.
122*309786c2SBenno Lossin //!             init: impl ::kernel::init::PinInit<T, E>,
123fc6c6baaSBenno Lossin //!         ) -> ::core::result::Result<(), E> {
124*309786c2SBenno Lossin //!             unsafe { ::kernel::init::PinInit::__pinned_init(init, slot) }
125fc6c6baaSBenno Lossin //!         }
126fc6c6baaSBenno Lossin //!         pub unsafe fn x<E>(
127fc6c6baaSBenno Lossin //!             self,
128fc6c6baaSBenno Lossin //!             slot: *mut usize,
129*309786c2SBenno Lossin //!             // Since `x` is not `#[pin]`, this is `Init`.
130fc6c6baaSBenno Lossin //!             init: impl ::kernel::init::Init<usize, E>,
131fc6c6baaSBenno Lossin //!         ) -> ::core::result::Result<(), E> {
132fc6c6baaSBenno Lossin //!             unsafe { ::kernel::init::Init::__init(init, slot) }
133fc6c6baaSBenno Lossin //!         }
134fc6c6baaSBenno Lossin //!     }
135fc6c6baaSBenno Lossin //!     // Implement the internal `HasPinData` trait that associates `Bar` with the pin-data struct
136*309786c2SBenno Lossin //!     // that we constructed above.
137fc6c6baaSBenno Lossin //!     unsafe impl<T> ::kernel::init::__internal::HasPinData for Bar<T> {
138fc6c6baaSBenno Lossin //!         type PinData = __ThePinData<T>;
139fc6c6baaSBenno Lossin //!         unsafe fn __pin_data() -> Self::PinData {
140fc6c6baaSBenno Lossin //!             __ThePinData {
141fc6c6baaSBenno Lossin //!                 __phantom: ::core::marker::PhantomData,
142fc6c6baaSBenno Lossin //!             }
143fc6c6baaSBenno Lossin //!         }
144fc6c6baaSBenno Lossin //!     }
145fc6c6baaSBenno Lossin //!     // Implement the internal `PinData` trait that marks the pin-data struct as a pin-data
146fc6c6baaSBenno Lossin //!     // struct. This is important to ensure that no user can implement a rouge `__pin_data`
147fc6c6baaSBenno Lossin //!     // function without using `unsafe`.
148fc6c6baaSBenno Lossin //!     unsafe impl<T> ::kernel::init::__internal::PinData for __ThePinData<T> {
149fc6c6baaSBenno Lossin //!         type Datee = Bar<T>;
150fc6c6baaSBenno Lossin //!     }
151fc6c6baaSBenno Lossin //!     // Now we only want to implement `Unpin` for `Bar` when every structurally pinned field is
152fc6c6baaSBenno Lossin //!     // `Unpin`. In other words, whether `Bar` is `Unpin` only depends on structurally pinned
153fc6c6baaSBenno Lossin //!     // fields (those marked with `#[pin]`). These fields will be listed in this struct, in our
154fc6c6baaSBenno Lossin //!     // case no such fields exist, hence this is almost empty. The two phantomdata fields exist
155fc6c6baaSBenno Lossin //!     // for two reasons:
156fc6c6baaSBenno Lossin //!     // - `__phantom`: every generic must be used, since we cannot really know which generics
157fc6c6baaSBenno Lossin //!     //   are used, we declere all and then use everything here once.
158fc6c6baaSBenno Lossin //!     // - `__phantom_pin`: uses the `'__pin` lifetime and ensures that this struct is invariant
159fc6c6baaSBenno Lossin //!     //   over it. The lifetime is needed to work around the limitation that trait bounds must
160fc6c6baaSBenno Lossin //!     //   not be trivial, e.g. the user has a `#[pin] PhantomPinned` field -- this is
161fc6c6baaSBenno Lossin //!     //   unconditionally `!Unpin` and results in an error. The lifetime tricks the compiler
162fc6c6baaSBenno Lossin //!     //   into accepting these bounds regardless.
163fc6c6baaSBenno Lossin //!     #[allow(dead_code)]
164fc6c6baaSBenno Lossin //!     struct __Unpin<'__pin, T> {
165fc6c6baaSBenno Lossin //!         __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
166fc6c6baaSBenno Lossin //!         __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,
167*309786c2SBenno Lossin //!         // Our only `#[pin]` field is `t`.
168*309786c2SBenno Lossin //!         t: T,
169fc6c6baaSBenno Lossin //!     }
170fc6c6baaSBenno Lossin //!     #[doc(hidden)]
171fc6c6baaSBenno Lossin //!     impl<'__pin, T>
172fc6c6baaSBenno Lossin //!         ::core::marker::Unpin for Bar<T> where __Unpin<'__pin, T>: ::core::marker::Unpin {}
173fc6c6baaSBenno Lossin //!     // Now we need to ensure that `Bar` does not implement `Drop`, since that would give users
174fc6c6baaSBenno Lossin //!     // access to `&mut self` inside of `drop` even if the struct was pinned. This could lead to
175fc6c6baaSBenno Lossin //!     // UB with only safe code, so we disallow this by giving a trait implementation error using
176fc6c6baaSBenno Lossin //!     // a direct impl and a blanket implementation.
177fc6c6baaSBenno Lossin //!     trait MustNotImplDrop {}
178fc6c6baaSBenno Lossin //!     // Normally `Drop` bounds do not have the correct semantics, but for this purpose they do
179fc6c6baaSBenno Lossin //!     // (normally people want to know if a type has any kind of drop glue at all, here we want
180fc6c6baaSBenno Lossin //!     // to know if it has any kind of custom drop glue, which is exactly what this bound does).
181fc6c6baaSBenno Lossin //!     #[allow(drop_bounds)]
182fc6c6baaSBenno Lossin //!     impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
183fc6c6baaSBenno Lossin //!     impl<T> MustNotImplDrop for Bar<T> {}
184d0fdc396SBenno Lossin //!     // Here comes a convenience check, if one implemented `PinnedDrop`, but forgot to add it to
185d0fdc396SBenno Lossin //!     // `#[pin_data]`, then this will error with the same mechanic as above, this is not needed
186d0fdc396SBenno Lossin //!     // for safety, but a good sanity check, since no normal code calls `PinnedDrop::drop`.
187d0fdc396SBenno Lossin //!     #[allow(non_camel_case_types)]
188d0fdc396SBenno Lossin //!     trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
189d0fdc396SBenno Lossin //!     impl<T: ::kernel::init::PinnedDrop>
190d0fdc396SBenno Lossin //!         UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
191d0fdc396SBenno Lossin //!     impl<T> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for Bar<T> {}
192fc6c6baaSBenno Lossin //! };
193fc6c6baaSBenno Lossin //! ```
194fc6c6baaSBenno Lossin //!
195fc6c6baaSBenno Lossin //! ## `pin_init!` in `impl Bar`
196fc6c6baaSBenno Lossin //!
197fc6c6baaSBenno Lossin //! This macro creates an pin-initializer for the given struct. It requires that the struct is
198fc6c6baaSBenno Lossin //! annotated by `#[pin_data]`.
199fc6c6baaSBenno Lossin //!
200fc6c6baaSBenno Lossin //! Here is the impl on `Bar` defining the new function:
201fc6c6baaSBenno Lossin //!
202*309786c2SBenno Lossin //! ```rust,ignore
203fc6c6baaSBenno Lossin //! impl<T> Bar<T> {
204fc6c6baaSBenno Lossin //!     fn new(t: T) -> impl PinInit<Self> {
205fc6c6baaSBenno Lossin //!         pin_init!(Self { t, x: 0 })
206fc6c6baaSBenno Lossin //!     }
207fc6c6baaSBenno Lossin //! }
208fc6c6baaSBenno Lossin //! ```
209fc6c6baaSBenno Lossin //!
210fc6c6baaSBenno Lossin //! This expands to the following code:
211fc6c6baaSBenno Lossin //!
212*309786c2SBenno Lossin //! ```rust,ignore
213fc6c6baaSBenno Lossin //! impl<T> Bar<T> {
214fc6c6baaSBenno Lossin //!     fn new(t: T) -> impl PinInit<Self> {
215fc6c6baaSBenno Lossin //!         {
216fc6c6baaSBenno Lossin //!             // We do not want to allow arbitrary returns, so we declare this type as the `Ok`
217fc6c6baaSBenno Lossin //!             // return type and shadow it later when we insert the arbitrary user code. That way
218fc6c6baaSBenno Lossin //!             // there will be no possibility of returning without `unsafe`.
219fc6c6baaSBenno Lossin //!             struct __InitOk;
220fc6c6baaSBenno Lossin //!             // Get the pin-data type from the initialized type.
221fc6c6baaSBenno Lossin //!             // - the function is unsafe, hence the unsafe block
222fc6c6baaSBenno Lossin //!             // - we `use` the `HasPinData` trait in the block, it is only available in that
223fc6c6baaSBenno Lossin //!             //   scope.
224fc6c6baaSBenno Lossin //!             let data = unsafe {
225fc6c6baaSBenno Lossin //!                 use ::kernel::init::__internal::HasPinData;
226fc6c6baaSBenno Lossin //!                 Self::__pin_data()
227fc6c6baaSBenno Lossin //!             };
228fc6c6baaSBenno Lossin //!             // Use `data` to help with type inference, the closure supplied will have the type
229fc6c6baaSBenno Lossin //!             // `FnOnce(*mut Self) -> Result<__InitOk, Infallible>`.
230fc6c6baaSBenno Lossin //!             let init = ::kernel::init::__internal::PinData::make_closure::<
231fc6c6baaSBenno Lossin //!                 _,
232fc6c6baaSBenno Lossin //!                 __InitOk,
233fc6c6baaSBenno Lossin //!                 ::core::convert::Infallible,
234fc6c6baaSBenno Lossin //!             >(data, move |slot| {
235fc6c6baaSBenno Lossin //!                 {
236fc6c6baaSBenno Lossin //!                     // Shadow the structure so it cannot be used to return early. If a user
237fc6c6baaSBenno Lossin //!                     // tries to write `return Ok(__InitOk)`, then they get a type error, since
238fc6c6baaSBenno Lossin //!                     // that will refer to this struct instead of the one defined above.
239fc6c6baaSBenno Lossin //!                     struct __InitOk;
240fc6c6baaSBenno Lossin //!                     // This is the expansion of `t,`, which is syntactic sugar for `t: t,`.
241*309786c2SBenno Lossin //!                     unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).t), t) };
242fc6c6baaSBenno Lossin //!                     // Since initialization could fail later (not in this case, since the error
243*309786c2SBenno Lossin //!                     // type is `Infallible`) we will need to drop this field if there is an
244*309786c2SBenno Lossin //!                     // error later. This `DropGuard` will drop the field when it gets dropped
245*309786c2SBenno Lossin //!                     // and has not yet been forgotten. We make a reference to it, so users
246*309786c2SBenno Lossin //!                     // cannot `mem::forget` it from the initializer, since the name is the same
247*309786c2SBenno Lossin //!                     // as the field (including hygiene).
248fc6c6baaSBenno Lossin //!                     let t = &unsafe {
249*309786c2SBenno Lossin //!                         ::kernel::init::__internal::DropGuard::new(
250*309786c2SBenno Lossin //!                             ::core::addr_of_mut!((*slot).t),
251*309786c2SBenno Lossin //!                         )
252fc6c6baaSBenno Lossin //!                     };
253fc6c6baaSBenno Lossin //!                     // Expansion of `x: 0,`:
254fc6c6baaSBenno Lossin //!                     // Since this can be an arbitrary expression we cannot place it inside of
255fc6c6baaSBenno Lossin //!                     // the `unsafe` block, so we bind it here.
256fc6c6baaSBenno Lossin //!                     let x = 0;
257*309786c2SBenno Lossin //!                     unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).x), x) };
258*309786c2SBenno Lossin //!                     // We again create a `DropGuard`.
259fc6c6baaSBenno Lossin //!                     let x = &unsafe {
260*309786c2SBenno Lossin //!                         ::kernel::init::__internal::DropGuard::new(
261*309786c2SBenno Lossin //!                             ::core::addr_of_mut!((*slot).x),
262*309786c2SBenno Lossin //!                         )
263fc6c6baaSBenno Lossin //!                     };
264fc6c6baaSBenno Lossin //!
265*309786c2SBenno Lossin //!                     // Here we use the type checker to ensure that every field has been
266fc6c6baaSBenno Lossin //!                     // initialized exactly once, since this is `if false` it will never get
267fc6c6baaSBenno Lossin //!                     // executed, but still type-checked.
268fc6c6baaSBenno Lossin //!                     // Additionally we abuse `slot` to automatically infer the correct type for
269fc6c6baaSBenno Lossin //!                     // the struct. This is also another check that every field is accessible
270fc6c6baaSBenno Lossin //!                     // from this scope.
271fc6c6baaSBenno Lossin //!                     #[allow(unreachable_code, clippy::diverging_sub_expression)]
272fc6c6baaSBenno Lossin //!                     if false {
273fc6c6baaSBenno Lossin //!                         unsafe {
274fc6c6baaSBenno Lossin //!                             ::core::ptr::write(
275fc6c6baaSBenno Lossin //!                                 slot,
276fc6c6baaSBenno Lossin //!                                 Self {
277fc6c6baaSBenno Lossin //!                                     // We only care about typecheck finding every field here,
278fc6c6baaSBenno Lossin //!                                     // the expression does not matter, just conjure one using
279fc6c6baaSBenno Lossin //!                                     // `panic!()`:
280fc6c6baaSBenno Lossin //!                                     t: ::core::panic!(),
281fc6c6baaSBenno Lossin //!                                     x: ::core::panic!(),
282fc6c6baaSBenno Lossin //!                                 },
283fc6c6baaSBenno Lossin //!                             );
284fc6c6baaSBenno Lossin //!                         };
285fc6c6baaSBenno Lossin //!                     }
286fc6c6baaSBenno Lossin //!                     // Since initialization has successfully completed, we can now forget the
287*309786c2SBenno Lossin //!                     // guards. This is not `mem::forget`, since we only have `&DropGuard`.
288fc6c6baaSBenno Lossin //!                     unsafe { ::kernel::init::__internal::DropGuard::forget(t) };
289fc6c6baaSBenno Lossin //!                     unsafe { ::kernel::init::__internal::DropGuard::forget(x) };
290fc6c6baaSBenno Lossin //!                 }
291fc6c6baaSBenno Lossin //!                 // We leave the scope above and gain access to the previously shadowed
292fc6c6baaSBenno Lossin //!                 // `__InitOk` that we need to return.
293fc6c6baaSBenno Lossin //!                 Ok(__InitOk)
294fc6c6baaSBenno Lossin //!             });
295*309786c2SBenno Lossin //!             // Change the return type from `__InitOk` to `()`.
296fc6c6baaSBenno Lossin //!             let init = move |slot| -> ::core::result::Result<(), ::core::convert::Infallible> {
297fc6c6baaSBenno Lossin //!                 init(slot).map(|__InitOk| ())
298fc6c6baaSBenno Lossin //!             };
299fc6c6baaSBenno Lossin //!             // Construct the initializer.
300fc6c6baaSBenno Lossin //!             let init = unsafe {
301fc6c6baaSBenno Lossin //!                 ::kernel::init::pin_init_from_closure::<_, ::core::convert::Infallible>(init)
302fc6c6baaSBenno Lossin //!             };
303fc6c6baaSBenno Lossin //!             init
304fc6c6baaSBenno Lossin //!         }
305fc6c6baaSBenno Lossin //!     }
306fc6c6baaSBenno Lossin //! }
307fc6c6baaSBenno Lossin //! ```
308d0fdc396SBenno Lossin //!
309d0fdc396SBenno Lossin //! ## `#[pin_data]` on `Foo`
310d0fdc396SBenno Lossin //!
311d0fdc396SBenno Lossin //! Since we already took a look at `#[pin_data]` on `Bar`, this section will only explain the
312d0fdc396SBenno Lossin //! differences/new things in the expansion of the `Foo` definition:
313d0fdc396SBenno Lossin //!
314*309786c2SBenno Lossin //! ```rust,ignore
315d0fdc396SBenno Lossin //! #[pin_data(PinnedDrop)]
316d0fdc396SBenno Lossin //! struct Foo {
317d0fdc396SBenno Lossin //!     a: usize,
318d0fdc396SBenno Lossin //!     #[pin]
319d0fdc396SBenno Lossin //!     b: Bar<u32>,
320d0fdc396SBenno Lossin //! }
321d0fdc396SBenno Lossin //! ```
322d0fdc396SBenno Lossin //!
323d0fdc396SBenno Lossin //! This expands to the following code:
324d0fdc396SBenno Lossin //!
325*309786c2SBenno Lossin //! ```rust,ignore
326d0fdc396SBenno Lossin //! struct Foo {
327d0fdc396SBenno Lossin //!     a: usize,
328d0fdc396SBenno Lossin //!     b: Bar<u32>,
329d0fdc396SBenno Lossin //! }
330d0fdc396SBenno Lossin //! const _: () = {
331d0fdc396SBenno Lossin //!     struct __ThePinData {
332d0fdc396SBenno Lossin //!         __phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
333d0fdc396SBenno Lossin //!     }
334d0fdc396SBenno Lossin //!     impl ::core::clone::Clone for __ThePinData {
335d0fdc396SBenno Lossin //!         fn clone(&self) -> Self {
336d0fdc396SBenno Lossin //!             *self
337d0fdc396SBenno Lossin //!         }
338d0fdc396SBenno Lossin //!     }
339d0fdc396SBenno Lossin //!     impl ::core::marker::Copy for __ThePinData {}
340d0fdc396SBenno Lossin //!     #[allow(dead_code)]
341d0fdc396SBenno Lossin //!     impl __ThePinData {
342d0fdc396SBenno Lossin //!         unsafe fn b<E>(
343d0fdc396SBenno Lossin //!             self,
344d0fdc396SBenno Lossin //!             slot: *mut Bar<u32>,
345d0fdc396SBenno Lossin //!             init: impl ::kernel::init::PinInit<Bar<u32>, E>,
346d0fdc396SBenno Lossin //!         ) -> ::core::result::Result<(), E> {
347d0fdc396SBenno Lossin //!             unsafe { ::kernel::init::PinInit::__pinned_init(init, slot) }
348d0fdc396SBenno Lossin //!         }
349d0fdc396SBenno Lossin //!         unsafe fn a<E>(
350d0fdc396SBenno Lossin //!             self,
351d0fdc396SBenno Lossin //!             slot: *mut usize,
352d0fdc396SBenno Lossin //!             init: impl ::kernel::init::Init<usize, E>,
353d0fdc396SBenno Lossin //!         ) -> ::core::result::Result<(), E> {
354d0fdc396SBenno Lossin //!             unsafe { ::kernel::init::Init::__init(init, slot) }
355d0fdc396SBenno Lossin //!         }
356d0fdc396SBenno Lossin //!     }
357d0fdc396SBenno Lossin //!     unsafe impl ::kernel::init::__internal::HasPinData for Foo {
358d0fdc396SBenno Lossin //!         type PinData = __ThePinData;
359d0fdc396SBenno Lossin //!         unsafe fn __pin_data() -> Self::PinData {
360d0fdc396SBenno Lossin //!             __ThePinData {
361d0fdc396SBenno Lossin //!                 __phantom: ::core::marker::PhantomData,
362d0fdc396SBenno Lossin //!             }
363d0fdc396SBenno Lossin //!         }
364d0fdc396SBenno Lossin //!     }
365d0fdc396SBenno Lossin //!     unsafe impl ::kernel::init::__internal::PinData for __ThePinData {
366d0fdc396SBenno Lossin //!         type Datee = Foo;
367d0fdc396SBenno Lossin //!     }
368d0fdc396SBenno Lossin //!     #[allow(dead_code)]
369d0fdc396SBenno Lossin //!     struct __Unpin<'__pin> {
370d0fdc396SBenno Lossin //!         __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
371d0fdc396SBenno Lossin //!         __phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
372d0fdc396SBenno Lossin //!         b: Bar<u32>,
373d0fdc396SBenno Lossin //!     }
374d0fdc396SBenno Lossin //!     #[doc(hidden)]
375d0fdc396SBenno Lossin //!     impl<'__pin> ::core::marker::Unpin for Foo where __Unpin<'__pin>: ::core::marker::Unpin {}
376d0fdc396SBenno Lossin //!     // Since we specified `PinnedDrop` as the argument to `#[pin_data]`, we expect `Foo` to
377d0fdc396SBenno Lossin //!     // implement `PinnedDrop`. Thus we do not need to prevent `Drop` implementations like
378*309786c2SBenno Lossin //!     // before, instead we implement `Drop` here and delegate to `PinnedDrop`.
379d0fdc396SBenno Lossin //!     impl ::core::ops::Drop for Foo {
380d0fdc396SBenno Lossin //!         fn drop(&mut self) {
381d0fdc396SBenno Lossin //!             // Since we are getting dropped, no one else has a reference to `self` and thus we
382d0fdc396SBenno Lossin //!             // can assume that we never move.
383d0fdc396SBenno Lossin //!             let pinned = unsafe { ::core::pin::Pin::new_unchecked(self) };
384d0fdc396SBenno Lossin //!             // Create the unsafe token that proves that we are inside of a destructor, this
385d0fdc396SBenno Lossin //!             // type is only allowed to be created in a destructor.
386d0fdc396SBenno Lossin //!             let token = unsafe { ::kernel::init::__internal::OnlyCallFromDrop::new() };
387d0fdc396SBenno Lossin //!             ::kernel::init::PinnedDrop::drop(pinned, token);
388d0fdc396SBenno Lossin //!         }
389d0fdc396SBenno Lossin //!     }
390d0fdc396SBenno Lossin //! };
391d0fdc396SBenno Lossin //! ```
392d0fdc396SBenno Lossin //!
393d0fdc396SBenno Lossin //! ## `#[pinned_drop]` on `impl PinnedDrop for Foo`
394d0fdc396SBenno Lossin //!
395d0fdc396SBenno Lossin //! This macro is used to implement the `PinnedDrop` trait, since that trait is `unsafe` and has an
396d0fdc396SBenno Lossin //! extra parameter that should not be used at all. The macro hides that parameter.
397d0fdc396SBenno Lossin //!
398d0fdc396SBenno Lossin //! Here is the `PinnedDrop` impl for `Foo`:
399d0fdc396SBenno Lossin //!
400*309786c2SBenno Lossin //! ```rust,ignore
401d0fdc396SBenno Lossin //! #[pinned_drop]
402d0fdc396SBenno Lossin //! impl PinnedDrop for Foo {
403d0fdc396SBenno Lossin //!     fn drop(self: Pin<&mut Self>) {
404d0fdc396SBenno Lossin //!         println!("{self:p} is getting dropped.");
405d0fdc396SBenno Lossin //!     }
406d0fdc396SBenno Lossin //! }
407d0fdc396SBenno Lossin //! ```
408d0fdc396SBenno Lossin //!
409d0fdc396SBenno Lossin //! This expands to the following code:
410d0fdc396SBenno Lossin //!
411*309786c2SBenno Lossin //! ```rust,ignore
412d0fdc396SBenno Lossin //! // `unsafe`, full path and the token parameter are added, everything else stays the same.
413d0fdc396SBenno Lossin //! unsafe impl ::kernel::init::PinnedDrop for Foo {
414d0fdc396SBenno Lossin //!     fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {
415d0fdc396SBenno Lossin //!         println!("{self:p} is getting dropped.");
416d0fdc396SBenno Lossin //!     }
417d0fdc396SBenno Lossin //! }
418d0fdc396SBenno Lossin //! ```
419d0fdc396SBenno Lossin //!
420d0fdc396SBenno Lossin //! ## `pin_init!` on `Foo`
421d0fdc396SBenno Lossin //!
422*309786c2SBenno Lossin //! Since we already took a look at `pin_init!` on `Bar`, this section will only show the expansion
423*309786c2SBenno Lossin //! of `pin_init!` on `Foo`:
424d0fdc396SBenno Lossin //!
425*309786c2SBenno Lossin //! ```rust,ignore
426d0fdc396SBenno Lossin //! let a = 42;
427d0fdc396SBenno Lossin //! let initializer = pin_init!(Foo {
428d0fdc396SBenno Lossin //!     a,
429d0fdc396SBenno Lossin //!     b <- Bar::new(36),
430d0fdc396SBenno Lossin //! });
431d0fdc396SBenno Lossin //! ```
432d0fdc396SBenno Lossin //!
433d0fdc396SBenno Lossin //! This expands to the following code:
434d0fdc396SBenno Lossin //!
435*309786c2SBenno Lossin //! ```rust,ignore
436d0fdc396SBenno Lossin //! let a = 42;
437d0fdc396SBenno Lossin //! let initializer = {
438d0fdc396SBenno Lossin //!     struct __InitOk;
439d0fdc396SBenno Lossin //!     let data = unsafe {
440d0fdc396SBenno Lossin //!         use ::kernel::init::__internal::HasPinData;
441d0fdc396SBenno Lossin //!         Foo::__pin_data()
442d0fdc396SBenno Lossin //!     };
443d0fdc396SBenno Lossin //!     let init = ::kernel::init::__internal::PinData::make_closure::<
444d0fdc396SBenno Lossin //!         _,
445d0fdc396SBenno Lossin //!         __InitOk,
446d0fdc396SBenno Lossin //!         ::core::convert::Infallible,
447d0fdc396SBenno Lossin //!     >(data, move |slot| {
448d0fdc396SBenno Lossin //!         {
449d0fdc396SBenno Lossin //!             struct __InitOk;
450*309786c2SBenno Lossin //!             unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).a), a) };
451*309786c2SBenno Lossin //!             let a = &unsafe {
452*309786c2SBenno Lossin //!                 ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).a))
453*309786c2SBenno Lossin //!             };
454d0fdc396SBenno Lossin //!             let b = Bar::new(36);
455*309786c2SBenno Lossin //!             unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? };
456*309786c2SBenno Lossin //!             let b = &unsafe {
457*309786c2SBenno Lossin //!                 ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).b))
458*309786c2SBenno Lossin //!             };
459d0fdc396SBenno Lossin //!
460d0fdc396SBenno Lossin //!             #[allow(unreachable_code, clippy::diverging_sub_expression)]
461d0fdc396SBenno Lossin //!             if false {
462d0fdc396SBenno Lossin //!                 unsafe {
463d0fdc396SBenno Lossin //!                     ::core::ptr::write(
464d0fdc396SBenno Lossin //!                         slot,
465d0fdc396SBenno Lossin //!                         Foo {
466d0fdc396SBenno Lossin //!                             a: ::core::panic!(),
467d0fdc396SBenno Lossin //!                             b: ::core::panic!(),
468d0fdc396SBenno Lossin //!                         },
469d0fdc396SBenno Lossin //!                     );
470d0fdc396SBenno Lossin //!                 };
471d0fdc396SBenno Lossin //!             }
472d0fdc396SBenno Lossin //!             unsafe { ::kernel::init::__internal::DropGuard::forget(a) };
473d0fdc396SBenno Lossin //!             unsafe { ::kernel::init::__internal::DropGuard::forget(b) };
474d0fdc396SBenno Lossin //!         }
475d0fdc396SBenno Lossin //!         Ok(__InitOk)
476d0fdc396SBenno Lossin //!     });
477d0fdc396SBenno Lossin //!     let init = move |slot| -> ::core::result::Result<(), ::core::convert::Infallible> {
478d0fdc396SBenno Lossin //!         init(slot).map(|__InitOk| ())
479d0fdc396SBenno Lossin //!     };
480d0fdc396SBenno Lossin //!     let init = unsafe {
481d0fdc396SBenno Lossin //!         ::kernel::init::pin_init_from_closure::<_, ::core::convert::Infallible>(init)
482d0fdc396SBenno Lossin //!     };
483d0fdc396SBenno Lossin //!     init
484d0fdc396SBenno Lossin //! };
485d0fdc396SBenno Lossin //! ```
486d0fdc396SBenno Lossin 
487d0fdc396SBenno Lossin /// Creates a `unsafe impl<...> PinnedDrop for $type` block.
488d0fdc396SBenno Lossin ///
489d0fdc396SBenno Lossin /// See [`PinnedDrop`] for more information.
490d0fdc396SBenno Lossin #[doc(hidden)]
491d0fdc396SBenno Lossin #[macro_export]
492d0fdc396SBenno Lossin macro_rules! __pinned_drop {
493d0fdc396SBenno Lossin     (
494d0fdc396SBenno Lossin         @impl_sig($($impl_sig:tt)*),
495d0fdc396SBenno Lossin         @impl_body(
496d0fdc396SBenno Lossin             $(#[$($attr:tt)*])*
497d0fdc396SBenno Lossin             fn drop($($sig:tt)*) {
498d0fdc396SBenno Lossin                 $($inner:tt)*
499d0fdc396SBenno Lossin             }
500d0fdc396SBenno Lossin         ),
501d0fdc396SBenno Lossin     ) => {
502d0fdc396SBenno Lossin         unsafe $($impl_sig)* {
503d0fdc396SBenno Lossin             // Inherit all attributes and the type/ident tokens for the signature.
504d0fdc396SBenno Lossin             $(#[$($attr)*])*
505d0fdc396SBenno Lossin             fn drop($($sig)*, _: $crate::init::__internal::OnlyCallFromDrop) {
506d0fdc396SBenno Lossin                 $($inner)*
507d0fdc396SBenno Lossin             }
508d0fdc396SBenno Lossin         }
509d0fdc396SBenno Lossin     }
510d0fdc396SBenno Lossin }
511fc6c6baaSBenno Lossin 
512fc6c6baaSBenno Lossin /// This macro first parses the struct definition such that it separates pinned and not pinned
513fc6c6baaSBenno Lossin /// fields. Afterwards it declares the struct and implement the `PinData` trait safely.
514fc6c6baaSBenno Lossin #[doc(hidden)]
515fc6c6baaSBenno Lossin #[macro_export]
516fc6c6baaSBenno Lossin macro_rules! __pin_data {
517fc6c6baaSBenno Lossin     // Proc-macro entry point, this is supplied by the proc-macro pre-parsing.
518fc6c6baaSBenno Lossin     (parse_input:
519fc6c6baaSBenno Lossin         @args($($pinned_drop:ident)?),
520fc6c6baaSBenno Lossin         @sig(
521fc6c6baaSBenno Lossin             $(#[$($struct_attr:tt)*])*
522fc6c6baaSBenno Lossin             $vis:vis struct $name:ident
523fc6c6baaSBenno Lossin             $(where $($whr:tt)*)?
524fc6c6baaSBenno Lossin         ),
525fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
526fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
527fc6c6baaSBenno Lossin         @body({ $($fields:tt)* }),
528fc6c6baaSBenno Lossin     ) => {
529fc6c6baaSBenno Lossin         // We now use token munching to iterate through all of the fields. While doing this we
530fc6c6baaSBenno Lossin         // identify fields marked with `#[pin]`, these fields are the 'pinned fields'. The user
531fc6c6baaSBenno Lossin         // wants these to be structurally pinned. The rest of the fields are the
532fc6c6baaSBenno Lossin         // 'not pinned fields'. Additionally we collect all fields, since we need them in the right
533fc6c6baaSBenno Lossin         // order to declare the struct.
534fc6c6baaSBenno Lossin         //
535fc6c6baaSBenno Lossin         // In this call we also put some explaining comments for the parameters.
536fc6c6baaSBenno Lossin         $crate::__pin_data!(find_pinned_fields:
537fc6c6baaSBenno Lossin             // Attributes on the struct itself, these will just be propagated to be put onto the
538fc6c6baaSBenno Lossin             // struct definition.
539fc6c6baaSBenno Lossin             @struct_attrs($(#[$($struct_attr)*])*),
540fc6c6baaSBenno Lossin             // The visibility of the struct.
541fc6c6baaSBenno Lossin             @vis($vis),
542fc6c6baaSBenno Lossin             // The name of the struct.
543fc6c6baaSBenno Lossin             @name($name),
544fc6c6baaSBenno Lossin             // The 'impl generics', the generics that will need to be specified on the struct inside
545fc6c6baaSBenno Lossin             // of an `impl<$ty_generics>` block.
546fc6c6baaSBenno Lossin             @impl_generics($($impl_generics)*),
547fc6c6baaSBenno Lossin             // The 'ty generics', the generics that will need to be specified on the impl blocks.
548fc6c6baaSBenno Lossin             @ty_generics($($ty_generics)*),
549fc6c6baaSBenno Lossin             // The where clause of any impl block and the declaration.
550fc6c6baaSBenno Lossin             @where($($($whr)*)?),
551fc6c6baaSBenno Lossin             // The remaining fields tokens that need to be processed.
552fc6c6baaSBenno Lossin             // We add a `,` at the end to ensure correct parsing.
553fc6c6baaSBenno Lossin             @fields_munch($($fields)* ,),
554fc6c6baaSBenno Lossin             // The pinned fields.
555fc6c6baaSBenno Lossin             @pinned(),
556fc6c6baaSBenno Lossin             // The not pinned fields.
557fc6c6baaSBenno Lossin             @not_pinned(),
558fc6c6baaSBenno Lossin             // All fields.
559fc6c6baaSBenno Lossin             @fields(),
560fc6c6baaSBenno Lossin             // The accumulator containing all attributes already parsed.
561fc6c6baaSBenno Lossin             @accum(),
562fc6c6baaSBenno Lossin             // Contains `yes` or `` to indicate if `#[pin]` was found on the current field.
563fc6c6baaSBenno Lossin             @is_pinned(),
564fc6c6baaSBenno Lossin             // The proc-macro argument, this should be `PinnedDrop` or ``.
565fc6c6baaSBenno Lossin             @pinned_drop($($pinned_drop)?),
566fc6c6baaSBenno Lossin         );
567fc6c6baaSBenno Lossin     };
568fc6c6baaSBenno Lossin     (find_pinned_fields:
569fc6c6baaSBenno Lossin         @struct_attrs($($struct_attrs:tt)*),
570fc6c6baaSBenno Lossin         @vis($vis:vis),
571fc6c6baaSBenno Lossin         @name($name:ident),
572fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
573fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
574fc6c6baaSBenno Lossin         @where($($whr:tt)*),
575fc6c6baaSBenno Lossin         // We found a PhantomPinned field, this should generally be pinned!
576fc6c6baaSBenno Lossin         @fields_munch($field:ident : $($($(::)?core::)?marker::)?PhantomPinned, $($rest:tt)*),
577fc6c6baaSBenno Lossin         @pinned($($pinned:tt)*),
578fc6c6baaSBenno Lossin         @not_pinned($($not_pinned:tt)*),
579fc6c6baaSBenno Lossin         @fields($($fields:tt)*),
580fc6c6baaSBenno Lossin         @accum($($accum:tt)*),
581fc6c6baaSBenno Lossin         // This field is not pinned.
582fc6c6baaSBenno Lossin         @is_pinned(),
583fc6c6baaSBenno Lossin         @pinned_drop($($pinned_drop:ident)?),
584fc6c6baaSBenno Lossin     ) => {
585fc6c6baaSBenno Lossin         ::core::compile_error!(concat!(
586fc6c6baaSBenno Lossin             "The field `",
587fc6c6baaSBenno Lossin             stringify!($field),
588fc6c6baaSBenno Lossin             "` of type `PhantomPinned` only has an effect, if it has the `#[pin]` attribute.",
589fc6c6baaSBenno Lossin         ));
590fc6c6baaSBenno Lossin         $crate::__pin_data!(find_pinned_fields:
591fc6c6baaSBenno Lossin             @struct_attrs($($struct_attrs)*),
592fc6c6baaSBenno Lossin             @vis($vis),
593fc6c6baaSBenno Lossin             @name($name),
594fc6c6baaSBenno Lossin             @impl_generics($($impl_generics)*),
595fc6c6baaSBenno Lossin             @ty_generics($($ty_generics)*),
596fc6c6baaSBenno Lossin             @where($($whr)*),
597fc6c6baaSBenno Lossin             @fields_munch($($rest)*),
598fc6c6baaSBenno Lossin             @pinned($($pinned)* $($accum)* $field: ::core::marker::PhantomPinned,),
599fc6c6baaSBenno Lossin             @not_pinned($($not_pinned)*),
600fc6c6baaSBenno Lossin             @fields($($fields)* $($accum)* $field: ::core::marker::PhantomPinned,),
601fc6c6baaSBenno Lossin             @accum(),
602fc6c6baaSBenno Lossin             @is_pinned(),
603fc6c6baaSBenno Lossin             @pinned_drop($($pinned_drop)?),
604fc6c6baaSBenno Lossin         );
605fc6c6baaSBenno Lossin     };
606fc6c6baaSBenno Lossin     (find_pinned_fields:
607fc6c6baaSBenno Lossin         @struct_attrs($($struct_attrs:tt)*),
608fc6c6baaSBenno Lossin         @vis($vis:vis),
609fc6c6baaSBenno Lossin         @name($name:ident),
610fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
611fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
612fc6c6baaSBenno Lossin         @where($($whr:tt)*),
613fc6c6baaSBenno Lossin         // We reached the field declaration.
614fc6c6baaSBenno Lossin         @fields_munch($field:ident : $type:ty, $($rest:tt)*),
615fc6c6baaSBenno Lossin         @pinned($($pinned:tt)*),
616fc6c6baaSBenno Lossin         @not_pinned($($not_pinned:tt)*),
617fc6c6baaSBenno Lossin         @fields($($fields:tt)*),
618fc6c6baaSBenno Lossin         @accum($($accum:tt)*),
619fc6c6baaSBenno Lossin         // This field is pinned.
620fc6c6baaSBenno Lossin         @is_pinned(yes),
621fc6c6baaSBenno Lossin         @pinned_drop($($pinned_drop:ident)?),
622fc6c6baaSBenno Lossin     ) => {
623fc6c6baaSBenno Lossin         $crate::__pin_data!(find_pinned_fields:
624fc6c6baaSBenno Lossin             @struct_attrs($($struct_attrs)*),
625fc6c6baaSBenno Lossin             @vis($vis),
626fc6c6baaSBenno Lossin             @name($name),
627fc6c6baaSBenno Lossin             @impl_generics($($impl_generics)*),
628fc6c6baaSBenno Lossin             @ty_generics($($ty_generics)*),
629fc6c6baaSBenno Lossin             @where($($whr)*),
630fc6c6baaSBenno Lossin             @fields_munch($($rest)*),
631fc6c6baaSBenno Lossin             @pinned($($pinned)* $($accum)* $field: $type,),
632fc6c6baaSBenno Lossin             @not_pinned($($not_pinned)*),
633fc6c6baaSBenno Lossin             @fields($($fields)* $($accum)* $field: $type,),
634fc6c6baaSBenno Lossin             @accum(),
635fc6c6baaSBenno Lossin             @is_pinned(),
636fc6c6baaSBenno Lossin             @pinned_drop($($pinned_drop)?),
637fc6c6baaSBenno Lossin         );
638fc6c6baaSBenno Lossin     };
639fc6c6baaSBenno Lossin     (find_pinned_fields:
640fc6c6baaSBenno Lossin         @struct_attrs($($struct_attrs:tt)*),
641fc6c6baaSBenno Lossin         @vis($vis:vis),
642fc6c6baaSBenno Lossin         @name($name:ident),
643fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
644fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
645fc6c6baaSBenno Lossin         @where($($whr:tt)*),
646fc6c6baaSBenno Lossin         // We reached the field declaration.
647fc6c6baaSBenno Lossin         @fields_munch($field:ident : $type:ty, $($rest:tt)*),
648fc6c6baaSBenno Lossin         @pinned($($pinned:tt)*),
649fc6c6baaSBenno Lossin         @not_pinned($($not_pinned:tt)*),
650fc6c6baaSBenno Lossin         @fields($($fields:tt)*),
651fc6c6baaSBenno Lossin         @accum($($accum:tt)*),
652fc6c6baaSBenno Lossin         // This field is not pinned.
653fc6c6baaSBenno Lossin         @is_pinned(),
654fc6c6baaSBenno Lossin         @pinned_drop($($pinned_drop:ident)?),
655fc6c6baaSBenno Lossin     ) => {
656fc6c6baaSBenno Lossin         $crate::__pin_data!(find_pinned_fields:
657fc6c6baaSBenno Lossin             @struct_attrs($($struct_attrs)*),
658fc6c6baaSBenno Lossin             @vis($vis),
659fc6c6baaSBenno Lossin             @name($name),
660fc6c6baaSBenno Lossin             @impl_generics($($impl_generics)*),
661fc6c6baaSBenno Lossin             @ty_generics($($ty_generics)*),
662fc6c6baaSBenno Lossin             @where($($whr)*),
663fc6c6baaSBenno Lossin             @fields_munch($($rest)*),
664fc6c6baaSBenno Lossin             @pinned($($pinned)*),
665fc6c6baaSBenno Lossin             @not_pinned($($not_pinned)* $($accum)* $field: $type,),
666fc6c6baaSBenno Lossin             @fields($($fields)* $($accum)* $field: $type,),
667fc6c6baaSBenno Lossin             @accum(),
668fc6c6baaSBenno Lossin             @is_pinned(),
669fc6c6baaSBenno Lossin             @pinned_drop($($pinned_drop)?),
670fc6c6baaSBenno Lossin         );
671fc6c6baaSBenno Lossin     };
672fc6c6baaSBenno Lossin     (find_pinned_fields:
673fc6c6baaSBenno Lossin         @struct_attrs($($struct_attrs:tt)*),
674fc6c6baaSBenno Lossin         @vis($vis:vis),
675fc6c6baaSBenno Lossin         @name($name:ident),
676fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
677fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
678fc6c6baaSBenno Lossin         @where($($whr:tt)*),
679fc6c6baaSBenno Lossin         // We found the `#[pin]` attr.
680fc6c6baaSBenno Lossin         @fields_munch(#[pin] $($rest:tt)*),
681fc6c6baaSBenno Lossin         @pinned($($pinned:tt)*),
682fc6c6baaSBenno Lossin         @not_pinned($($not_pinned:tt)*),
683fc6c6baaSBenno Lossin         @fields($($fields:tt)*),
684fc6c6baaSBenno Lossin         @accum($($accum:tt)*),
685fc6c6baaSBenno Lossin         @is_pinned($($is_pinned:ident)?),
686fc6c6baaSBenno Lossin         @pinned_drop($($pinned_drop:ident)?),
687fc6c6baaSBenno Lossin     ) => {
688fc6c6baaSBenno Lossin         $crate::__pin_data!(find_pinned_fields:
689fc6c6baaSBenno Lossin             @struct_attrs($($struct_attrs)*),
690fc6c6baaSBenno Lossin             @vis($vis),
691fc6c6baaSBenno Lossin             @name($name),
692fc6c6baaSBenno Lossin             @impl_generics($($impl_generics)*),
693fc6c6baaSBenno Lossin             @ty_generics($($ty_generics)*),
694fc6c6baaSBenno Lossin             @where($($whr)*),
695fc6c6baaSBenno Lossin             @fields_munch($($rest)*),
696fc6c6baaSBenno Lossin             // We do not include `#[pin]` in the list of attributes, since it is not actually an
697fc6c6baaSBenno Lossin             // attribute that is defined somewhere.
698fc6c6baaSBenno Lossin             @pinned($($pinned)*),
699fc6c6baaSBenno Lossin             @not_pinned($($not_pinned)*),
700fc6c6baaSBenno Lossin             @fields($($fields)*),
701fc6c6baaSBenno Lossin             @accum($($accum)*),
702fc6c6baaSBenno Lossin             // Set this to `yes`.
703fc6c6baaSBenno Lossin             @is_pinned(yes),
704fc6c6baaSBenno Lossin             @pinned_drop($($pinned_drop)?),
705fc6c6baaSBenno Lossin         );
706fc6c6baaSBenno Lossin     };
707fc6c6baaSBenno Lossin     (find_pinned_fields:
708fc6c6baaSBenno Lossin         @struct_attrs($($struct_attrs:tt)*),
709fc6c6baaSBenno Lossin         @vis($vis:vis),
710fc6c6baaSBenno Lossin         @name($name:ident),
711fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
712fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
713fc6c6baaSBenno Lossin         @where($($whr:tt)*),
714fc6c6baaSBenno Lossin         // We reached the field declaration with visibility, for simplicity we only munch the
715fc6c6baaSBenno Lossin         // visibility and put it into `$accum`.
716fc6c6baaSBenno Lossin         @fields_munch($fvis:vis $field:ident $($rest:tt)*),
717fc6c6baaSBenno Lossin         @pinned($($pinned:tt)*),
718fc6c6baaSBenno Lossin         @not_pinned($($not_pinned:tt)*),
719fc6c6baaSBenno Lossin         @fields($($fields:tt)*),
720fc6c6baaSBenno Lossin         @accum($($accum:tt)*),
721fc6c6baaSBenno Lossin         @is_pinned($($is_pinned:ident)?),
722fc6c6baaSBenno Lossin         @pinned_drop($($pinned_drop:ident)?),
723fc6c6baaSBenno Lossin     ) => {
724fc6c6baaSBenno Lossin         $crate::__pin_data!(find_pinned_fields:
725fc6c6baaSBenno Lossin             @struct_attrs($($struct_attrs)*),
726fc6c6baaSBenno Lossin             @vis($vis),
727fc6c6baaSBenno Lossin             @name($name),
728fc6c6baaSBenno Lossin             @impl_generics($($impl_generics)*),
729fc6c6baaSBenno Lossin             @ty_generics($($ty_generics)*),
730fc6c6baaSBenno Lossin             @where($($whr)*),
731fc6c6baaSBenno Lossin             @fields_munch($field $($rest)*),
732fc6c6baaSBenno Lossin             @pinned($($pinned)*),
733fc6c6baaSBenno Lossin             @not_pinned($($not_pinned)*),
734fc6c6baaSBenno Lossin             @fields($($fields)*),
735fc6c6baaSBenno Lossin             @accum($($accum)* $fvis),
736fc6c6baaSBenno Lossin             @is_pinned($($is_pinned)?),
737fc6c6baaSBenno Lossin             @pinned_drop($($pinned_drop)?),
738fc6c6baaSBenno Lossin         );
739fc6c6baaSBenno Lossin     };
740fc6c6baaSBenno Lossin     (find_pinned_fields:
741fc6c6baaSBenno Lossin         @struct_attrs($($struct_attrs:tt)*),
742fc6c6baaSBenno Lossin         @vis($vis:vis),
743fc6c6baaSBenno Lossin         @name($name:ident),
744fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
745fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
746fc6c6baaSBenno Lossin         @where($($whr:tt)*),
747fc6c6baaSBenno Lossin         // Some other attribute, just put it into `$accum`.
748fc6c6baaSBenno Lossin         @fields_munch(#[$($attr:tt)*] $($rest:tt)*),
749fc6c6baaSBenno Lossin         @pinned($($pinned:tt)*),
750fc6c6baaSBenno Lossin         @not_pinned($($not_pinned:tt)*),
751fc6c6baaSBenno Lossin         @fields($($fields:tt)*),
752fc6c6baaSBenno Lossin         @accum($($accum:tt)*),
753fc6c6baaSBenno Lossin         @is_pinned($($is_pinned:ident)?),
754fc6c6baaSBenno Lossin         @pinned_drop($($pinned_drop:ident)?),
755fc6c6baaSBenno Lossin     ) => {
756fc6c6baaSBenno Lossin         $crate::__pin_data!(find_pinned_fields:
757fc6c6baaSBenno Lossin             @struct_attrs($($struct_attrs)*),
758fc6c6baaSBenno Lossin             @vis($vis),
759fc6c6baaSBenno Lossin             @name($name),
760fc6c6baaSBenno Lossin             @impl_generics($($impl_generics)*),
761fc6c6baaSBenno Lossin             @ty_generics($($ty_generics)*),
762fc6c6baaSBenno Lossin             @where($($whr)*),
763fc6c6baaSBenno Lossin             @fields_munch($($rest)*),
764fc6c6baaSBenno Lossin             @pinned($($pinned)*),
765fc6c6baaSBenno Lossin             @not_pinned($($not_pinned)*),
766fc6c6baaSBenno Lossin             @fields($($fields)*),
767fc6c6baaSBenno Lossin             @accum($($accum)* #[$($attr)*]),
768fc6c6baaSBenno Lossin             @is_pinned($($is_pinned)?),
769fc6c6baaSBenno Lossin             @pinned_drop($($pinned_drop)?),
770fc6c6baaSBenno Lossin         );
771fc6c6baaSBenno Lossin     };
772fc6c6baaSBenno Lossin     (find_pinned_fields:
773fc6c6baaSBenno Lossin         @struct_attrs($($struct_attrs:tt)*),
774fc6c6baaSBenno Lossin         @vis($vis:vis),
775fc6c6baaSBenno Lossin         @name($name:ident),
776fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
777fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
778fc6c6baaSBenno Lossin         @where($($whr:tt)*),
779fc6c6baaSBenno Lossin         // We reached the end of the fields, plus an optional additional comma, since we added one
780fc6c6baaSBenno Lossin         // before and the user is also allowed to put a trailing comma.
781fc6c6baaSBenno Lossin         @fields_munch($(,)?),
782fc6c6baaSBenno Lossin         @pinned($($pinned:tt)*),
783fc6c6baaSBenno Lossin         @not_pinned($($not_pinned:tt)*),
784fc6c6baaSBenno Lossin         @fields($($fields:tt)*),
785fc6c6baaSBenno Lossin         @accum(),
786fc6c6baaSBenno Lossin         @is_pinned(),
787fc6c6baaSBenno Lossin         @pinned_drop($($pinned_drop:ident)?),
788fc6c6baaSBenno Lossin     ) => {
789fc6c6baaSBenno Lossin         // Declare the struct with all fields in the correct order.
790fc6c6baaSBenno Lossin         $($struct_attrs)*
791fc6c6baaSBenno Lossin         $vis struct $name <$($impl_generics)*>
792fc6c6baaSBenno Lossin         where $($whr)*
793fc6c6baaSBenno Lossin         {
794fc6c6baaSBenno Lossin             $($fields)*
795fc6c6baaSBenno Lossin         }
796fc6c6baaSBenno Lossin 
797fc6c6baaSBenno Lossin         // We put the rest into this const item, because it then will not be accessible to anything
798fc6c6baaSBenno Lossin         // outside.
799fc6c6baaSBenno Lossin         const _: () = {
800fc6c6baaSBenno Lossin             // We declare this struct which will host all of the projection function for our type.
801fc6c6baaSBenno Lossin             // it will be invariant over all generic parameters which are inherited from the
802fc6c6baaSBenno Lossin             // struct.
803fc6c6baaSBenno Lossin             $vis struct __ThePinData<$($impl_generics)*>
804fc6c6baaSBenno Lossin             where $($whr)*
805fc6c6baaSBenno Lossin             {
806fc6c6baaSBenno Lossin                 __phantom: ::core::marker::PhantomData<
807fc6c6baaSBenno Lossin                     fn($name<$($ty_generics)*>) -> $name<$($ty_generics)*>
808fc6c6baaSBenno Lossin                 >,
809fc6c6baaSBenno Lossin             }
810fc6c6baaSBenno Lossin 
811fc6c6baaSBenno Lossin             impl<$($impl_generics)*> ::core::clone::Clone for __ThePinData<$($ty_generics)*>
812fc6c6baaSBenno Lossin             where $($whr)*
813fc6c6baaSBenno Lossin             {
814fc6c6baaSBenno Lossin                 fn clone(&self) -> Self { *self }
815fc6c6baaSBenno Lossin             }
816fc6c6baaSBenno Lossin 
817fc6c6baaSBenno Lossin             impl<$($impl_generics)*> ::core::marker::Copy for __ThePinData<$($ty_generics)*>
818fc6c6baaSBenno Lossin             where $($whr)*
819fc6c6baaSBenno Lossin             {}
820fc6c6baaSBenno Lossin 
821fc6c6baaSBenno Lossin             // Make all projection functions.
822fc6c6baaSBenno Lossin             $crate::__pin_data!(make_pin_data:
823fc6c6baaSBenno Lossin                 @pin_data(__ThePinData),
824fc6c6baaSBenno Lossin                 @impl_generics($($impl_generics)*),
825fc6c6baaSBenno Lossin                 @ty_generics($($ty_generics)*),
826fc6c6baaSBenno Lossin                 @where($($whr)*),
827fc6c6baaSBenno Lossin                 @pinned($($pinned)*),
828fc6c6baaSBenno Lossin                 @not_pinned($($not_pinned)*),
829fc6c6baaSBenno Lossin             );
830fc6c6baaSBenno Lossin 
831fc6c6baaSBenno Lossin             // SAFETY: We have added the correct projection functions above to `__ThePinData` and
832fc6c6baaSBenno Lossin             // we also use the least restrictive generics possible.
833fc6c6baaSBenno Lossin             unsafe impl<$($impl_generics)*>
834fc6c6baaSBenno Lossin                 $crate::init::__internal::HasPinData for $name<$($ty_generics)*>
835fc6c6baaSBenno Lossin             where $($whr)*
836fc6c6baaSBenno Lossin             {
837fc6c6baaSBenno Lossin                 type PinData = __ThePinData<$($ty_generics)*>;
838fc6c6baaSBenno Lossin 
839fc6c6baaSBenno Lossin                 unsafe fn __pin_data() -> Self::PinData {
840fc6c6baaSBenno Lossin                     __ThePinData { __phantom: ::core::marker::PhantomData }
841fc6c6baaSBenno Lossin                 }
842fc6c6baaSBenno Lossin             }
843fc6c6baaSBenno Lossin 
844fc6c6baaSBenno Lossin             unsafe impl<$($impl_generics)*>
845fc6c6baaSBenno Lossin                 $crate::init::__internal::PinData for __ThePinData<$($ty_generics)*>
846fc6c6baaSBenno Lossin             where $($whr)*
847fc6c6baaSBenno Lossin             {
848fc6c6baaSBenno Lossin                 type Datee = $name<$($ty_generics)*>;
849fc6c6baaSBenno Lossin             }
850fc6c6baaSBenno Lossin 
851fc6c6baaSBenno Lossin             // This struct will be used for the unpin analysis. Since only structurally pinned
852fc6c6baaSBenno Lossin             // fields are relevant whether the struct should implement `Unpin`.
853fc6c6baaSBenno Lossin             #[allow(dead_code)]
854fc6c6baaSBenno Lossin             struct __Unpin <'__pin, $($impl_generics)*>
855fc6c6baaSBenno Lossin             where $($whr)*
856fc6c6baaSBenno Lossin             {
857fc6c6baaSBenno Lossin                 __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
858fc6c6baaSBenno Lossin                 __phantom: ::core::marker::PhantomData<
859fc6c6baaSBenno Lossin                     fn($name<$($ty_generics)*>) -> $name<$($ty_generics)*>
860fc6c6baaSBenno Lossin                 >,
861fc6c6baaSBenno Lossin                 // Only the pinned fields.
862fc6c6baaSBenno Lossin                 $($pinned)*
863fc6c6baaSBenno Lossin             }
864fc6c6baaSBenno Lossin 
865fc6c6baaSBenno Lossin             #[doc(hidden)]
866fc6c6baaSBenno Lossin             impl<'__pin, $($impl_generics)*> ::core::marker::Unpin for $name<$($ty_generics)*>
867fc6c6baaSBenno Lossin             where
868fc6c6baaSBenno Lossin                 __Unpin<'__pin, $($ty_generics)*>: ::core::marker::Unpin,
869fc6c6baaSBenno Lossin                 $($whr)*
870fc6c6baaSBenno Lossin             {}
871fc6c6baaSBenno Lossin 
872fc6c6baaSBenno Lossin             // We need to disallow normal `Drop` implementation, the exact behavior depends on
873fc6c6baaSBenno Lossin             // whether `PinnedDrop` was specified as the parameter.
874fc6c6baaSBenno Lossin             $crate::__pin_data!(drop_prevention:
875fc6c6baaSBenno Lossin                 @name($name),
876fc6c6baaSBenno Lossin                 @impl_generics($($impl_generics)*),
877fc6c6baaSBenno Lossin                 @ty_generics($($ty_generics)*),
878fc6c6baaSBenno Lossin                 @where($($whr)*),
879fc6c6baaSBenno Lossin                 @pinned_drop($($pinned_drop)?),
880fc6c6baaSBenno Lossin             );
881fc6c6baaSBenno Lossin         };
882fc6c6baaSBenno Lossin     };
883fc6c6baaSBenno Lossin     // When no `PinnedDrop` was specified, then we have to prevent implementing drop.
884fc6c6baaSBenno Lossin     (drop_prevention:
885fc6c6baaSBenno Lossin         @name($name:ident),
886fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
887fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
888fc6c6baaSBenno Lossin         @where($($whr:tt)*),
889fc6c6baaSBenno Lossin         @pinned_drop(),
890fc6c6baaSBenno Lossin     ) => {
891fc6c6baaSBenno Lossin         // We prevent this by creating a trait that will be implemented for all types implementing
892fc6c6baaSBenno Lossin         // `Drop`. Additionally we will implement this trait for the struct leading to a conflict,
893fc6c6baaSBenno Lossin         // if it also implements `Drop`
894fc6c6baaSBenno Lossin         trait MustNotImplDrop {}
895fc6c6baaSBenno Lossin         #[allow(drop_bounds)]
896fc6c6baaSBenno Lossin         impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
897fc6c6baaSBenno Lossin         impl<$($impl_generics)*> MustNotImplDrop for $name<$($ty_generics)*>
898fc6c6baaSBenno Lossin         where $($whr)* {}
899d0fdc396SBenno Lossin         // We also take care to prevent users from writing a useless `PinnedDrop` implementation.
900d0fdc396SBenno Lossin         // They might implement `PinnedDrop` correctly for the struct, but forget to give
901d0fdc396SBenno Lossin         // `PinnedDrop` as the parameter to `#[pin_data]`.
902d0fdc396SBenno Lossin         #[allow(non_camel_case_types)]
903d0fdc396SBenno Lossin         trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
904d0fdc396SBenno Lossin         impl<T: $crate::init::PinnedDrop>
905d0fdc396SBenno Lossin             UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
906d0fdc396SBenno Lossin         impl<$($impl_generics)*>
907d0fdc396SBenno Lossin             UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for $name<$($ty_generics)*>
908d0fdc396SBenno Lossin         where $($whr)* {}
909d0fdc396SBenno Lossin     };
910d0fdc396SBenno Lossin     // When `PinnedDrop` was specified we just implement `Drop` and delegate.
911d0fdc396SBenno Lossin     (drop_prevention:
912d0fdc396SBenno Lossin         @name($name:ident),
913d0fdc396SBenno Lossin         @impl_generics($($impl_generics:tt)*),
914d0fdc396SBenno Lossin         @ty_generics($($ty_generics:tt)*),
915d0fdc396SBenno Lossin         @where($($whr:tt)*),
916d0fdc396SBenno Lossin         @pinned_drop(PinnedDrop),
917d0fdc396SBenno Lossin     ) => {
918d0fdc396SBenno Lossin         impl<$($impl_generics)*> ::core::ops::Drop for $name<$($ty_generics)*>
919d0fdc396SBenno Lossin         where $($whr)*
920d0fdc396SBenno Lossin         {
921d0fdc396SBenno Lossin             fn drop(&mut self) {
922d0fdc396SBenno Lossin                 // SAFETY: Since this is a destructor, `self` will not move after this function
923d0fdc396SBenno Lossin                 // terminates, since it is inaccessible.
924d0fdc396SBenno Lossin                 let pinned = unsafe { ::core::pin::Pin::new_unchecked(self) };
925d0fdc396SBenno Lossin                 // SAFETY: Since this is a drop function, we can create this token to call the
926d0fdc396SBenno Lossin                 // pinned destructor of this type.
927d0fdc396SBenno Lossin                 let token = unsafe { $crate::init::__internal::OnlyCallFromDrop::new() };
928d0fdc396SBenno Lossin                 $crate::init::PinnedDrop::drop(pinned, token);
929d0fdc396SBenno Lossin             }
930d0fdc396SBenno Lossin         }
931fc6c6baaSBenno Lossin     };
932fc6c6baaSBenno Lossin     // If some other parameter was specified, we emit a readable error.
933fc6c6baaSBenno Lossin     (drop_prevention:
934fc6c6baaSBenno Lossin         @name($name:ident),
935fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
936fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
937fc6c6baaSBenno Lossin         @where($($whr:tt)*),
938fc6c6baaSBenno Lossin         @pinned_drop($($rest:tt)*),
939fc6c6baaSBenno Lossin     ) => {
940fc6c6baaSBenno Lossin         compile_error!(
941fc6c6baaSBenno Lossin             "Wrong parameters to `#[pin_data]`, expected nothing or `PinnedDrop`, got '{}'.",
942fc6c6baaSBenno Lossin             stringify!($($rest)*),
943fc6c6baaSBenno Lossin         );
944fc6c6baaSBenno Lossin     };
945fc6c6baaSBenno Lossin     (make_pin_data:
946fc6c6baaSBenno Lossin         @pin_data($pin_data:ident),
947fc6c6baaSBenno Lossin         @impl_generics($($impl_generics:tt)*),
948fc6c6baaSBenno Lossin         @ty_generics($($ty_generics:tt)*),
949fc6c6baaSBenno Lossin         @where($($whr:tt)*),
950fc6c6baaSBenno Lossin         @pinned($($(#[$($p_attr:tt)*])* $pvis:vis $p_field:ident : $p_type:ty),* $(,)?),
951fc6c6baaSBenno Lossin         @not_pinned($($(#[$($attr:tt)*])* $fvis:vis $field:ident : $type:ty),* $(,)?),
952fc6c6baaSBenno Lossin     ) => {
953fc6c6baaSBenno Lossin         // For every field, we create a projection function according to its projection type. If a
954fc6c6baaSBenno Lossin         // field is structurally pinned, then it must be initialized via `PinInit`, if it is not
955fc6c6baaSBenno Lossin         // structurally pinned, then it can be initialized via `Init`.
956fc6c6baaSBenno Lossin         //
957fc6c6baaSBenno Lossin         // The functions are `unsafe` to prevent accidentally calling them.
958fc6c6baaSBenno Lossin         #[allow(dead_code)]
959fc6c6baaSBenno Lossin         impl<$($impl_generics)*> $pin_data<$($ty_generics)*>
960fc6c6baaSBenno Lossin         where $($whr)*
961fc6c6baaSBenno Lossin         {
962fc6c6baaSBenno Lossin             $(
963fc6c6baaSBenno Lossin                 $pvis unsafe fn $p_field<E>(
964fc6c6baaSBenno Lossin                     self,
965fc6c6baaSBenno Lossin                     slot: *mut $p_type,
966fc6c6baaSBenno Lossin                     init: impl $crate::init::PinInit<$p_type, E>,
967fc6c6baaSBenno Lossin                 ) -> ::core::result::Result<(), E> {
968fc6c6baaSBenno Lossin                     unsafe { $crate::init::PinInit::__pinned_init(init, slot) }
969fc6c6baaSBenno Lossin                 }
970fc6c6baaSBenno Lossin             )*
971fc6c6baaSBenno Lossin             $(
972fc6c6baaSBenno Lossin                 $fvis unsafe fn $field<E>(
973fc6c6baaSBenno Lossin                     self,
974fc6c6baaSBenno Lossin                     slot: *mut $type,
975fc6c6baaSBenno Lossin                     init: impl $crate::init::Init<$type, E>,
976fc6c6baaSBenno Lossin                 ) -> ::core::result::Result<(), E> {
977fc6c6baaSBenno Lossin                     unsafe { $crate::init::Init::__init(init, slot) }
978fc6c6baaSBenno Lossin                 }
979fc6c6baaSBenno Lossin             )*
980fc6c6baaSBenno Lossin         }
981fc6c6baaSBenno Lossin     };
982fc6c6baaSBenno Lossin }
983