Skip to main content

pin_project_lite/
lib.rs

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