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