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(
488 explicit_outlives_requirements, // https://github.com/rust-lang/rust/issues/60993
489 single_use_lifetimes, // https://github.com/rust-lang/rust/issues/55058
490 // This lint warns of `clippy::*` generated by external macros.
491 // We allow this lint for compatibility with older compilers.
492 clippy::unknown_clippy_lints,
493 clippy::absolute_paths,
494 clippy::min_ident_chars,
495 clippy::redundant_pub_crate, // This lint warns `pub(crate)` field in private struct.
496 clippy::single_char_lifetime_names,
497 clippy::used_underscore_binding
498 )]
499 const _: () = {
500 $crate::__pin_project_make_proj_ty! {
501 [$($proj_mut_ident)? Projection]
502 [$proj_vis struct $ident]
503 [__pin_project_make_proj_field_mut]
504 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
505 {
506 $(
507 $(#[$pin])?
508 $field_vis $field: $field_ty
509 ),+
510 }
511 }
512 $crate::__pin_project_make_proj_ty! {
513 [$($proj_ref_ident)? ProjectionRef]
514 [$proj_vis struct $ident]
515 [__pin_project_make_proj_field_ref]
516 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
517 {
518 $(
519 $(#[$pin])?
520 $field_vis $field: $field_ty
521 ),+
522 }
523 }
524
525 impl<$($impl_generics)*> $ident <$($ty_generics)*>
526 $(where
527 $($where_clause)*)?
528 {
529 $crate::__pin_project_struct_make_proj_method! {
530 [$($proj_mut_ident)? Projection]
531 [$proj_vis]
532 [project get_unchecked_mut mut]
533 [$($ty_generics)*]
534 {
535 $(
536 $(#[$pin])?
537 $field_vis $field
538 ),+
539 }
540 }
541 $crate::__pin_project_struct_make_proj_method! {
542 [$($proj_ref_ident)? ProjectionRef]
543 [$proj_vis]
544 [project_ref get_ref]
545 [$($ty_generics)*]
546 {
547 $(
548 $(#[$pin])?
549 $field_vis $field
550 ),+
551 }
552 }
553 $crate::__pin_project_struct_make_proj_replace_method! {
554 [$($proj_replace_ident)?]
555 [$proj_vis]
556 [ProjectionReplace]
557 [$($ty_generics)*]
558 {
559 $(
560 $(#[$pin])?
561 $field_vis $field
562 ),+
563 }
564 }
565 }
566
567 $crate::__pin_project_make_unpin_impl! {
568 [$($proj_not_unpin_mark)?]
569 [$vis $ident]
570 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
571 $(
572 $field: $crate::__pin_project_make_unpin_bound!(
573 $(#[$pin])? $field_ty
574 )
575 ),+
576 }
577
578 $crate::__pin_project_make_drop_impl! {
579 [$ident]
580 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
581 $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?
582 }
583
584 // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
585 //
586 // Taking a reference to a packed field is UB, and applying
587 // `#[forbid(unaligned_references)]` makes sure that doing this is a hard error.
588 //
589 // If the struct ends up having #[repr(packed)] applied somehow,
590 // this will generate an (unfriendly) error message. Under all reasonable
591 // circumstances, we'll detect the #[repr(packed)] attribute, and generate
592 // a much nicer error above.
593 //
594 // See https://github.com/taiki-e/pin-project/pull/34 for more details.
595 //
596 // Note:
597 // - Lint-based tricks aren't perfect, but they're much better than nothing:
598 // https://github.com/taiki-e/pin-project-lite/issues/26
599 //
600 // - Enable both unaligned_references and safe_packed_borrows lints
601 // because unaligned_references lint does not exist in older compilers:
602 // https://github.com/taiki-e/pin-project-lite/pull/55
603 // https://github.com/rust-lang/rust/pull/82525
604 #[forbid(unaligned_references, safe_packed_borrows)]
605 fn __assert_not_repr_packed <$($impl_generics)*> (this: &$ident <$($ty_generics)*>)
606 $(where
607 $($where_clause)*)?
608 {
609 $(
610 let _ = &this.$field;
611 )+
612 }
613 };
614 };
615 (
616 [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
617 [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]
618 [$($proj_not_unpin_mark:ident)?]
619 [$proj_vis:vis]
620 [$($def_generics:tt)*]
621 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
622 {
623 $(
624 $(#[$variant_attrs:meta])*
625 $variant:ident $({
626 $(
627 $(#[$pin:ident])?
628 $field:ident: $field_ty:ty
629 ),+ $(,)?
630 })?
631 ),+ $(,)?
632 }
633 $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?
634 ) => {
635 #[allow(
636 single_use_lifetimes, // https://github.com/rust-lang/rust/issues/55058
637 // This lint warns of `clippy::*` generated by external macros.
638 // We allow this lint for compatibility with older compilers.
639 clippy::unknown_clippy_lints,
640 clippy::absolute_paths,
641 clippy::min_ident_chars,
642 clippy::single_char_lifetime_names,
643 clippy::used_underscore_binding
644 )]
645 const _: () = {
646 impl<$($impl_generics)*> $ident <$($ty_generics)*>
647 $(where
648 $($where_clause)*)?
649 {
650 $crate::__pin_project_enum_make_proj_method! {
651 [$($proj_mut_ident)?]
652 [$proj_vis]
653 [project get_unchecked_mut mut]
654 [$($ty_generics)*]
655 {
656 $(
657 $variant $({
658 $(
659 $(#[$pin])?
660 $field
661 ),+
662 })?
663 ),+
664 }
665 }
666 $crate::__pin_project_enum_make_proj_method! {
667 [$($proj_ref_ident)?]
668 [$proj_vis]
669 [project_ref get_ref]
670 [$($ty_generics)*]
671 {
672 $(
673 $variant $({
674 $(
675 $(#[$pin])?
676 $field
677 ),+
678 })?
679 ),+
680 }
681 }
682 $crate::__pin_project_enum_make_proj_replace_method! {
683 [$($proj_replace_ident)?]
684 [$proj_vis]
685 [$($ty_generics)*]
686 {
687 $(
688 $variant $({
689 $(
690 $(#[$pin])?
691 $field
692 ),+
693 })?
694 ),+
695 }
696 }
697 }
698
699 $crate::__pin_project_make_unpin_impl! {
700 [$($proj_not_unpin_mark)?]
701 [$vis $ident]
702 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
703 $(
704 $variant: ($(
705 $(
706 $crate::__pin_project_make_unpin_bound!(
707 $(#[$pin])? $field_ty
708 )
709 ),+
710 )?)
711 ),+
712 }
713
714 $crate::__pin_project_make_drop_impl! {
715 [$ident]
716 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
717 $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?
718 }
719
720 // We don't need to check for '#[repr(packed)]',
721 // since it does not apply to enums.
722 };
723 };
724}
725
726#[doc(hidden)]
727#[macro_export]
728macro_rules! __pin_project_reconstruct {
729 (
730 [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
731 [$($def_generics:tt)*] [$($impl_generics:tt)*]
732 [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
733 {
734 $(
735 $(#[$pin:ident])?
736 $field_vis:vis $field:ident: $field_ty:ty
737 ),+ $(,)?
738 }
739 ) => {
740 $(#[$attrs])*
741 $vis struct $ident $($def_generics)*
742 $(where
743 $($where_clause)*)?
744 {
745 $(
746 $field_vis $field: $field_ty
747 ),+
748 }
749 };
750 (
751 [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
752 [$($def_generics:tt)*] [$($impl_generics:tt)*]
753 [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
754 {
755 $(
756 $(#[$variant_attrs:meta])*
757 $variant:ident $({
758 $(
759 $(#[$pin:ident])?
760 $field:ident: $field_ty:ty
761 ),+ $(,)?
762 })?
763 ),+ $(,)?
764 }
765 ) => {
766 $(#[$attrs])*
767 $vis enum $ident $($def_generics)*
768 $(where
769 $($where_clause)*)?
770 {
771 $(
772 $(#[$variant_attrs])*
773 $variant $({
774 $(
775 $field: $field_ty
776 ),+
777 })?
778 ),+
779 }
780 };
781}
782
783#[doc(hidden)]
784#[macro_export]
785macro_rules! __pin_project_make_proj_ty {
786 ([] $($field:tt)*) => {};
787 (
788 [$proj_ty_ident:ident $default_ident:ident]
789 [$proj_vis:vis struct $ident:ident]
790 $($field:tt)*
791 ) => {};
792 (
793 [$proj_ty_ident:ident]
794 [$proj_vis:vis struct $ident:ident]
795 [$__pin_project_make_proj_field:ident]
796 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
797 {
798 $(
799 $(#[$pin:ident])?
800 $field_vis:vis $field:ident: $field_ty:ty
801 ),+ $(,)?
802 }
803 ) => {
804 $crate::__pin_project_make_proj_ty_body! {
805 [$proj_ty_ident]
806 [$proj_vis struct $ident]
807 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
808 [
809 $(
810 $field_vis $field: $crate::$__pin_project_make_proj_field!(
811 $(#[$pin])? $field_ty
812 )
813 ),+
814 ]
815 }
816 };
817 (
818 [$proj_ty_ident:ident]
819 [$proj_vis:vis enum $ident:ident]
820 [$__pin_project_make_proj_field:ident]
821 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
822 {
823 $(
824 $(#[$variant_attrs:meta])*
825 $variant:ident $({
826 $(
827 $(#[$pin:ident])?
828 $field:ident: $field_ty:ty
829 ),+ $(,)?
830 })?
831 ),+ $(,)?
832 }
833 ) => {
834 $crate::__pin_project_make_proj_ty_body! {
835 [$proj_ty_ident]
836 [$proj_vis enum $ident]
837 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
838 [
839 $(
840 $variant $({
841 $(
842 $field: $crate::$__pin_project_make_proj_field!(
843 $(#[$pin])? $field_ty
844 )
845 ),+
846 })?
847 ),+
848 ]
849 }
850 };
851}
852
853#[doc(hidden)]
854#[macro_export]
855macro_rules! __pin_project_make_proj_ty_body {
856 (
857 [$proj_ty_ident:ident]
858 [$proj_vis:vis $struct_ty_ident:ident $ident:ident]
859 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
860 [$($body_data:tt)+]
861 ) => {
862 #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
863 #[allow(
864 dead_code, // This lint warns unused fields/variants.
865 single_use_lifetimes, // https://github.com/rust-lang/rust/issues/55058
866 // This lint warns of `clippy::*` generated by external macros.
867 // We allow this lint for compatibility with older compilers.
868 clippy::unknown_clippy_lints,
869 clippy::absolute_paths,
870 clippy::min_ident_chars,
871 clippy::mut_mut, // This lint warns `&mut &mut <ty>`. (only needed for project)
872 clippy::redundant_pub_crate, // This lint warns `pub(crate)` field in private struct.
873 clippy::ref_option_ref, // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
874 clippy::single_char_lifetime_names,
875 clippy::type_repetition_in_bounds // https://github.com/rust-lang/rust-clippy/issues/4326
876 )]
877 $proj_vis $struct_ty_ident $proj_ty_ident <'__pin, $($impl_generics)*>
878 where
879 $ident <$($ty_generics)*>: '__pin
880 $(, $($where_clause)*)?
881 {
882 $($body_data)+
883 }
884 };
885}
886
887#[doc(hidden)]
888#[macro_export]
889macro_rules! __pin_project_make_proj_replace_ty {
890 ([] $($field:tt)*) => {};
891 (
892 [$proj_ty_ident:ident]
893 [$proj_vis:vis struct]
894 [$__pin_project_make_proj_field:ident]
895 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
896 {
897 $(
898 $(#[$pin:ident])?
899 $field_vis:vis $field:ident: $field_ty:ty
900 ),+ $(,)?
901 }
902 ) => {
903 $crate::__pin_project_make_proj_replace_ty_body! {
904 [$proj_ty_ident]
905 [$proj_vis struct]
906 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
907 [
908 $(
909 $field_vis $field: $crate::$__pin_project_make_proj_field!(
910 $(#[$pin])? $field_ty
911 )
912 ),+
913 ]
914 }
915 };
916 (
917 [$proj_ty_ident:ident]
918 [$proj_vis:vis enum]
919 [$__pin_project_make_proj_field:ident]
920 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
921 {
922 $(
923 $(#[$variant_attrs:meta])*
924 $variant:ident $({
925 $(
926 $(#[$pin:ident])?
927 $field:ident: $field_ty:ty
928 ),+ $(,)?
929 })?
930 ),+ $(,)?
931 }
932 ) => {
933 $crate::__pin_project_make_proj_replace_ty_body! {
934 [$proj_ty_ident]
935 [$proj_vis enum]
936 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
937 [
938 $(
939 $variant $({
940 $(
941 $field: $crate::$__pin_project_make_proj_field!(
942 $(#[$pin])? $field_ty
943 )
944 ),+
945 })?
946 ),+
947 ]
948 }
949 };
950}
951
952#[doc(hidden)]
953#[macro_export]
954macro_rules! __pin_project_make_proj_replace_ty_body {
955 (
956 [$proj_ty_ident:ident]
957 [$proj_vis:vis $struct_ty_ident:ident]
958 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
959 [$($body_data:tt)+]
960 ) => {
961 #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
962 #[allow(
963 dead_code, // This lint warns unused fields/variants.
964 single_use_lifetimes, // https://github.com/rust-lang/rust/issues/55058
965 // This lint warns of `clippy::*` generated by external macros.
966 // We allow this lint for compatibility with older compilers.
967 clippy::unknown_clippy_lints,
968 clippy::absolute_paths,
969 clippy::min_ident_chars,
970 clippy::mut_mut, // This lint warns `&mut &mut <ty>`. (only needed for project)
971 clippy::redundant_pub_crate, // This lint warns `pub(crate)` field in private struct.
972 clippy::single_char_lifetime_names,
973 clippy::type_repetition_in_bounds // https://github.com/rust-lang/rust-clippy/issues/4326
974 )]
975 $proj_vis $struct_ty_ident $proj_ty_ident <$($impl_generics)*>
976 where
977 $($($where_clause)*)?
978 {
979 $($body_data)+
980 }
981 };
982}
983
984#[doc(hidden)]
985#[macro_export]
986macro_rules! __pin_project_make_proj_replace_block {
987 (
988 [$($proj_path:tt)+]
989 {
990 $(
991 $(#[$pin:ident])?
992 $field_vis:vis $field:ident
993 ),+
994 }
995 ) => {
996 let result = $($proj_path)* {
997 $(
998 $field: $crate::__pin_project_make_replace_field_proj!(
999 $(#[$pin])? $field
1000 )
1001 ),+
1002 };
1003
1004 {
1005 ( $(
1006 $crate::__pin_project_make_unsafe_drop_in_place_guard!(
1007 $(#[$pin])? $field
1008 ),
1009 )* );
1010 }
1011
1012 result
1013 };
1014 ([$($proj_path:tt)+]) => { $($proj_path)* };
1015}
1016
1017#[doc(hidden)]
1018#[macro_export]
1019macro_rules! __pin_project_struct_make_proj_method {
1020 ([] $($variant:tt)*) => {};
1021 (
1022 [$proj_ty_ident:ident $_ignored_default_arg:ident]
1023 [$proj_vis:vis]
1024 [$method_ident:ident $get_method:ident $($mut:ident)?]
1025 [$($ty_generics:tt)*]
1026 $($variant:tt)*
1027 ) => {
1028 $crate::__pin_project_struct_make_proj_method! {
1029 [$proj_ty_ident]
1030 [$proj_vis]
1031 [$method_ident $get_method $($mut)?]
1032 [$($ty_generics)*]
1033 $($variant)*
1034 }
1035 };
1036 (
1037 [$proj_ty_ident:ident]
1038 [$proj_vis:vis]
1039 [$method_ident:ident $get_method:ident $($mut:ident)?]
1040 [$($ty_generics:tt)*]
1041 {
1042 $(
1043 $(#[$pin:ident])?
1044 $field_vis:vis $field:ident
1045 ),+
1046 }
1047 ) => {
1048 #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
1049 #[inline]
1050 $proj_vis fn $method_ident<'__pin>(
1051 self: $crate::__private::Pin<&'__pin $($mut)? Self>,
1052 ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
1053 unsafe {
1054 let Self { $($field),* } = self.$get_method();
1055 $proj_ty_ident {
1056 $(
1057 $field: $crate::__pin_project_make_unsafe_field_proj!(
1058 $(#[$pin])? $field
1059 )
1060 ),+
1061 }
1062 }
1063 }
1064 };
1065}
1066
1067#[doc(hidden)]
1068#[macro_export]
1069macro_rules! __pin_project_struct_make_proj_replace_method {
1070 ([] $($field:tt)*) => {};
1071 (
1072 [$proj_ty_ident:ident]
1073 [$proj_vis:vis]
1074 [$_proj_ty_ident:ident]
1075 [$($ty_generics:tt)*]
1076 {
1077 $(
1078 $(#[$pin:ident])?
1079 $field_vis:vis $field:ident
1080 ),+
1081 }
1082 ) => {
1083 #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
1084 #[inline]
1085 $proj_vis fn project_replace(
1086 self: $crate::__private::Pin<&mut Self>,
1087 replacement: Self,
1088 ) -> $proj_ty_ident <$($ty_generics)*> {
1089 unsafe {
1090 let __self_ptr: *mut Self = self.get_unchecked_mut();
1091
1092 // Destructors will run in reverse order, so next create a guard to overwrite
1093 // `self` with the replacement value without calling destructors.
1094 let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
1095
1096 let Self { $($field),* } = &mut *__self_ptr;
1097
1098 $crate::__pin_project_make_proj_replace_block! {
1099 [$proj_ty_ident]
1100 {
1101 $(
1102 $(#[$pin])?
1103 $field
1104 ),+
1105 }
1106 }
1107 }
1108 }
1109 };
1110}
1111
1112#[doc(hidden)]
1113#[macro_export]
1114macro_rules! __pin_project_enum_make_proj_method {
1115 ([] $($variant:tt)*) => {};
1116 (
1117 [$proj_ty_ident:ident]
1118 [$proj_vis:vis]
1119 [$method_ident:ident $get_method:ident $($mut:ident)?]
1120 [$($ty_generics:tt)*]
1121 {
1122 $(
1123 $variant:ident $({
1124 $(
1125 $(#[$pin:ident])?
1126 $field:ident
1127 ),+
1128 })?
1129 ),+
1130 }
1131 ) => {
1132 #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
1133 #[inline]
1134 $proj_vis fn $method_ident<'__pin>(
1135 self: $crate::__private::Pin<&'__pin $($mut)? Self>,
1136 ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
1137 unsafe {
1138 match self.$get_method() {
1139 $(
1140 Self::$variant $({
1141 $($field),+
1142 })? => {
1143 $proj_ty_ident::$variant $({
1144 $(
1145 $field: $crate::__pin_project_make_unsafe_field_proj!(
1146 $(#[$pin])? $field
1147 )
1148 ),+
1149 })?
1150 }
1151 ),+
1152 }
1153 }
1154 }
1155 };
1156}
1157
1158#[doc(hidden)]
1159#[macro_export]
1160macro_rules! __pin_project_enum_make_proj_replace_method {
1161 ([] $($field:tt)*) => {};
1162 (
1163 [$proj_ty_ident:ident]
1164 [$proj_vis:vis]
1165 [$($ty_generics:tt)*]
1166 {
1167 $(
1168 $variant:ident $({
1169 $(
1170 $(#[$pin:ident])?
1171 $field:ident
1172 ),+
1173 })?
1174 ),+
1175 }
1176 ) => {
1177 #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.
1178 #[inline]
1179 $proj_vis fn project_replace(
1180 self: $crate::__private::Pin<&mut Self>,
1181 replacement: Self,
1182 ) -> $proj_ty_ident <$($ty_generics)*> {
1183 unsafe {
1184 let __self_ptr: *mut Self = self.get_unchecked_mut();
1185
1186 // Destructors will run in reverse order, so next create a guard to overwrite
1187 // `self` with the replacement value without calling destructors.
1188 let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
1189
1190 match &mut *__self_ptr {
1191 $(
1192 Self::$variant $({
1193 $($field),+
1194 })? => {
1195 $crate::__pin_project_make_proj_replace_block! {
1196 [$proj_ty_ident :: $variant]
1197 $({
1198 $(
1199 $(#[$pin])?
1200 $field
1201 ),+
1202 })?
1203 }
1204 }
1205 ),+
1206 }
1207 }
1208 }
1209 };
1210}
1211
1212#[doc(hidden)]
1213#[macro_export]
1214macro_rules! __pin_project_make_unpin_impl {
1215 (
1216 []
1217 [$vis:vis $ident:ident]
1218 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
1219 $($field:tt)*
1220 ) => {
1221 // Automatically create the appropriate conditional `Unpin` implementation.
1222 //
1223 // Basically this is equivalent to the following code:
1224 // ```
1225 // impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
1226 // ```
1227 //
1228 // However, if struct is public and there is a private type field,
1229 // this would cause an E0446 (private type in public interface).
1230 //
1231 // When RFC 2145 is implemented (rust-lang/rust#48054),
1232 // this will become a lint, rather than a hard error.
1233 //
1234 // As a workaround for this, we generate a new struct, containing all of the pinned
1235 // fields from our #[pin_project] type. This struct is declared within
1236 // a function, which makes it impossible to be named by user code.
1237 // This guarantees that it will use the default auto-trait impl for Unpin -
1238 // that is, it will implement Unpin iff all of its fields implement Unpin.
1239 // This type can be safely declared as 'public', satisfying the privacy
1240 // checker without actually allowing user code to access it.
1241 //
1242 // This allows users to apply the #[pin_project] attribute to types
1243 // regardless of the privacy of the types of their fields.
1244 //
1245 // See also https://github.com/taiki-e/pin-project/pull/53.
1246 #[allow(non_snake_case)]
1247 $vis struct __Origin<'__pin, $($impl_generics)*>
1248 $(where
1249 $($where_clause)*)?
1250 {
1251 __dummy_lifetime: $crate::__private::PhantomData<&'__pin ()>,
1252 $($field)*
1253 }
1254 impl<'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>
1255 where
1256 $crate::__private::PinnedFieldsOf<__Origin<'__pin, $($ty_generics)*>>:
1257 $crate::__private::Unpin
1258 $(, $($where_clause)*)?
1259 {
1260 }
1261 };
1262 (
1263 [$proj_not_unpin_mark:ident]
1264 [$vis:vis $ident:ident]
1265 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
1266 $($field:tt)*
1267 ) => {
1268 // TODO: Using `<unsized type>: Sized` here allow emulating real negative_impls...
1269 // https://github.com/taiki-e/pin-project/issues/340#issuecomment-2428002670
1270 #[doc(hidden)]
1271 impl<'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>
1272 where
1273 (
1274 $crate::__private::PhantomData<&'__pin ()>,
1275 $crate::__private::PhantomPinned,
1276 ): $crate::__private::Unpin
1277 $(, $($where_clause)*)?
1278 {
1279 }
1280 }
1281}
1282
1283#[doc(hidden)]
1284#[macro_export]
1285macro_rules! __pin_project_make_drop_impl {
1286 (
1287 [$_ident:ident]
1288 [$($_impl_generics:tt)*] [$($_ty_generics:tt)*] [$(where $($_where_clause:tt)*)?]
1289 $(#[$drop_impl_attrs:meta])*
1290 impl $(<
1291 $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
1292 $( $generics:ident
1293 $(: $generics_bound:path)?
1294 $(: ?$generics_unsized_bound:path)?
1295 $(: $generics_lifetime_bound:lifetime)?
1296 ),*
1297 >)? PinnedDrop for $self_ty:ty
1298 $(where
1299 $( $where_clause_ty:ty
1300 $(: $where_clause_bound:path)?
1301 $(: ?$where_clause_unsized_bound:path)?
1302 $(: $where_clause_lifetime_bound:lifetime)?
1303 ),* $(,)?
1304 )?
1305 {
1306 $(#[$drop_fn_attrs:meta])*
1307 fn drop($($arg:ident)+: Pin<&mut Self>) {
1308 $($tt:tt)*
1309 }
1310 }
1311 ) => {
1312 $(#[$drop_impl_attrs])*
1313 impl $(<
1314 $( $lifetime $(: $lifetime_bound)? ,)*
1315 $( $generics
1316 $(: $generics_bound)?
1317 $(: ?$generics_unsized_bound)?
1318 $(: $generics_lifetime_bound)?
1319 ),*
1320 >)? $crate::__private::Drop for $self_ty
1321 $(where
1322 $( $where_clause_ty
1323 $(: $where_clause_bound)?
1324 $(: ?$where_clause_unsized_bound)?
1325 $(: $where_clause_lifetime_bound)?
1326 ),*
1327 )?
1328 {
1329 $(#[$drop_fn_attrs])*
1330 fn drop(&mut self) {
1331 // Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe.
1332 // This is because destructors can be called multiple times in safe code and
1333 // [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
1334 //
1335 // `__drop_inner` is defined as a safe method, but this is fine since
1336 // `__drop_inner` is not accessible by the users and we call `__drop_inner` only
1337 // once.
1338 //
1339 // Users can implement [`Drop`] safely using `pin_project!` and can drop a
1340 // type that implements `PinnedDrop` using the [`drop`] function safely.
1341 fn __drop_inner $(<
1342 $( $lifetime $(: $lifetime_bound)? ,)*
1343 $( $generics
1344 $(: $generics_bound)?
1345 $(: ?$generics_unsized_bound)?
1346 $(: $generics_lifetime_bound)?
1347 ),*
1348 >)? (
1349 $($arg)+: $crate::__private::Pin<&mut $self_ty>,
1350 )
1351 $(where
1352 $( $where_clause_ty
1353 $(: $where_clause_bound)?
1354 $(: ?$where_clause_unsized_bound)?
1355 $(: $where_clause_lifetime_bound)?
1356 ),*
1357 )?
1358 {
1359 // A dummy `__drop_inner` function to prevent users call outer `__drop_inner`.
1360 fn __drop_inner() {}
1361 $($tt)*
1362 }
1363
1364 // Safety - we're in 'drop', so we know that 'self' will
1365 // never move again.
1366 let pinned_self: $crate::__private::Pin<&mut Self>
1367 = unsafe { $crate::__private::Pin::new_unchecked(self) };
1368 // We call `__drop_inner` only once. Since `__DropInner::__drop_inner`
1369 // is not accessible by the users, it is never called again.
1370 __drop_inner(pinned_self);
1371 }
1372 }
1373 };
1374 (
1375 [$ident:ident]
1376 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
1377 ) => {
1378 // Ensure that struct does not implement `Drop`.
1379 //
1380 // There are two possible cases:
1381 // 1. The user type does not implement Drop. In this case,
1382 // the first blanket impl will not apply to it. This code
1383 // will compile, as there is only one impl of MustNotImplDrop for the user type
1384 // 2. The user type does impl Drop. This will make the blanket impl applicable,
1385 // which will then conflict with the explicit MustNotImplDrop impl below.
1386 // This will result in a compilation error, which is exactly what we want.
1387 trait MustNotImplDrop {}
1388 #[allow(clippy::drop_bounds, drop_bounds)]
1389 impl<T: $crate::__private::Drop> MustNotImplDrop for T {}
1390 impl<$($impl_generics)*> MustNotImplDrop for $ident <$($ty_generics)*>
1391 $(where
1392 $($where_clause)*)?
1393 {
1394 }
1395 };
1396}
1397
1398#[doc(hidden)]
1399#[macro_export]
1400macro_rules! __pin_project_make_unpin_bound {
1401 (#[pin] $field_ty:ty) => {
1402 $field_ty
1403 };
1404 ($field_ty:ty) => {
1405 $crate::__private::AlwaysUnpin<$field_ty>
1406 };
1407}
1408
1409#[doc(hidden)]
1410#[macro_export]
1411macro_rules! __pin_project_make_unsafe_field_proj {
1412 (#[pin] $field:ident) => {
1413 $crate::__private::Pin::new_unchecked($field)
1414 };
1415 ($field:ident) => {
1416 $field
1417 };
1418}
1419
1420#[doc(hidden)]
1421#[macro_export]
1422macro_rules! __pin_project_make_replace_field_proj {
1423 (#[pin] $field:ident) => {
1424 $crate::__private::PhantomData
1425 };
1426 ($field:ident) => {
1427 $crate::__private::ptr::read($field)
1428 };
1429}
1430
1431#[doc(hidden)]
1432#[macro_export]
1433macro_rules! __pin_project_make_unsafe_drop_in_place_guard {
1434 (#[pin] $field:ident) => {
1435 $crate::__private::UnsafeDropInPlaceGuard::new($field)
1436 };
1437 ($field:ident) => {
1438 ()
1439 };
1440}
1441
1442#[doc(hidden)]
1443#[macro_export]
1444macro_rules! __pin_project_make_proj_field_mut {
1445 (#[pin] $field_ty:ty) => {
1446 $crate::__private::Pin<&'__pin mut ($field_ty)>
1447 };
1448 ($field_ty:ty) => {
1449 &'__pin mut ($field_ty)
1450 };
1451}
1452
1453#[doc(hidden)]
1454#[macro_export]
1455macro_rules! __pin_project_make_proj_field_ref {
1456 (#[pin] $field_ty:ty) => {
1457 $crate::__private::Pin<&'__pin ($field_ty)>
1458 };
1459 ($field_ty:ty) => {
1460 &'__pin ($field_ty)
1461 };
1462}
1463
1464#[doc(hidden)]
1465#[macro_export]
1466macro_rules! __pin_project_make_proj_field_replace {
1467 (#[pin] $field_ty:ty) => {
1468 $crate::__private::PhantomData<$field_ty>
1469 };
1470 ($field_ty:ty) => {
1471 $field_ty
1472 };
1473}
1474
1475#[doc(hidden)]
1476#[macro_export]
1477macro_rules! __pin_project_internal {
1478 // parsing proj_mut_ident
1479 (
1480 []
1481 [$($proj_ref_ident:ident)?]
1482 [$($proj_replace_ident:ident)?]
1483 [$( ! $proj_not_unpin_mark:ident)?]
1484 [$($attrs:tt)*]
1485
1486 #[project = $proj_mut_ident:ident]
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)*]
1495 $($tt)*
1496 }
1497 };
1498 // parsing proj_ref_ident
1499 (
1500 [$($proj_mut_ident:ident)?]
1501 []
1502 [$($proj_replace_ident:ident)?]
1503 [$( ! $proj_not_unpin_mark:ident)?]
1504 [$($attrs:tt)*]
1505
1506 #[project_ref = $proj_ref_ident:ident]
1507 $($tt:tt)*
1508 ) => {
1509 $crate::__pin_project_internal! {
1510 [$($proj_mut_ident)?]
1511 [$proj_ref_ident]
1512 [$($proj_replace_ident)?]
1513 [$( ! $proj_not_unpin_mark)?]
1514 [$($attrs)*]
1515 $($tt)*
1516 }
1517 };
1518 // parsing proj_replace_ident
1519 (
1520 [$($proj_mut_ident:ident)?]
1521 [$($proj_ref_ident:ident)?]
1522 []
1523 [$( ! $proj_not_unpin_mark:ident)?]
1524 [$($attrs:tt)*]
1525
1526 #[project_replace = $proj_replace_ident:ident]
1527 $($tt:tt)*
1528 ) => {
1529 $crate::__pin_project_internal! {
1530 [$($proj_mut_ident)?]
1531 [$($proj_ref_ident)?]
1532 [$proj_replace_ident]
1533 [$( ! $proj_not_unpin_mark)?]
1534 [$($attrs)*]
1535 $($tt)*
1536 }
1537 };
1538 // parsing !Unpin
1539 (
1540 [$($proj_mut_ident:ident)?]
1541 [$($proj_ref_ident:ident)?]
1542 [$($proj_replace_ident:ident)?]
1543 []
1544 [$($attrs:tt)*]
1545
1546 #[project( ! $proj_not_unpin_mark:ident)]
1547 $($tt:tt)*
1548 ) => {
1549 $crate::__pin_project_internal! {
1550 [$($proj_mut_ident)?]
1551 [$($proj_ref_ident)?]
1552 [$($proj_replace_ident)?]
1553 [ ! $proj_not_unpin_mark]
1554 [$($attrs)*]
1555 $($tt)*
1556 }
1557 };
1558 // this is actually part of a recursive step that picks off a single non-`pin_project_lite` attribute
1559 // there could be more to parse
1560 (
1561 [$($proj_mut_ident:ident)?]
1562 [$($proj_ref_ident:ident)?]
1563 [$($proj_replace_ident:ident)?]
1564 [$( ! $proj_not_unpin_mark:ident)?]
1565 [$($attrs:tt)*]
1566
1567 #[$($attr:tt)*]
1568 $($tt:tt)*
1569 ) => {
1570 $crate::__pin_project_internal! {
1571 [$($proj_mut_ident)?]
1572 [$($proj_ref_ident)?]
1573 [$($proj_replace_ident)?]
1574 [$( ! $proj_not_unpin_mark)?]
1575 [$($attrs)* #[$($attr)*]]
1576 $($tt)*
1577 }
1578 };
1579 // now determine visibility
1580 // if public, downgrade
1581 (
1582 [$($proj_mut_ident:ident)?]
1583 [$($proj_ref_ident:ident)?]
1584 [$($proj_replace_ident:ident)?]
1585 [$( ! $proj_not_unpin_mark:ident)?]
1586 [$($attrs:tt)*]
1587 pub $struct_ty_ident:ident $ident:ident
1588 $($tt:tt)*
1589 ) => {
1590 $crate::__pin_project_parse_generics! {
1591 [$($proj_mut_ident)?]
1592 [$($proj_ref_ident)?]
1593 [$($proj_replace_ident)?]
1594 [$($proj_not_unpin_mark)?]
1595 [$($attrs)*]
1596 [pub $struct_ty_ident $ident pub(crate)]
1597 $($tt)*
1598 }
1599 };
1600 (
1601 [$($proj_mut_ident:ident)?]
1602 [$($proj_ref_ident:ident)?]
1603 [$($proj_replace_ident:ident)?]
1604 [$( ! $proj_not_unpin_mark:ident)?]
1605 [$($attrs:tt)*]
1606 $vis:vis $struct_ty_ident:ident $ident:ident
1607 $($tt:tt)*
1608 ) => {
1609 $crate::__pin_project_parse_generics! {
1610 [$($proj_mut_ident)?]
1611 [$($proj_ref_ident)?]
1612 [$($proj_replace_ident)?]
1613 [$($proj_not_unpin_mark)?]
1614 [$($attrs)*]
1615 [$vis $struct_ty_ident $ident $vis]
1616 $($tt)*
1617 }
1618 };
1619}
1620
1621#[doc(hidden)]
1622#[macro_export]
1623macro_rules! __pin_project_parse_generics {
1624 (
1625 [$($proj_mut_ident:ident)?]
1626 [$($proj_ref_ident:ident)?]
1627 [$($proj_replace_ident:ident)?]
1628 [$($proj_not_unpin_mark:ident)?]
1629 [$($attrs:tt)*]
1630 [$vis:vis $struct_ty_ident:ident $ident:ident $proj_vis:vis]
1631 $(<
1632 $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
1633 $( $generics:ident
1634 $(: $generics_bound:path)?
1635 $(: ?$generics_unsized_bound:path)?
1636 $(: $generics_lifetime_bound:lifetime)?
1637 $(= $generics_default:ty)?
1638 ),* $(,)?
1639 >)?
1640 $(where
1641 $( $where_clause_ty:ty
1642 $(: $where_clause_bound:path)?
1643 $(: ?$where_clause_unsized_bound:path)?
1644 $(: $where_clause_lifetime_bound:lifetime)?
1645 ),* $(,)?
1646 )?
1647 {
1648 $($body_data:tt)*
1649 }
1650 $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?
1651 ) => {
1652 $crate::__pin_project_expand! {
1653 [$($proj_mut_ident)?]
1654 [$($proj_ref_ident)?]
1655 [$($proj_replace_ident)?]
1656 [$($proj_not_unpin_mark)?]
1657 [$proj_vis]
1658 [$($attrs)* $vis $struct_ty_ident $ident]
1659 [$(<
1660 $( $lifetime $(: $lifetime_bound)? ,)*
1661 $( $generics
1662 $(: $generics_bound)?
1663 $(: ?$generics_unsized_bound)?
1664 $(: $generics_lifetime_bound)?
1665 $(= $generics_default)?
1666 ),*
1667 >)?]
1668 [$(
1669 $( $lifetime $(: $lifetime_bound)? ,)*
1670 $( $generics
1671 $(: $generics_bound)?
1672 $(: ?$generics_unsized_bound)?
1673 $(: $generics_lifetime_bound)?
1674 ),*
1675 )?]
1676 [$( $( $lifetime ,)* $( $generics ),* )?]
1677 [$(where $( $where_clause_ty
1678 $(: $where_clause_bound)?
1679 $(: ?$where_clause_unsized_bound)?
1680 $(: $where_clause_lifetime_bound)?
1681 ),* )?]
1682 {
1683 $($body_data)*
1684 }
1685 $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?
1686 }
1687 };
1688}
1689
1690// Not public API.
1691#[doc(hidden)]
1692#[allow(missing_debug_implementations)]
1693pub mod __private {
1694 use core::mem::ManuallyDrop;
1695 #[doc(hidden)]
1696 pub use core::{
1697 marker::{PhantomData, PhantomPinned, Unpin},
1698 ops::Drop,
1699 pin::Pin,
1700 ptr,
1701 };
1702
1703 // Workaround for issue on unstable negative_impls feature that allows unsound overlapping Unpin
1704 // implementations and rustc bug that leaks unstable negative_impls into stable.
1705 // See https://github.com/taiki-e/pin-project/issues/340#issuecomment-2432146009 for details.
1706 #[doc(hidden)]
1707 pub type PinnedFieldsOf<T> =
1708 <PinnedFieldsOfHelperStruct<T> as PinnedFieldsOfHelperTrait>::Actual;
1709 // We cannot use <Option<T> as IntoIterator>::Item or similar since we should allow ?Sized in T.
1710 #[doc(hidden)]
1711 pub trait PinnedFieldsOfHelperTrait {
1712 type Actual: ?Sized;
1713 }
1714 #[doc(hidden)]
1715 pub struct PinnedFieldsOfHelperStruct<T: ?Sized>(T);
1716 impl<T: ?Sized> PinnedFieldsOfHelperTrait for PinnedFieldsOfHelperStruct<T> {
1717 type Actual = T;
1718 }
1719
1720 // This is an internal helper struct used by `pin_project!`.
1721 #[doc(hidden)]
1722 pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);
1723 impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
1724
1725 // This is an internal helper used to ensure a value is dropped.
1726 #[doc(hidden)]
1727 pub struct UnsafeDropInPlaceGuard<T: ?Sized>(*mut T);
1728 impl<T: ?Sized> UnsafeDropInPlaceGuard<T> {
1729 #[doc(hidden)]
1730 pub unsafe fn new(ptr: *mut T) -> Self {
1731 Self(ptr)
1732 }
1733 }
1734 impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
1735 fn drop(&mut self) {
1736 // SAFETY: the caller of `UnsafeDropInPlaceGuard::new` must guarantee
1737 // that `ptr` is valid for drop when this guard is destructed.
1738 unsafe {
1739 ptr::drop_in_place(self.0);
1740 }
1741 }
1742 }
1743
1744 // This is an internal helper used to ensure a value is overwritten without
1745 // its destructor being called.
1746 #[doc(hidden)]
1747 pub struct UnsafeOverwriteGuard<T> {
1748 target: *mut T,
1749 value: ManuallyDrop<T>,
1750 }
1751 impl<T> UnsafeOverwriteGuard<T> {
1752 #[doc(hidden)]
1753 pub unsafe fn new(target: *mut T, value: T) -> Self {
1754 Self { target, value: ManuallyDrop::new(value) }
1755 }
1756 }
1757 impl<T> Drop for UnsafeOverwriteGuard<T> {
1758 fn drop(&mut self) {
1759 // SAFETY: the caller of `UnsafeOverwriteGuard::new` must guarantee
1760 // that `target` is valid for writes when this guard is destructed.
1761 unsafe {
1762 ptr::write(self.target, ptr::read(&*self.value));
1763 }
1764 }
1765 }
1766}