Skip to main content

pin_project_lite/
lib.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3/*!
4A lightweight version of pin-project written with declarative macros.
5
6## Examples
7
8[`pin_project!`] macro creates a projection type covering all the fields of
9struct.
10
11```rust
12use std::pin::Pin;
13
14use pin_project_lite::pin_project;
15
16pin_project! {
17    struct Struct<T, U> {
18        #[pin]
19        pinned: T,
20        unpinned: U,
21    }
22}
23
24impl<T, U> Struct<T, U> {
25    fn method(self: Pin<&mut Self>) {
26        let this = self.project();
27        let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
28        let _: &mut U = this.unpinned; // Normal reference to the field
29    }
30}
31```
32
33To use [`pin_project!`] on enums, you need to name the projection type
34returned from the method.
35
36```rust
37use std::pin::Pin;
38
39use pin_project_lite::pin_project;
40
41pin_project! {
42    #[project = EnumProj]
43    enum Enum<T, U> {
44        Variant { #[pin] pinned: T, unpinned: U },
45    }
46}
47
48impl<T, U> Enum<T, U> {
49    fn method(self: Pin<&mut Self>) {
50        match self.project() {
51            EnumProj::Variant { pinned, unpinned } => {
52                let _: Pin<&mut T> = pinned;
53                let _: &mut U = unpinned;
54            }
55        }
56    }
57}
58```
59*/
60
61#![no_std]
62#![doc(test(
63    no_crate_inject,
64    attr(
65        deny(warnings, rust_2018_idioms, single_use_lifetimes),
66        allow(dead_code, unused_variables)
67    )
68))]
69// #![warn(unsafe_op_in_unsafe_fn)] // requires Rust 1.52
70#![warn(
71    // Lints that may help when writing public library.
72    missing_debug_implementations,
73    missing_docs,
74    clippy::alloc_instead_of_core,
75    clippy::exhaustive_enums,
76    clippy::exhaustive_structs,
77    clippy::impl_trait_in_params,
78    // clippy::missing_inline_in_public_items,
79    clippy::std_instead_of_alloc,
80    clippy::std_instead_of_core,
81)]
82
83/// A macro that creates a projection type covering all the fields of struct.
84///
85/// This macro creates a projection type according to the following rules:
86///
87/// - For the field that uses `#[pin]` attribute, makes the pinned reference to the field.
88/// - For the other fields, makes the unpinned reference to the field.
89///
90/// And the following methods are implemented on the original type:
91///
92/// ```
93/// # use std::pin::Pin;
94/// # type Projection<'a> = &'a ();
95/// # type ProjectionRef<'a> = &'a ();
96/// # trait Dox {
97/// fn project(self: Pin<&mut Self>) -> Projection<'_>;
98/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;
99/// # }
100/// ```
101///
102/// By passing an attribute with the same name as the method to the macro,
103/// you can name the projection type returned from the method. This allows you
104/// to use pattern matching on the projected types.
105///
106/// ```
107/// # use pin_project_lite::pin_project;
108/// # use std::pin::Pin;
109/// pin_project! {
110///     #[project = EnumProj]
111///     enum Enum<T> {
112///         Variant { #[pin] field: T },
113///     }
114/// }
115///
116/// impl<T> Enum<T> {
117///     fn method(self: Pin<&mut Self>) {
118///         let this: EnumProj<'_, T> = self.project();
119///         match this {
120///             EnumProj::Variant { field } => {
121///                 let _: Pin<&mut T> = field;
122///             }
123///         }
124///     }
125/// }
126/// ```
127///
128/// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional
129/// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving
130/// out all unpinned fields in `Self`.
131///
132/// ```
133/// # use std::pin::Pin;
134/// # type MyProjReplace = ();
135/// # trait Dox {
136/// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace;
137/// # }
138/// ```
139///
140/// Also, note that the projection types returned by `project` and `project_ref` have
141/// an additional lifetime at the beginning of generics.
142///
143/// ```text
144/// let this: EnumProj<'_, T> = self.project();
145///                    ^^
146/// ```
147///
148/// The visibility of the projected types and projection methods is based on the
149/// original type. However, if the visibility of the original type is `pub`, the
150/// visibility of the projected types and the projection methods is downgraded
151/// to `pub(crate)`.
152///
153/// # Safety
154///
155/// `pin_project!` macro guarantees safety in much the same way as [pin-project] crate.
156/// Both are completely safe unless you write other unsafe code.
157///
158/// See [pin-project] crate for more details.
159///
160/// # Examples
161///
162/// ```
163/// use std::pin::Pin;
164///
165/// use pin_project_lite::pin_project;
166///
167/// pin_project! {
168///     struct Struct<T, U> {
169///         #[pin]
170///         pinned: T,
171///         unpinned: U,
172///     }
173/// }
174///
175/// impl<T, U> Struct<T, U> {
176///     fn method(self: Pin<&mut Self>) {
177///         let this = self.project();
178///         let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
179///         let _: &mut U = this.unpinned; // Normal reference to the field
180///     }
181/// }
182/// ```
183///
184/// To use `pin_project!` on enums, you need to name the projection type
185/// returned from the method.
186///
187/// ```
188/// use std::pin::Pin;
189///
190/// use pin_project_lite::pin_project;
191///
192/// pin_project! {
193///     #[project = EnumProj]
194///     enum Enum<T> {
195///         Struct {
196///             #[pin]
197///             field: T,
198///         },
199///         Unit,
200///     }
201/// }
202///
203/// impl<T> Enum<T> {
204///     fn method(self: Pin<&mut Self>) {
205///         match self.project() {
206///             EnumProj::Struct { field } => {
207///                 let _: Pin<&mut T> = field;
208///             }
209///             EnumProj::Unit => {}
210///         }
211///     }
212/// }
213/// ```
214///
215/// If you want to call the `project()` method multiple times or later use the
216/// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid
217/// consuming the [`Pin`].
218///
219/// ```
220/// use std::pin::Pin;
221///
222/// use pin_project_lite::pin_project;
223///
224/// pin_project! {
225///     struct Struct<T> {
226///         #[pin]
227///         field: T,
228///     }
229/// }
230///
231/// impl<T> Struct<T> {
232///     fn call_project_twice(mut self: Pin<&mut Self>) {
233///         // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.
234///         self.as_mut().project();
235///         self.as_mut().project();
236///     }
237/// }
238/// ```
239///
240/// # `!Unpin`
241///
242/// If you want to make sure `Unpin` is not implemented, use the `#[project(!Unpin)]`
243/// attribute.
244///
245/// ```
246/// use pin_project_lite::pin_project;
247///
248/// pin_project! {
249///      #[project(!Unpin)]
250///      struct Struct<T> {
251///          #[pin]
252///          field: T,
253///      }
254/// }
255/// ```
256///
257/// This is equivalent to using `#[pin]` attribute for a [`PhantomPinned`] field.
258///
259/// ```
260/// use std::marker::PhantomPinned;
261///
262/// use pin_project_lite::pin_project;
263///
264/// pin_project! {
265///     struct Struct<T> {
266///         field: T,
267///         #[pin]
268///         _pin: PhantomPinned,
269///     }
270/// }
271/// ```
272///
273/// Note that using [`PhantomPinned`] without `#[pin]` or `#[project(!Unpin)]`
274/// attribute has no effect.
275///
276/// # Pinned Drop
277///
278/// In order to correctly implement pin projections, a type’s [`Drop`] impl must not move out of any
279/// structurally pinned fields. Unfortunately, [`Drop::drop`] takes `&mut Self`, not `Pin<&mut
280/// Self>`.
281///
282/// To implement [`Drop`] for type that has pin, add an `impl PinnedDrop` block at the end of the
283/// [`pin_project`] macro block. PinnedDrop has the following interface:
284///
285/// ```rust
286/// # use std::pin::Pin;
287/// trait PinnedDrop {
288///     fn drop(this: Pin<&mut Self>);
289/// }
290/// ```
291///
292/// Note that the argument to `PinnedDrop::drop` cannot be named `self`.
293///
294/// `pin_project!` implements the actual [`Drop`] trait via PinnedDrop you implemented. To
295/// explicitly drop a type that implements PinnedDrop, use the [drop] function just like dropping a
296/// type that directly implements [`Drop`].
297///
298/// `PinnedDrop::drop` will never be called more than once, just like [`Drop::drop`].
299///
300/// ```rust
301/// use pin_project_lite::pin_project;
302///
303/// pin_project! {
304///     pub struct Struct<'a> {
305///         was_dropped: &'a mut bool,
306///         #[pin]
307///         field: u8,
308///     }
309///
310///     impl PinnedDrop for Struct<'_> {
311///         fn drop(this: Pin<&mut Self>) { // <----- NOTE: this is not `self`
312///             **this.project().was_dropped = true;
313///         }
314///     }
315/// }
316///
317/// let mut was_dropped = false;
318/// drop(Struct { was_dropped: &mut was_dropped, field: 42 });
319/// assert!(was_dropped);
320/// ```
321///
322/// [`PhantomPinned`]: core::marker::PhantomPinned
323/// [`Pin::as_mut`]: core::pin::Pin::as_mut
324/// [`Pin`]: core::pin::Pin
325/// [pin-project]: https://github.com/taiki-e/pin-project
326#[macro_export]
327macro_rules! pin_project {
328    ($($tt:tt)*) => {
329        $crate::__pin_project_internal! {
330            [][][][][]
331            $($tt)*
332        }
333    };
334}
335
336// limitations:
337// - no support for tuple structs and tuple variant (wontfix).
338// - no support for multiple trait/lifetime bounds.
339// - no support for `Self` in where clauses. (wontfix)
340// - no support for overlapping lifetime names. (wontfix)
341// - no interoperability with other field attributes.
342// - no useful error messages. (wontfix)
343// etc...
344
345#[doc(hidden)]
346#[macro_export]
347macro_rules! __pin_project_expand {
348    (
349        [$($proj_mut_ident:ident)?]
350        [$($proj_ref_ident:ident)?]
351        [$($proj_replace_ident:ident)?]
352        [$($proj_not_unpin_mark:ident)?]
353        [$proj_vis:vis]
354        [$(#[$attrs:meta])* $vis:vis $struct_ty_ident:ident $ident:ident]
355        [$($def_generics:tt)*]
356        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
357        {
358            $($body_data:tt)*
359        }
360        $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?
361    ) => {
362        $crate::__pin_project_reconstruct! {
363            [$(#[$attrs])* $vis $struct_ty_ident $ident]
364            [$($def_generics)*] [$($impl_generics)*]
365            [$($ty_generics)*] [$(where $($where_clause)*)?]
366            {
367                $($body_data)*
368            }
369        }
370
371        $crate::__pin_project_make_proj_ty! {
372            [$($proj_mut_ident)?]
373            [$proj_vis $struct_ty_ident $ident]
374            [__pin_project_make_proj_field_mut]
375            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
376            {
377                $($body_data)*
378            }
379        }
380        $crate::__pin_project_make_proj_ty! {
381            [$($proj_ref_ident)?]
382            [$proj_vis $struct_ty_ident $ident]
383            [__pin_project_make_proj_field_ref]
384            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
385            {
386                $($body_data)*
387            }
388        }
389        $crate::__pin_project_make_proj_replace_ty! {
390            [$($proj_replace_ident)?]
391            [$proj_vis $struct_ty_ident]
392            [__pin_project_make_proj_field_replace]
393            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
394            {
395                $($body_data)*
396            }
397        }
398
399        $crate::__pin_project_constant! {
400            [$(#[$attrs])* $vis $struct_ty_ident $ident]
401            [$($proj_mut_ident)?] [$($proj_ref_ident)?] [$($proj_replace_ident)?]
402            [$($proj_not_unpin_mark)?]
403            [$proj_vis]
404            [$($def_generics)*] [$($impl_generics)*]
405            [$($ty_generics)*] [$(where $($where_clause)*)?]
406            {
407                $($body_data)*
408            }
409            $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?
410        }
411    };
412}
413
414#[doc(hidden)]
415#[macro_export]
416macro_rules! __pin_project_constant {
417    (
418        [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
419        [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]
420        [$($proj_not_unpin_mark:ident)?]
421        [$proj_vis:vis]
422        [$($def_generics:tt)*]
423        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
424        {
425            $(
426                $(#[$pin:ident])?
427                $field_vis:vis $field:ident: $field_ty:ty
428            ),+ $(,)?
429        }
430        $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?
431    ) => {
432        #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
433        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
434        // This lint warns of `clippy::*` generated by external macros.
435        // We allow this lint for compatibility with older compilers.
436        #[allow(clippy::unknown_clippy_lints)]
437        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
438        #[allow(clippy::used_underscore_binding)]
439        const _: () = {
440            $crate::__pin_project_make_proj_ty! {
441                [$($proj_mut_ident)? Projection]
442                [$proj_vis struct $ident]
443                [__pin_project_make_proj_field_mut]
444                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
445                {
446                    $(
447                        $(#[$pin])?
448                        $field_vis $field: $field_ty
449                    ),+
450                }
451            }
452            $crate::__pin_project_make_proj_ty! {
453                [$($proj_ref_ident)? ProjectionRef]
454                [$proj_vis struct $ident]
455                [__pin_project_make_proj_field_ref]
456                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
457                {
458                    $(
459                        $(#[$pin])?
460                        $field_vis $field: $field_ty
461                    ),+
462                }
463            }
464
465            impl <$($impl_generics)*> $ident <$($ty_generics)*>
466            $(where
467                $($where_clause)*)?
468            {
469                $crate::__pin_project_struct_make_proj_method! {
470                    [$($proj_mut_ident)? Projection]
471                    [$proj_vis]
472                    [project get_unchecked_mut mut]
473                    [$($ty_generics)*]
474                    {
475                        $(
476                            $(#[$pin])?
477                            $field_vis $field
478                        ),+
479                    }
480                }
481                $crate::__pin_project_struct_make_proj_method! {
482                    [$($proj_ref_ident)? ProjectionRef]
483                    [$proj_vis]
484                    [project_ref get_ref]
485                    [$($ty_generics)*]
486                    {
487                        $(
488                            $(#[$pin])?
489                            $field_vis $field
490                        ),+
491                    }
492                }
493                $crate::__pin_project_struct_make_proj_replace_method! {
494                    [$($proj_replace_ident)?]
495                    [$proj_vis]
496                    [ProjectionReplace]
497                    [$($ty_generics)*]
498                    {
499                        $(
500                            $(#[$pin])?
501                            $field_vis $field
502                        ),+
503                    }
504                }
505            }
506
507            $crate::__pin_project_make_unpin_impl! {
508                [$($proj_not_unpin_mark)?]
509                [$vis $ident]
510                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
511                $(
512                    $field: $crate::__pin_project_make_unpin_bound!(
513                        $(#[$pin])? $field_ty
514                    )
515                ),+
516            }
517
518            $crate::__pin_project_make_drop_impl! {
519                [$ident]
520                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
521                $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?
522            }
523
524            // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
525            //
526            // Taking a reference to a packed field is UB, and applying
527            // `#[forbid(unaligned_references)]` makes sure that doing this is a hard error.
528            //
529            // If the struct ends up having #[repr(packed)] applied somehow,
530            // this will generate an (unfriendly) error message. Under all reasonable
531            // circumstances, we'll detect the #[repr(packed)] attribute, and generate
532            // a much nicer error above.
533            //
534            // See https://github.com/taiki-e/pin-project/pull/34 for more details.
535            //
536            // Note:
537            // - Lint-based tricks aren't perfect, but they're much better than nothing:
538            //   https://github.com/taiki-e/pin-project-lite/issues/26
539            //
540            // - Enable both unaligned_references and safe_packed_borrows lints
541            //   because unaligned_references lint does not exist in older compilers:
542            //   https://github.com/taiki-e/pin-project-lite/pull/55
543            //   https://github.com/rust-lang/rust/pull/82525
544            #[forbid(unaligned_references, safe_packed_borrows)]
545            fn __assert_not_repr_packed <$($impl_generics)*> (this: &$ident <$($ty_generics)*>)
546            $(where
547                $($where_clause)*)?
548            {
549                $(
550                    let _ = &this.$field;
551                )+
552            }
553        };
554    };
555    (
556        [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
557        [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]
558        [$($proj_not_unpin_mark:ident)?]
559        [$proj_vis:vis]
560        [$($def_generics:tt)*]
561        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
562        {
563            $(
564                $(#[$variant_attrs:meta])*
565                $variant:ident $({
566                    $(
567                        $(#[$pin:ident])?
568                        $field:ident: $field_ty:ty
569                    ),+ $(,)?
570                })?
571            ),+ $(,)?
572        }
573        $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?
574    ) => {
575        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
576        // This lint warns of `clippy::*` generated by external macros.
577        // We allow this lint for compatibility with older compilers.
578        #[allow(clippy::unknown_clippy_lints)]
579        #[allow(clippy::used_underscore_binding)]
580        const _: () = {
581            impl <$($impl_generics)*> $ident <$($ty_generics)*>
582            $(where
583                $($where_clause)*)?
584            {
585                $crate::__pin_project_enum_make_proj_method! {
586                    [$($proj_mut_ident)?]
587                    [$proj_vis]
588                    [project get_unchecked_mut mut]
589                    [$($ty_generics)*]
590                    {
591                        $(
592                            $variant $({
593                                $(
594                                    $(#[$pin])?
595                                    $field
596                                ),+
597                            })?
598                        ),+
599                    }
600                }
601                $crate::__pin_project_enum_make_proj_method! {
602                    [$($proj_ref_ident)?]
603                    [$proj_vis]
604                    [project_ref get_ref]
605                    [$($ty_generics)*]
606                    {
607                        $(
608                            $variant $({
609                                $(
610                                    $(#[$pin])?
611                                    $field
612                                ),+
613                            })?
614                        ),+
615                    }
616                }
617                $crate::__pin_project_enum_make_proj_replace_method! {
618                    [$($proj_replace_ident)?]
619                    [$proj_vis]
620                    [$($ty_generics)*]
621                    {
622                        $(
623                            $variant $({
624                                $(
625                                    $(#[$pin])?
626                                    $field
627                                ),+
628                            })?
629                        ),+
630                    }
631                }
632            }
633
634            $crate::__pin_project_make_unpin_impl! {
635                [$($proj_not_unpin_mark)?]
636                [$vis $ident]
637                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
638                $(
639                    $variant: ($(
640                        $(
641                            $crate::__pin_project_make_unpin_bound!(
642                                $(#[$pin])? $field_ty
643                            )
644                        ),+
645                    )?)
646                ),+
647            }
648
649            $crate::__pin_project_make_drop_impl! {
650                [$ident]
651                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
652                $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?
653            }
654
655            // We don't need to check for '#[repr(packed)]',
656            // since it does not apply to enums.
657        };
658    };
659}
660
661#[doc(hidden)]
662#[macro_export]
663macro_rules! __pin_project_reconstruct {
664    (
665        [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
666        [$($def_generics:tt)*] [$($impl_generics:tt)*]
667        [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
668        {
669            $(
670                $(#[$pin:ident])?
671                $field_vis:vis $field:ident: $field_ty:ty
672            ),+ $(,)?
673        }
674    ) => {
675        $(#[$attrs])*
676        $vis struct $ident $($def_generics)*
677        $(where
678            $($where_clause)*)?
679        {
680            $(
681                $field_vis $field: $field_ty
682            ),+
683        }
684    };
685    (
686        [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
687        [$($def_generics:tt)*] [$($impl_generics:tt)*]
688        [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
689        {
690            $(
691                $(#[$variant_attrs:meta])*
692                $variant:ident $({
693                    $(
694                        $(#[$pin:ident])?
695                        $field:ident: $field_ty:ty
696                    ),+ $(,)?
697                })?
698            ),+ $(,)?
699        }
700    ) => {
701        $(#[$attrs])*
702        $vis enum $ident $($def_generics)*
703        $(where
704            $($where_clause)*)?
705        {
706            $(
707                $(#[$variant_attrs])*
708                $variant $({
709                    $(
710                        $field: $field_ty
711                    ),+
712                })?
713            ),+
714        }
715    };
716}
717
718#[doc(hidden)]
719#[macro_export]
720macro_rules! __pin_project_make_proj_ty {
721    ([] $($field:tt)*) => {};
722    (
723        [$proj_ty_ident:ident $default_ident:ident]
724        [$proj_vis:vis struct $ident:ident]
725        $($field:tt)*
726    ) => {};
727    (
728        [$proj_ty_ident:ident]
729        [$proj_vis:vis struct $ident:ident]
730        [$__pin_project_make_proj_field:ident]
731        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
732        {
733            $(
734                $(#[$pin:ident])?
735                $field_vis:vis $field:ident: $field_ty:ty
736            ),+ $(,)?
737        }
738    ) => {
739        $crate::__pin_project_make_proj_ty_body! {
740            [$proj_ty_ident]
741            [$proj_vis struct $ident]
742            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
743            [
744                $(
745                    $field_vis $field: $crate::$__pin_project_make_proj_field!(
746                        $(#[$pin])? $field_ty
747                    )
748                ),+
749            ]
750        }
751    };
752    (
753        [$proj_ty_ident:ident]
754        [$proj_vis:vis enum $ident:ident]
755        [$__pin_project_make_proj_field:ident]
756        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
757        {
758            $(
759                $(#[$variant_attrs:meta])*
760                $variant:ident $({
761                    $(
762                        $(#[$pin:ident])?
763                        $field:ident: $field_ty:ty
764                    ),+ $(,)?
765                })?
766            ),+ $(,)?
767        }
768    ) => {
769        $crate::__pin_project_make_proj_ty_body! {
770            [$proj_ty_ident]
771            [$proj_vis enum $ident]
772            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
773            [
774                $(
775                    $variant $({
776                        $(
777                            $field: $crate::$__pin_project_make_proj_field!(
778                                $(#[$pin])? $field_ty
779                            )
780                        ),+
781                    })?
782                ),+
783            ]
784        }
785    };
786}
787
788#[doc(hidden)]
789#[macro_export]
790macro_rules! __pin_project_make_proj_ty_body {
791    (
792        [$proj_ty_ident:ident]
793        [$proj_vis:vis $struct_ty_ident:ident $ident:ident]
794        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
795        [$($body_data:tt)+]
796    ) => {
797        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
798        #[allow(dead_code)] // This lint warns unused fields/variants.
799        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
800        // This lint warns of `clippy::*` generated by external macros.
801        // We allow this lint for compatibility with older compilers.
802        #[allow(clippy::unknown_clippy_lints)]
803        #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
804        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
805        #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
806        #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
807        $proj_vis $struct_ty_ident $proj_ty_ident <'__pin, $($impl_generics)*>
808        where
809            $ident <$($ty_generics)*>: '__pin
810            $(, $($where_clause)*)?
811        {
812            $($body_data)+
813        }
814    };
815}
816
817#[doc(hidden)]
818#[macro_export]
819macro_rules! __pin_project_make_proj_replace_ty {
820    ([] $($field:tt)*) => {};
821    (
822        [$proj_ty_ident:ident]
823        [$proj_vis:vis struct]
824        [$__pin_project_make_proj_field:ident]
825        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
826        {
827            $(
828                $(#[$pin:ident])?
829                $field_vis:vis $field:ident: $field_ty:ty
830            ),+ $(,)?
831        }
832    ) => {
833        $crate::__pin_project_make_proj_replace_ty_body! {
834            [$proj_ty_ident]
835            [$proj_vis struct]
836            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
837            [
838                $(
839                    $field_vis $field: $crate::$__pin_project_make_proj_field!(
840                        $(#[$pin])? $field_ty
841                    )
842                ),+
843            ]
844        }
845    };
846    (
847        [$proj_ty_ident:ident]
848        [$proj_vis:vis enum]
849        [$__pin_project_make_proj_field:ident]
850        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
851        {
852            $(
853                $(#[$variant_attrs:meta])*
854                $variant:ident $({
855                    $(
856                        $(#[$pin:ident])?
857                        $field:ident: $field_ty:ty
858                    ),+ $(,)?
859                })?
860            ),+ $(,)?
861        }
862    ) => {
863        $crate::__pin_project_make_proj_replace_ty_body! {
864            [$proj_ty_ident]
865            [$proj_vis enum]
866            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
867            [
868                $(
869                    $variant $({
870                        $(
871                            $field: $crate::$__pin_project_make_proj_field!(
872                                $(#[$pin])? $field_ty
873                            )
874                        ),+
875                    })?
876                ),+
877            ]
878        }
879    };
880}
881
882#[doc(hidden)]
883#[macro_export]
884macro_rules! __pin_project_make_proj_replace_ty_body {
885    (
886        [$proj_ty_ident:ident]
887        [$proj_vis:vis $struct_ty_ident:ident]
888        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
889        [$($body_data:tt)+]
890    ) => {
891        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
892        #[allow(dead_code)] // This lint warns unused fields/variants.
893        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
894        #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
895        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
896        #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
897        $proj_vis $struct_ty_ident $proj_ty_ident <$($impl_generics)*>
898        where
899            $($($where_clause)*)?
900        {
901            $($body_data)+
902        }
903    };
904}
905
906#[doc(hidden)]
907#[macro_export]
908macro_rules! __pin_project_make_proj_replace_block {
909    (
910        [$($proj_path:tt)+]
911        {
912            $(
913                $(#[$pin:ident])?
914                $field_vis:vis $field:ident
915            ),+
916        }
917    ) => {
918        let result = $($proj_path)* {
919            $(
920                $field: $crate::__pin_project_make_replace_field_proj!(
921                    $(#[$pin])? $field
922                )
923            ),+
924        };
925
926        {
927            ( $(
928                $crate::__pin_project_make_unsafe_drop_in_place_guard!(
929                    $(#[$pin])? $field
930                ),
931            )* );
932        }
933
934        result
935    };
936    ([$($proj_path:tt)+]) => { $($proj_path)* };
937}
938
939#[doc(hidden)]
940#[macro_export]
941macro_rules! __pin_project_struct_make_proj_method {
942    ([] $($variant:tt)*) => {};
943    (
944        [$proj_ty_ident:ident $_ignored_default_arg:ident]
945        [$proj_vis:vis]
946        [$method_ident:ident $get_method:ident $($mut:ident)?]
947        [$($ty_generics:tt)*]
948        $($variant:tt)*
949    ) => {
950        $crate::__pin_project_struct_make_proj_method! {
951            [$proj_ty_ident]
952            [$proj_vis]
953            [$method_ident $get_method $($mut)?]
954            [$($ty_generics)*]
955            $($variant)*
956        }
957    };
958    (
959        [$proj_ty_ident:ident]
960        [$proj_vis:vis]
961        [$method_ident:ident $get_method:ident $($mut:ident)?]
962        [$($ty_generics:tt)*]
963        {
964            $(
965                $(#[$pin:ident])?
966                $field_vis:vis $field:ident
967            ),+
968        }
969    ) => {
970        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
971        #[inline]
972        $proj_vis fn $method_ident<'__pin>(
973            self: $crate::__private::Pin<&'__pin $($mut)? Self>,
974        ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
975            unsafe {
976                let Self { $($field),* } = self.$get_method();
977                $proj_ty_ident {
978                    $(
979                        $field: $crate::__pin_project_make_unsafe_field_proj!(
980                            $(#[$pin])? $field
981                        )
982                    ),+
983                }
984            }
985        }
986    };
987}
988
989#[doc(hidden)]
990#[macro_export]
991macro_rules! __pin_project_struct_make_proj_replace_method {
992    ([] $($field:tt)*) => {};
993    (
994        [$proj_ty_ident:ident]
995        [$proj_vis:vis]
996        [$_proj_ty_ident:ident]
997        [$($ty_generics:tt)*]
998        {
999            $(
1000                $(#[$pin:ident])?
1001                $field_vis:vis $field:ident
1002            ),+
1003        }
1004    ) => {
1005        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
1006        #[inline]
1007        $proj_vis fn project_replace(
1008            self: $crate::__private::Pin<&mut Self>,
1009            replacement: Self,
1010        ) -> $proj_ty_ident <$($ty_generics)*> {
1011            unsafe {
1012                let __self_ptr: *mut Self = self.get_unchecked_mut();
1013
1014                // Destructors will run in reverse order, so next create a guard to overwrite
1015                // `self` with the replacement value without calling destructors.
1016                let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
1017
1018                let Self { $($field),* } = &mut *__self_ptr;
1019
1020                $crate::__pin_project_make_proj_replace_block! {
1021                    [$proj_ty_ident]
1022                    {
1023                        $(
1024                            $(#[$pin])?
1025                            $field
1026                        ),+
1027                    }
1028                }
1029            }
1030        }
1031    };
1032}
1033
1034#[doc(hidden)]
1035#[macro_export]
1036macro_rules! __pin_project_enum_make_proj_method {
1037    ([] $($variant:tt)*) => {};
1038    (
1039        [$proj_ty_ident:ident]
1040        [$proj_vis:vis]
1041        [$method_ident:ident $get_method:ident $($mut:ident)?]
1042        [$($ty_generics:tt)*]
1043        {
1044            $(
1045                $variant:ident $({
1046                    $(
1047                        $(#[$pin:ident])?
1048                        $field:ident
1049                    ),+
1050                })?
1051            ),+
1052        }
1053    ) => {
1054        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
1055        #[inline]
1056        $proj_vis fn $method_ident<'__pin>(
1057            self: $crate::__private::Pin<&'__pin $($mut)? Self>,
1058        ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
1059            unsafe {
1060                match self.$get_method() {
1061                    $(
1062                        Self::$variant $({
1063                            $($field),+
1064                        })? => {
1065                            $proj_ty_ident::$variant $({
1066                                $(
1067                                    $field: $crate::__pin_project_make_unsafe_field_proj!(
1068                                        $(#[$pin])? $field
1069                                    )
1070                                ),+
1071                            })?
1072                        }
1073                    ),+
1074                }
1075            }
1076        }
1077    };
1078}
1079
1080#[doc(hidden)]
1081#[macro_export]
1082macro_rules! __pin_project_enum_make_proj_replace_method {
1083    ([] $($field:tt)*) => {};
1084    (
1085        [$proj_ty_ident:ident]
1086        [$proj_vis:vis]
1087        [$($ty_generics:tt)*]
1088        {
1089            $(
1090                $variant:ident $({
1091                    $(
1092                        $(#[$pin:ident])?
1093                        $field:ident
1094                    ),+
1095                })?
1096            ),+
1097        }
1098    ) => {
1099        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
1100        #[inline]
1101        $proj_vis fn project_replace(
1102            self: $crate::__private::Pin<&mut Self>,
1103            replacement: Self,
1104        ) -> $proj_ty_ident <$($ty_generics)*> {
1105            unsafe {
1106                let __self_ptr: *mut Self = self.get_unchecked_mut();
1107
1108                // Destructors will run in reverse order, so next create a guard to overwrite
1109                // `self` with the replacement value without calling destructors.
1110                let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
1111
1112                match &mut *__self_ptr {
1113                    $(
1114                        Self::$variant $({
1115                            $($field),+
1116                        })? => {
1117                            $crate::__pin_project_make_proj_replace_block! {
1118                                [$proj_ty_ident :: $variant]
1119                                $({
1120                                    $(
1121                                        $(#[$pin])?
1122                                        $field
1123                                    ),+
1124                                })?
1125                            }
1126                        }
1127                    ),+
1128                }
1129            }
1130        }
1131    };
1132}
1133
1134#[doc(hidden)]
1135#[macro_export]
1136macro_rules! __pin_project_make_unpin_impl {
1137    (
1138        []
1139        [$vis:vis $ident:ident]
1140        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
1141        $($field:tt)*
1142    ) => {
1143        // Automatically create the appropriate conditional `Unpin` implementation.
1144        //
1145        // Basically this is equivalent to the following code:
1146        // ```
1147        // impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
1148        // ```
1149        //
1150        // However, if struct is public and there is a private type field,
1151        // this would cause an E0446 (private type in public interface).
1152        //
1153        // When RFC 2145 is implemented (rust-lang/rust#48054),
1154        // this will become a lint, rather then a hard error.
1155        //
1156        // As a workaround for this, we generate a new struct, containing all of the pinned
1157        // fields from our #[pin_project] type. This struct is declared within
1158        // a function, which makes it impossible to be named by user code.
1159        // This guarantees that it will use the default auto-trait impl for Unpin -
1160        // that is, it will implement Unpin iff all of its fields implement Unpin.
1161        // This type can be safely declared as 'public', satisfying the privacy
1162        // checker without actually allowing user code to access it.
1163        //
1164        // This allows users to apply the #[pin_project] attribute to types
1165        // regardless of the privacy of the types of their fields.
1166        //
1167        // See also https://github.com/taiki-e/pin-project/pull/53.
1168        #[allow(non_snake_case)]
1169        $vis struct __Origin <'__pin, $($impl_generics)*>
1170        $(where
1171            $($where_clause)*)?
1172        {
1173            __dummy_lifetime: $crate::__private::PhantomData<&'__pin ()>,
1174            $($field)*
1175        }
1176        impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>
1177        where
1178            __Origin <'__pin, $($ty_generics)*>: $crate::__private::Unpin
1179            $(, $($where_clause)*)?
1180        {
1181        }
1182    };
1183    (
1184        [$proj_not_unpin_mark:ident]
1185        [$vis:vis $ident:ident]
1186        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
1187        $($field:tt)*
1188    ) => {
1189        #[doc(hidden)]
1190        impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>
1191        where
1192            (
1193                ::core::marker::PhantomData<&'__pin ()>,
1194                ::core::marker::PhantomPinned,
1195            ): $crate::__private::Unpin
1196            $(, $($where_clause)*)?
1197        {
1198        }
1199    }
1200}
1201
1202#[doc(hidden)]
1203#[macro_export]
1204macro_rules! __pin_project_make_drop_impl {
1205    (
1206        [$_ident:ident]
1207        [$($_impl_generics:tt)*] [$($_ty_generics:tt)*] [$(where $($_where_clause:tt)*)?]
1208        $(#[$drop_impl_attrs:meta])*
1209        impl $(<
1210            $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
1211            $( $generics:ident
1212                $(: $generics_bound:path)?
1213                $(: ?$generics_unsized_bound:path)?
1214                $(: $generics_lifetime_bound:lifetime)?
1215            ),*
1216        >)? PinnedDrop for $self_ty:ty
1217        $(where
1218            $( $where_clause_ty:ty
1219                $(: $where_clause_bound:path)?
1220                $(: ?$where_clause_unsized_bound:path)?
1221                $(: $where_clause_lifetime_bound:lifetime)?
1222            ),* $(,)?
1223        )?
1224        {
1225            $(#[$drop_fn_attrs:meta])*
1226            fn drop($($arg:ident)+: Pin<&mut Self>) {
1227                $($tt:tt)*
1228            }
1229        }
1230    ) => {
1231        $(#[$drop_impl_attrs])*
1232        impl $(<
1233            $( $lifetime $(: $lifetime_bound)? ,)*
1234            $( $generics
1235                $(: $generics_bound)?
1236                $(: ?$generics_unsized_bound)?
1237                $(: $generics_lifetime_bound)?
1238            ),*
1239        >)? $crate::__private::Drop for $self_ty
1240        $(where
1241            $( $where_clause_ty
1242                $(: $where_clause_bound)?
1243                $(: ?$where_clause_unsized_bound)?
1244                $(: $where_clause_lifetime_bound)?
1245            ),*
1246        )?
1247        {
1248            $(#[$drop_fn_attrs])*
1249            fn drop(&mut self) {
1250                // Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe.
1251                // This is because destructors can be called multiple times in safe code and
1252                // [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
1253                //
1254                // `__drop_inner` is defined as a safe method, but this is fine since
1255                // `__drop_inner` is not accessible by the users and we call `__drop_inner` only
1256                // once.
1257                //
1258                // Users can implement [`Drop`] safely using `pin_project!` and can drop a
1259                // type that implements `PinnedDrop` using the [`drop`] function safely.
1260                fn __drop_inner $(<
1261                    $( $lifetime $(: $lifetime_bound)? ,)*
1262                    $( $generics
1263                        $(: $generics_bound)?
1264                        $(: ?$generics_unsized_bound)?
1265                        $(: $generics_lifetime_bound)?
1266                    ),*
1267                >)? (
1268                    $($arg)+: $crate::__private::Pin<&mut $self_ty>,
1269                )
1270                $(where
1271                    $( $where_clause_ty
1272                        $(: $where_clause_bound)?
1273                        $(: ?$where_clause_unsized_bound)?
1274                        $(: $where_clause_lifetime_bound)?
1275                    ),*
1276                )?
1277                {
1278                    // A dummy `__drop_inner` function to prevent users call outer `__drop_inner`.
1279                    fn __drop_inner() {}
1280                    $($tt)*
1281                }
1282
1283                // Safety - we're in 'drop', so we know that 'self' will
1284                // never move again.
1285                let pinned_self: $crate::__private::Pin<&mut Self>
1286                    = unsafe { $crate::__private::Pin::new_unchecked(self) };
1287                // We call `__drop_inner` only once. Since `__DropInner::__drop_inner`
1288                // is not accessible by the users, it is never called again.
1289                __drop_inner(pinned_self);
1290            }
1291        }
1292    };
1293    (
1294        [$ident:ident]
1295        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
1296    ) => {
1297        // Ensure that struct does not implement `Drop`.
1298        //
1299        // There are two possible cases:
1300        // 1. The user type does not implement Drop. In this case,
1301        // the first blanked impl will not apply to it. This code
1302        // will compile, as there is only one impl of MustNotImplDrop for the user type
1303        // 2. The user type does impl Drop. This will make the blanket impl applicable,
1304        // which will then conflict with the explicit MustNotImplDrop impl below.
1305        // This will result in a compilation error, which is exactly what we want.
1306        trait MustNotImplDrop {}
1307        #[allow(clippy::drop_bounds, drop_bounds)]
1308        impl<T: $crate::__private::Drop> MustNotImplDrop for T {}
1309        impl <$($impl_generics)*> MustNotImplDrop for $ident <$($ty_generics)*>
1310        $(where
1311            $($where_clause)*)?
1312        {
1313        }
1314    };
1315}
1316
1317#[doc(hidden)]
1318#[macro_export]
1319macro_rules! __pin_project_make_unpin_bound {
1320    (#[pin] $field_ty:ty) => {
1321        $field_ty
1322    };
1323    ($field_ty:ty) => {
1324        $crate::__private::AlwaysUnpin<$field_ty>
1325    };
1326}
1327
1328#[doc(hidden)]
1329#[macro_export]
1330macro_rules! __pin_project_make_unsafe_field_proj {
1331    (#[pin] $field:ident) => {
1332        $crate::__private::Pin::new_unchecked($field)
1333    };
1334    ($field:ident) => {
1335        $field
1336    };
1337}
1338
1339#[doc(hidden)]
1340#[macro_export]
1341macro_rules! __pin_project_make_replace_field_proj {
1342    (#[pin] $field:ident) => {
1343        $crate::__private::PhantomData
1344    };
1345    ($field:ident) => {
1346        $crate::__private::ptr::read($field)
1347    };
1348}
1349
1350#[doc(hidden)]
1351#[macro_export]
1352macro_rules! __pin_project_make_unsafe_drop_in_place_guard {
1353    (#[pin] $field:ident) => {
1354        $crate::__private::UnsafeDropInPlaceGuard::new($field)
1355    };
1356    ($field:ident) => {
1357        ()
1358    };
1359}
1360
1361#[doc(hidden)]
1362#[macro_export]
1363macro_rules! __pin_project_make_proj_field_mut {
1364    (#[pin] $field_ty:ty) => {
1365        $crate::__private::Pin<&'__pin mut ($field_ty)>
1366    };
1367    ($field_ty:ty) => {
1368        &'__pin mut ($field_ty)
1369    };
1370}
1371
1372#[doc(hidden)]
1373#[macro_export]
1374macro_rules! __pin_project_make_proj_field_ref {
1375    (#[pin] $field_ty:ty) => {
1376        $crate::__private::Pin<&'__pin ($field_ty)>
1377    };
1378    ($field_ty:ty) => {
1379        &'__pin ($field_ty)
1380    };
1381}
1382
1383#[doc(hidden)]
1384#[macro_export]
1385macro_rules! __pin_project_make_proj_field_replace {
1386    (#[pin] $field_ty:ty) => {
1387        $crate::__private::PhantomData<$field_ty>
1388    };
1389    ($field_ty:ty) => {
1390        $field_ty
1391    };
1392}
1393
1394#[doc(hidden)]
1395#[macro_export]
1396macro_rules! __pin_project_internal {
1397    // parsing proj_mut_ident
1398    (
1399        []
1400        [$($proj_ref_ident:ident)?]
1401        [$($proj_replace_ident:ident)?]
1402        [$( ! $proj_not_unpin_mark:ident)?]
1403        [$($attrs:tt)*]
1404
1405        #[project = $proj_mut_ident:ident]
1406        $($tt:tt)*
1407    ) => {
1408        $crate::__pin_project_internal! {
1409            [$proj_mut_ident]
1410            [$($proj_ref_ident)?]
1411            [$($proj_replace_ident)?]
1412            [$( ! $proj_not_unpin_mark)?]
1413            [$($attrs)*]
1414            $($tt)*
1415        }
1416    };
1417    // parsing proj_ref_ident
1418    (
1419        [$($proj_mut_ident:ident)?]
1420        []
1421        [$($proj_replace_ident:ident)?]
1422        [$( ! $proj_not_unpin_mark:ident)?]
1423        [$($attrs:tt)*]
1424
1425        #[project_ref = $proj_ref_ident:ident]
1426        $($tt:tt)*
1427    ) => {
1428        $crate::__pin_project_internal! {
1429            [$($proj_mut_ident)?]
1430            [$proj_ref_ident]
1431            [$($proj_replace_ident)?]
1432            [$( ! $proj_not_unpin_mark)?]
1433            [$($attrs)*]
1434            $($tt)*
1435        }
1436    };
1437    // parsing proj_replace_ident
1438    (
1439        [$($proj_mut_ident:ident)?]
1440        [$($proj_ref_ident:ident)?]
1441        []
1442        [$( ! $proj_not_unpin_mark:ident)?]
1443        [$($attrs:tt)*]
1444
1445        #[project_replace = $proj_replace_ident:ident]
1446        $($tt:tt)*
1447    ) => {
1448        $crate::__pin_project_internal! {
1449            [$($proj_mut_ident)?]
1450            [$($proj_ref_ident)?]
1451            [$proj_replace_ident]
1452            [$( ! $proj_not_unpin_mark)?]
1453            [$($attrs)*]
1454            $($tt)*
1455        }
1456    };
1457    // parsing !Unpin
1458    (
1459        [$($proj_mut_ident:ident)?]
1460        [$($proj_ref_ident:ident)?]
1461        [$($proj_replace_ident:ident)?]
1462        []
1463        [$($attrs:tt)*]
1464
1465        #[project( ! $proj_not_unpin_mark:ident)]
1466        $($tt:tt)*
1467    ) => {
1468        $crate::__pin_project_internal! {
1469            [$($proj_mut_ident)?]
1470            [$($proj_ref_ident)?]
1471            [$($proj_replace_ident)?]
1472            [ ! $proj_not_unpin_mark]
1473            [$($attrs)*]
1474            $($tt)*
1475        }
1476    };
1477    // this is actually part of a recursive step that picks off a single non-`pin_project_lite` attribute
1478    // there could be more to parse
1479    (
1480        [$($proj_mut_ident:ident)?]
1481        [$($proj_ref_ident:ident)?]
1482        [$($proj_replace_ident:ident)?]
1483        [$( ! $proj_not_unpin_mark:ident)?]
1484        [$($attrs:tt)*]
1485
1486        #[$($attr:tt)*]
1487        $($tt:tt)*
1488    ) => {
1489        $crate::__pin_project_internal! {
1490            [$($proj_mut_ident)?]
1491            [$($proj_ref_ident)?]
1492            [$($proj_replace_ident)?]
1493            [$( ! $proj_not_unpin_mark)?]
1494            [$($attrs)* #[$($attr)*]]
1495            $($tt)*
1496        }
1497    };
1498    // now determine visibility
1499    // if public, downgrade
1500    (
1501        [$($proj_mut_ident:ident)?]
1502        [$($proj_ref_ident:ident)?]
1503        [$($proj_replace_ident:ident)?]
1504        [$( ! $proj_not_unpin_mark:ident)?]
1505        [$($attrs:tt)*]
1506        pub $struct_ty_ident:ident $ident:ident
1507        $($tt:tt)*
1508    ) => {
1509        $crate::__pin_project_parse_generics! {
1510            [$($proj_mut_ident)?]
1511            [$($proj_ref_ident)?]
1512            [$($proj_replace_ident)?]
1513            [$($proj_not_unpin_mark)?]
1514            [$($attrs)*]
1515            [pub $struct_ty_ident $ident pub(crate)]
1516            $($tt)*
1517        }
1518    };
1519    (
1520        [$($proj_mut_ident:ident)?]
1521        [$($proj_ref_ident:ident)?]
1522        [$($proj_replace_ident:ident)?]
1523        [$( ! $proj_not_unpin_mark:ident)?]
1524        [$($attrs:tt)*]
1525        $vis:vis $struct_ty_ident:ident $ident:ident
1526        $($tt:tt)*
1527    ) => {
1528        $crate::__pin_project_parse_generics! {
1529            [$($proj_mut_ident)?]
1530            [$($proj_ref_ident)?]
1531            [$($proj_replace_ident)?]
1532            [$($proj_not_unpin_mark)?]
1533            [$($attrs)*]
1534            [$vis $struct_ty_ident $ident $vis]
1535            $($tt)*
1536        }
1537    };
1538}
1539
1540#[doc(hidden)]
1541#[macro_export]
1542macro_rules! __pin_project_parse_generics {
1543    (
1544        [$($proj_mut_ident:ident)?]
1545        [$($proj_ref_ident:ident)?]
1546        [$($proj_replace_ident:ident)?]
1547        [$($proj_not_unpin_mark:ident)?]
1548        [$($attrs:tt)*]
1549        [$vis:vis $struct_ty_ident:ident $ident:ident $proj_vis:vis]
1550        $(<
1551            $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
1552            $( $generics:ident
1553                $(: $generics_bound:path)?
1554                $(: ?$generics_unsized_bound:path)?
1555                $(: $generics_lifetime_bound:lifetime)?
1556                $(= $generics_default:ty)?
1557            ),* $(,)?
1558        >)?
1559        $(where
1560            $( $where_clause_ty:ty
1561                $(: $where_clause_bound:path)?
1562                $(: ?$where_clause_unsized_bound:path)?
1563                $(: $where_clause_lifetime_bound:lifetime)?
1564            ),* $(,)?
1565        )?
1566        {
1567            $($body_data:tt)*
1568        }
1569        $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?
1570    ) => {
1571        $crate::__pin_project_expand! {
1572            [$($proj_mut_ident)?]
1573            [$($proj_ref_ident)?]
1574            [$($proj_replace_ident)?]
1575            [$($proj_not_unpin_mark)?]
1576            [$proj_vis]
1577            [$($attrs)* $vis $struct_ty_ident $ident]
1578            [$(<
1579                $( $lifetime $(: $lifetime_bound)? ,)*
1580                $( $generics
1581                    $(: $generics_bound)?
1582                    $(: ?$generics_unsized_bound)?
1583                    $(: $generics_lifetime_bound)?
1584                    $(= $generics_default)?
1585                ),*
1586            >)?]
1587            [$(
1588                $( $lifetime $(: $lifetime_bound)? ,)*
1589                $( $generics
1590                    $(: $generics_bound)?
1591                    $(: ?$generics_unsized_bound)?
1592                    $(: $generics_lifetime_bound)?
1593                ),*
1594            )?]
1595            [$( $( $lifetime ,)* $( $generics ),* )?]
1596            [$(where $( $where_clause_ty
1597                $(: $where_clause_bound)?
1598                $(: ?$where_clause_unsized_bound)?
1599                $(: $where_clause_lifetime_bound)?
1600            ),* )?]
1601            {
1602                $($body_data)*
1603            }
1604            $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?
1605        }
1606    };
1607}
1608
1609// Not public API.
1610#[doc(hidden)]
1611#[allow(missing_debug_implementations)]
1612pub mod __private {
1613    use core::mem::ManuallyDrop;
1614    #[doc(hidden)]
1615    pub use core::{
1616        marker::{PhantomData, Unpin},
1617        ops::Drop,
1618        pin::Pin,
1619        ptr,
1620    };
1621
1622    // This is an internal helper struct used by `pin_project!`.
1623    #[doc(hidden)]
1624    pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);
1625
1626    impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
1627
1628    // This is an internal helper used to ensure a value is dropped.
1629    #[doc(hidden)]
1630    pub struct UnsafeDropInPlaceGuard<T: ?Sized>(*mut T);
1631
1632    impl<T: ?Sized> UnsafeDropInPlaceGuard<T> {
1633        #[doc(hidden)]
1634        pub unsafe fn new(ptr: *mut T) -> Self {
1635            Self(ptr)
1636        }
1637    }
1638
1639    impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
1640        fn drop(&mut self) {
1641            // SAFETY: the caller of `UnsafeDropInPlaceGuard::new` must guarantee
1642            // that `ptr` is valid for drop when this guard is destructed.
1643            unsafe {
1644                ptr::drop_in_place(self.0);
1645            }
1646        }
1647    }
1648
1649    // This is an internal helper used to ensure a value is overwritten without
1650    // its destructor being called.
1651    #[doc(hidden)]
1652    pub struct UnsafeOverwriteGuard<T> {
1653        target: *mut T,
1654        value: ManuallyDrop<T>,
1655    }
1656
1657    impl<T> UnsafeOverwriteGuard<T> {
1658        #[doc(hidden)]
1659        pub unsafe fn new(target: *mut T, value: T) -> Self {
1660            Self { target, value: ManuallyDrop::new(value) }
1661        }
1662    }
1663
1664    impl<T> Drop for UnsafeOverwriteGuard<T> {
1665        fn drop(&mut self) {
1666            // SAFETY: the caller of `UnsafeOverwriteGuard::new` must guarantee
1667            // that `target` is valid for writes when this guard is destructed.
1668            unsafe {
1669                ptr::write(self.target, ptr::read(&*self.value));
1670            }
1671        }
1672    }
1673}