aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs.orig
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs.orig')
-rw-r--r--src/lib.rs.orig1737
1 files changed, 1737 insertions, 0 deletions
diff --git a/src/lib.rs.orig b/src/lib.rs.orig
new file mode 100644
index 0000000..ff1e3bf
--- /dev/null
+++ b/src/lib.rs.orig
@@ -0,0 +1,1737 @@
+//! A lightweight version of [pin-project] written with declarative macros.
+//!
+//! # Examples
+//!
+//! [`pin_project!`] macro creates a projection type covering all the fields of struct.
+//!
+//! ```rust
+//! use pin_project_lite::pin_project;
+//! use std::pin::Pin;
+//!
+//! pin_project! {
+//! struct Struct<T, U> {
+//! #[pin]
+//! pinned: T,
+//! unpinned: U,
+//! }
+//! }
+//!
+//! impl<T, U> Struct<T, U> {
+//! fn method(self: Pin<&mut Self>) {
+//! let this = self.project();
+//! let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
+//! let _: &mut U = this.unpinned; // Normal reference to the field
+//! }
+//! }
+//! ```
+//!
+//! To use [`pin_project!`] on enums, you need to name the projection type
+//! returned from the method.
+//!
+//! ```rust
+//! use pin_project_lite::pin_project;
+//! use std::pin::Pin;
+//!
+//! pin_project! {
+//! #[project = EnumProj]
+//! enum Enum<T, U> {
+//! Variant { #[pin] pinned: T, unpinned: U },
+//! }
+//! }
+//!
+//! impl<T, U> Enum<T, U> {
+//! fn method(self: Pin<&mut Self>) {
+//! match self.project() {
+//! EnumProj::Variant { pinned, unpinned } => {
+//! let _: Pin<&mut T> = pinned;
+//! let _: &mut U = unpinned;
+//! }
+//! }
+//! }
+//! }
+//! ```
+//!
+//! # [pin-project] vs pin-project-lite
+//!
+//! Here are some similarities and differences compared to [pin-project].
+//!
+//! ## Similar: Safety
+//!
+//! pin-project-lite guarantees safety in much the same way as [pin-project].
+//! Both are completely safe unless you write other unsafe code.
+//!
+//! ## Different: Minimal design
+//!
+//! This library does not tackle as expansive of a range of use cases as
+//! [pin-project] does. If your use case is not already covered, please use
+//! [pin-project].
+//!
+//! ## Different: No proc-macro related dependencies
+//!
+//! This is the **only** reason to use this crate. However, **if you already
+//! have proc-macro related dependencies in your crate's dependency graph, there
+//! is no benefit from using this crate.** (Note: There is almost no difference
+//! in the amount of code generated between [pin-project] and pin-project-lite.)
+//!
+//! ## Different: No useful error messages
+//!
+//! This macro does not handle any invalid input. So error messages are not to
+//! be useful in most cases. If you do need useful error messages, then upon
+//! error you can pass the same input to [pin-project] to receive a helpful
+//! description of the compile error.
+//!
+//! ## Different: No support for custom Drop implementation
+//!
+//! pin-project supports this by [`#[pinned_drop]`][pinned-drop].
+//!
+//! ## Different: No support for custom Unpin implementation
+//!
+//! pin-project supports this by [`UnsafeUnpin`][unsafe-unpin] and [`!Unpin`][not-unpin].
+//!
+//! ## Different: No support for tuple structs and tuple variants
+//!
+//! pin-project supports this.
+//!
+//! [not-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unpin
+//! [pin-project]: https://github.com/taiki-e/pin-project
+//! [pinned-drop]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#pinned_drop
+//! [unsafe-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unsafeunpin
+
+#![no_std]
+#![doc(test(
+ no_crate_inject,
+ attr(
+ deny(warnings, rust_2018_idioms, single_use_lifetimes),
+ allow(dead_code, unused_variables)
+ )
+))]
+#![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
+#![warn(clippy::all, clippy::default_trait_access)]
+
+/// A macro that creates a projection type covering all the fields of struct.
+///
+/// This macro creates a projection type according to the following rules:
+///
+/// * For the field that uses `#[pin]` attribute, makes the pinned reference to the field.
+/// * For the other fields, makes the unpinned reference to the field.
+///
+/// And the following methods are implemented on the original type:
+///
+/// ```rust
+/// # use std::pin::Pin;
+/// # type Projection<'a> = &'a ();
+/// # type ProjectionRef<'a> = &'a ();
+/// # trait Dox {
+/// fn project(self: Pin<&mut Self>) -> Projection<'_>;
+/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;
+/// # }
+/// ```
+///
+/// By passing an attribute with the same name as the method to the macro,
+/// you can name the projection type returned from the method. This allows you
+/// to use pattern matching on the projected types.
+///
+/// ```rust
+/// # use pin_project_lite::pin_project;
+/// # use std::pin::Pin;
+/// pin_project! {
+/// #[project = EnumProj]
+/// enum Enum<T> {
+/// Variant { #[pin] field: T },
+/// }
+/// }
+///
+/// impl<T> Enum<T> {
+/// fn method(self: Pin<&mut Self>) {
+/// let this: EnumProj<'_, T> = self.project();
+/// match this {
+/// EnumProj::Variant { field } => {
+/// let _: Pin<&mut T> = field;
+/// }
+/// }
+/// }
+/// }
+/// ```
+///
+/// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional
+/// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving
+/// out all unpinned fields in `Self`.
+///
+/// ```rust
+/// # use std::pin::Pin;
+/// # type MyProjReplace = ();
+/// # trait Dox {
+/// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace;
+/// # }
+/// ```
+///
+/// The `#[project]` (and `#[project_ref]`) attribute must precede the other
+/// attributes except for `#[doc]`. For example, the following code will not be compiled:
+///
+/// ```rust,compile_fail
+/// # use pin_project_lite::pin_project;
+/// # use std::pin::Pin;
+/// pin_project! {
+/// /// documents (`#[doc]`) can be placed before `#[project]`.
+/// #[derive(Clone)] // <--- ERROR
+/// #[project = EnumProj]
+/// #[derive(Debug)] // <--- Ok
+/// enum Enum<T> {
+/// Variant { #[pin] field: T },
+/// }
+/// }
+/// ```
+///
+/// Also, note that the projection types returned by `project` and `project_ref` have
+/// an additional lifetime at the beginning of generics.
+///
+/// ```text
+/// let this: EnumProj<'_, T> = self.project();
+/// ^^
+/// ```
+///
+/// The visibility of the projected types and projection methods is based on the
+/// original type. However, if the visibility of the original type is `pub`, the
+/// visibility of the projected types and the projection methods is downgraded
+/// to `pub(crate)`.
+///
+/// # Safety
+///
+/// `pin_project!` macro guarantees safety in much the same way as [pin-project] crate.
+/// Both are completely safe unless you write other unsafe code.
+///
+/// See [pin-project] crate for more details.
+///
+/// # Examples
+///
+/// ```rust
+/// use pin_project_lite::pin_project;
+/// use std::pin::Pin;
+///
+/// pin_project! {
+/// struct Struct<T, U> {
+/// #[pin]
+/// pinned: T,
+/// unpinned: U,
+/// }
+/// }
+///
+/// impl<T, U> Struct<T, U> {
+/// fn method(self: Pin<&mut Self>) {
+/// let this = self.project();
+/// let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
+/// let _: &mut U = this.unpinned; // Normal reference to the field
+/// }
+/// }
+/// ```
+///
+/// To use `pin_project!` on enums, you need to name the projection type
+/// returned from the method.
+///
+/// ```rust
+/// use pin_project_lite::pin_project;
+/// use std::pin::Pin;
+///
+/// pin_project! {
+/// #[project = EnumProj]
+/// enum Enum<T> {
+/// Struct {
+/// #[pin]
+/// field: T,
+/// },
+/// Unit,
+/// }
+/// }
+///
+/// impl<T> Enum<T> {
+/// fn method(self: Pin<&mut Self>) {
+/// match self.project() {
+/// EnumProj::Struct { field } => {
+/// let _: Pin<&mut T> = field;
+/// }
+/// EnumProj::Unit => {}
+/// }
+/// }
+/// }
+/// ```
+///
+/// If you want to call the `project()` method multiple times or later use the
+/// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid
+/// consuming the [`Pin`].
+///
+/// ```rust
+/// use pin_project_lite::pin_project;
+/// use std::pin::Pin;
+///
+/// pin_project! {
+/// struct Struct<T> {
+/// #[pin]
+/// field: T,
+/// }
+/// }
+///
+/// impl<T> Struct<T> {
+/// fn call_project_twice(mut self: Pin<&mut Self>) {
+/// // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.
+/// self.as_mut().project();
+/// self.as_mut().project();
+/// }
+/// }
+/// ```
+///
+/// # `!Unpin`
+///
+/// If you want to ensure that [`Unpin`] is not implemented, use `#[pin]`
+/// attribute for a [`PhantomPinned`] field.
+///
+/// ```rust
+/// use pin_project_lite::pin_project;
+/// use std::marker::PhantomPinned;
+///
+/// pin_project! {
+/// struct Struct<T> {
+/// field: T,
+/// #[pin] // <------ This `#[pin]` is required to make `Struct` to `!Unpin`.
+/// _pin: PhantomPinned,
+/// }
+/// }
+/// ```
+///
+/// Note that using [`PhantomPinned`] without `#[pin]` attribute has no effect.
+///
+/// [`PhantomPinned`]: core::marker::PhantomPinned
+/// [`Pin::as_mut`]: core::pin::Pin::as_mut
+/// [`Pin`]: core::pin::Pin
+/// [pin-project]: https://github.com/taiki-e/pin-project
+#[macro_export]
+macro_rules! pin_project {
+ // Parses options
+ (
+ $(#[doc $($doc:tt)*])*
+ #[project = $proj_mut_ident:ident]
+ #[project_ref = $proj_ref_ident:ident]
+ #[project_replace = $proj_replace_ident:ident]
+ $($tt:tt)*
+ ) => {
+ $crate::__pin_project_internal! {
+ [$proj_mut_ident][$proj_ref_ident][$proj_replace_ident]
+ $(#[doc $($doc)*])*
+ $($tt)*
+ }
+ };
+ (
+ $(#[doc $($doc:tt)*])*
+ #[project = $proj_mut_ident:ident]
+ #[project_ref = $proj_ref_ident:ident]
+ $($tt:tt)*
+ ) => {
+ $crate::__pin_project_internal! {
+ [$proj_mut_ident][$proj_ref_ident][]
+ $(#[doc $($doc)*])*
+ $($tt)*
+ }
+ };
+ (
+ $(#[doc $($doc:tt)*])*
+ #[project = $proj_mut_ident:ident]
+ #[project_replace = $proj_replace_ident:ident]
+ $($tt:tt)*
+ ) => {
+ $crate::__pin_project_internal! {
+ [$proj_mut_ident][][$proj_replace_ident]
+ $(#[doc $($doc)*])*
+ $($tt)*
+ }
+ };
+ (
+ $(#[doc $($doc:tt)*])*
+ #[project_ref = $proj_ref_ident:ident]
+ #[project_replace = $proj_replace_ident:ident]
+ $($tt:tt)*
+ ) => {
+ $crate::__pin_project_internal! {
+ [][$proj_ref_ident][$proj_replace_ident]
+ $(#[doc $($doc)*])*
+ $($tt)*
+ }
+ };
+ (
+ $(#[doc $($doc:tt)*])*
+ #[project = $proj_mut_ident:ident]
+ $($tt:tt)*
+ ) => {
+ $crate::__pin_project_internal! {
+ [$proj_mut_ident][][]
+ $(#[doc $($doc)*])*
+ $($tt)*
+ }
+ };
+ (
+ $(#[doc $($doc:tt)*])*
+ #[project_ref = $proj_ref_ident:ident]
+ $($tt:tt)*
+ ) => {
+ $crate::__pin_project_internal! {
+ [][$proj_ref_ident][]
+ $(#[doc $($doc)*])*
+ $($tt)*
+ }
+ };
+ (
+ $(#[doc $($doc:tt)*])*
+ #[project_replace = $proj_replace_ident:ident]
+ $($tt:tt)*
+ ) => {
+ $crate::__pin_project_internal! {
+ [][][$proj_replace_ident]
+ $(#[doc $($doc)*])*
+ $($tt)*
+ }
+ };
+ (
+ $($tt:tt)*
+ ) => {
+ $crate::__pin_project_internal! {
+ [][][]
+ $($tt)*
+ }
+ };
+}
+
+// limitations:
+// * no support for tuple structs and tuple variant (wontfix).
+// * no support for multiple trait/lifetime bounds.
+// * no support for `Self` in where clauses. (wontfix)
+// * no support for overlapping lifetime names. (wontfix)
+// * no interoperability with other field attributes.
+// * no useful error messages. (wontfix)
+// etc...
+
+// Not public API.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_internal {
+ // =============================================================================================
+ // struct:main
+ (@struct=>internal;
+ [$($proj_mut_ident:ident)?]
+ [$($proj_ref_ident:ident)?]
+ [$($proj_replace_ident:ident)?]
+ [$proj_vis:vis]
+ [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
+ [$($def_generics:tt)*]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+
+ }
+ ) => {
+ $(#[$attrs])*
+ $vis struct $ident $($def_generics)*
+ $(where
+ $($where_clause)*)?
+ {
+ $(
+ $field_vis $field: $field_ty
+ ),+
+ }
+
+ $crate::__pin_project_internal! { @struct=>make_proj_ty=>named;
+ [$proj_vis]
+ [$($proj_mut_ident)?]
+ [make_proj_field_mut]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @struct=>make_proj_ty=>named;
+ [$proj_vis]
+ [$($proj_ref_ident)?]
+ [make_proj_field_ref]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @struct=>make_proj_replace_ty=>named;
+ [$proj_vis]
+ [$($proj_replace_ident)?]
+ [make_proj_field_replace]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+
+ #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
+ #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+ // This lint warns of `clippy::*` generated by external macros.
+ // We allow this lint for compatibility with older compilers.
+ #[allow(clippy::unknown_clippy_lints)]
+ #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+ #[allow(clippy::used_underscore_binding)]
+ const _: () = {
+ $crate::__pin_project_internal! { @struct=>make_proj_ty=>unnamed;
+ [$proj_vis]
+ [$($proj_mut_ident)?][Projection]
+ [make_proj_field_mut]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @struct=>make_proj_ty=>unnamed;
+ [$proj_vis]
+ [$($proj_ref_ident)?][ProjectionRef]
+ [make_proj_field_ref]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @struct=>make_proj_replace_ty=>unnamed;
+ [$proj_vis]
+ [$($proj_replace_ident)?][ProjectionReplace]
+ [make_proj_field_replace]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+
+ impl <$($impl_generics)*> $ident <$($ty_generics)*>
+ $(where
+ $($where_clause)*)?
+ {
+ $crate::__pin_project_internal! { @struct=>make_proj_method;
+ [$proj_vis]
+ [$($proj_mut_ident)?][Projection]
+ [project get_unchecked_mut mut]
+ [$($ty_generics)*]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @struct=>make_proj_method;
+ [$proj_vis]
+ [$($proj_ref_ident)?][ProjectionRef]
+ [project_ref get_ref]
+ [$($ty_generics)*]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @struct=>make_proj_replace_method;
+ [$proj_vis]
+ [$($proj_replace_ident)?][ProjectionReplace]
+ [$($ty_generics)*]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field
+ ),+
+ }
+ }
+ }
+
+ $crate::__pin_project_internal! { @make_unpin_impl;
+ [$vis $ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ $(
+ $field: $crate::__pin_project_internal!(@make_unpin_bound;
+ $(#[$pin])? $field_ty
+ )
+ ),+
+ }
+
+ $crate::__pin_project_internal! { @make_drop_impl;
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ }
+
+ // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+ //
+ // Taking a reference to a packed field is unsafe, amd appplying
+ // #[forbid(safe_packed_borrows)] makes sure that doing this without
+ // an 'unsafe' block (which we deliberately do not generate)
+ // is a hard error.
+ //
+ // If the struct ends up having #[repr(packed)] applied somehow,
+ // this will generate an (unfriendly) error message. Under all reasonable
+ // circumstances, we'll detect the #[repr(packed)] attribute, and generate
+ // a much nicer error above.
+ //
+ // See https://github.com/taiki-e/pin-project/pull/34 for more details.
+ #[forbid(safe_packed_borrows)]
+ fn __assert_not_repr_packed <$($impl_generics)*> (this: &$ident <$($ty_generics)*>)
+ $(where
+ $($where_clause)*)?
+ {
+ $(
+ let _ = &this.$field;
+ )+
+ }
+ };
+ };
+ // =============================================================================================
+ // enum:main
+ (@enum=>internal;
+ [$($proj_mut_ident:ident)?]
+ [$($proj_ref_ident:ident)?]
+ [$($proj_replace_ident:ident)?]
+ [$proj_vis:vis]
+ [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
+ [$($def_generics:tt)*]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+ {
+ $(
+ $(#[$variant_attrs:meta])*
+ $variant:ident $({
+ $(
+ $(#[$pin:ident])?
+ $field:ident: $field_ty:ty
+ ),+
+ })?
+ ),+
+ }
+ ) => {
+ $(#[$attrs])*
+ $vis enum $ident $($def_generics)*
+ $(where
+ $($where_clause)*)?
+ {
+ $(
+ $(#[$variant_attrs])*
+ $variant $({
+ $(
+ $field: $field_ty
+ ),+
+ })?
+ ),+
+ }
+
+ $crate::__pin_project_internal! { @enum=>make_proj_ty;
+ [$proj_vis]
+ [$($proj_mut_ident)?]
+ [make_proj_field_mut]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $variant $({
+ $(
+ $(#[$pin])?
+ $field: $field_ty
+ ),+
+ })?
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @enum=>make_proj_ty;
+ [$proj_vis]
+ [$($proj_ref_ident)?]
+ [make_proj_field_ref]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $variant $({
+ $(
+ $(#[$pin])?
+ $field: $field_ty
+ ),+
+ })?
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @enum=>make_proj_replace_ty;
+ [$proj_vis]
+ [$($proj_replace_ident)?]
+ [make_proj_field_replace]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ {
+ $(
+ $variant $({
+ $(
+ $(#[$pin])?
+ $field: $field_ty
+ ),+
+ })?
+ ),+
+ }
+ }
+
+ #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+ // This lint warns of `clippy::*` generated by external macros.
+ // We allow this lint for compatibility with older compilers.
+ #[allow(clippy::unknown_clippy_lints)]
+ #[allow(clippy::used_underscore_binding)]
+ const _: () = {
+ impl <$($impl_generics)*> $ident <$($ty_generics)*>
+ $(where
+ $($where_clause)*)?
+ {
+ $crate::__pin_project_internal! { @enum=>make_proj_method;
+ [$proj_vis]
+ [$($proj_mut_ident)?]
+ [project get_unchecked_mut mut]
+ [$($ty_generics)*]
+ {
+ $(
+ $variant $({
+ $(
+ $(#[$pin])?
+ $field
+ ),+
+ })?
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @enum=>make_proj_method;
+ [$proj_vis]
+ [$($proj_ref_ident)?]
+ [project_ref get_ref]
+ [$($ty_generics)*]
+ {
+ $(
+ $variant $({
+ $(
+ $(#[$pin])?
+ $field
+ ),+
+ })?
+ ),+
+ }
+ }
+ $crate::__pin_project_internal! { @enum=>make_proj_replace_method;
+ [$proj_vis]
+ [$($proj_replace_ident)?]
+ [$($ty_generics)*]
+ {
+ $(
+ $variant $({
+ $(
+ $(#[$pin])?
+ $field
+ ),+
+ })?
+ ),+
+ }
+ }
+ }
+
+ $crate::__pin_project_internal! { @make_unpin_impl;
+ [$vis $ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ $(
+ $variant: ($(
+ $(
+ $crate::__pin_project_internal!(@make_unpin_bound;
+ $(#[$pin])? $field_ty
+ )
+ ),+
+ )?)
+ ),+
+ }
+
+ $crate::__pin_project_internal! { @make_drop_impl;
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ }
+
+ // We don't need to check for '#[repr(packed)]',
+ // since it does not apply to enums.
+ };
+ };
+
+ // =============================================================================================
+ // struct:make_proj_ty
+ (@struct=>make_proj_ty=>unnamed;
+ [$proj_vis:vis]
+ [$_proj_ty_ident:ident][$proj_ty_ident:ident]
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($field:tt)*
+ ) => {};
+ (@struct=>make_proj_ty=>unnamed;
+ [$proj_vis:vis]
+ [][$proj_ty_ident:ident]
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($field:tt)*
+ ) => {
+ $crate::__pin_project_internal! { @struct=>make_proj_ty=>named;
+ [$proj_vis]
+ [$proj_ty_ident]
+ [$make_proj_field]
+ [$ident]
+ [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+ $($field)*
+ }
+ };
+ (@struct=>make_proj_ty=>named;
+ [$proj_vis:vis]
+ [$proj_ty_ident:ident]
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+
+ }
+ ) => {
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+ // This lint warns of `clippy::*` generated by external macros.
+ // We allow this lint for compatibility with older compilers.
+ #[allow(clippy::unknown_clippy_lints)]
+ #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+ #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+ #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
+ #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+ $proj_vis struct $proj_ty_ident <'__pin, $($impl_generics)*>
+ where
+ $ident <$($ty_generics)*>: '__pin
+ $(, $($where_clause)*)?
+ {
+ $(
+ $field_vis $field: $crate::__pin_project_internal!(@$make_proj_field;
+ $(#[$pin])? $field_ty
+ )
+ ),+
+ }
+ };
+ (@struct=>make_proj_ty=>named;
+ [$proj_vis:vis]
+ []
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($field:tt)*
+ ) => {};
+
+ (@struct=>make_proj_replace_ty=>unnamed;
+ [$proj_vis:vis]
+ [$_proj_ty_ident:ident][$proj_ty_ident:ident]
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($field:tt)*
+ ) => {};
+ (@struct=>make_proj_replace_ty=>unnamed;
+ [$proj_vis:vis]
+ [][$proj_ty_ident:ident]
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($field:tt)*
+ ) => {
+ };
+ (@struct=>make_proj_replace_ty=>named;
+ [$proj_vis:vis]
+ [$proj_ty_ident:ident]
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+
+ }
+ ) => {
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+ #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+ #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+ #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+ $proj_vis struct $proj_ty_ident <$($impl_generics)*>
+ where
+ $($($where_clause)*)?
+ {
+ $(
+ $field_vis $field: $crate::__pin_project_internal!(@$make_proj_field;
+ $(#[$pin])? $field_ty
+ )
+ ),+
+ }
+ };
+ (@struct=>make_proj_replace_ty=>named;
+ [$proj_vis:vis]
+ []
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($field:tt)*
+ ) => {};
+ // =============================================================================================
+ // enum:make_proj_ty
+ (@enum=>make_proj_ty;
+ [$proj_vis:vis]
+ [$proj_ty_ident:ident]
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ {
+ $(
+ $variant:ident $({
+ $(
+ $(#[$pin:ident])?
+ $field:ident: $field_ty:ty
+ ),+
+ })?
+ ),+
+ }
+ ) => {
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+ // This lint warns of `clippy::*` generated by external macros.
+ // We allow this lint for compatibility with older compilers.
+ #[allow(clippy::unknown_clippy_lints)]
+ #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+ #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+ #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
+ #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+ $proj_vis enum $proj_ty_ident <'__pin, $($impl_generics)*>
+ where
+ $ident <$($ty_generics)*>: '__pin
+ $(, $($where_clause)*)?
+ {
+ $(
+ $variant $({
+ $(
+ $field: $crate::__pin_project_internal!(@$make_proj_field;
+ $(#[$pin])? $field_ty
+ )
+ ),+
+ })?
+ ),+
+ }
+ };
+ (@enum=>make_proj_ty;
+ [$proj_vis:vis]
+ []
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($variant:tt)*
+ ) => {};
+
+ (@enum=>make_proj_replace_ty;
+ [$proj_vis:vis]
+ [$proj_ty_ident:ident]
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ {
+ $(
+ $variant:ident $({
+ $(
+ $(#[$pin:ident])?
+ $field:ident: $field_ty:ty
+ ),+
+ })?
+ ),+
+ }
+ ) => {
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+ #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+ #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+ #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+ $proj_vis enum $proj_ty_ident <$($impl_generics)*>
+ where
+ $($($where_clause)*)?
+ {
+ $(
+ $variant $({
+ $(
+ $field: $crate::__pin_project_internal!(@$make_proj_field;
+ $(#[$pin])? $field_ty
+ )
+ ),+
+ })?
+ ),+
+ }
+ };
+ (@enum=>make_proj_replace_ty;
+ [$proj_vis:vis]
+ []
+ [$make_proj_field:ident]
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($variant:tt)*
+ ) => {};
+
+ // =============================================================================================
+ (@make_proj_replace_block;
+ [$($proj_path: tt)+]
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident
+ ),+
+ }
+ ) => {
+ let result = $($proj_path)* {
+ $(
+ $field: $crate::__pin_project_internal!(@make_replace_field_proj;
+ $(#[$pin])? $field
+ )
+ ),+
+ };
+
+ {
+ ( $(
+ $crate::__pin_project_internal!(@make_unsafe_drop_in_place_guard;
+ $(#[$pin])? $field
+ ),
+ )* );
+ }
+
+ result
+ };
+ (@make_proj_replace_block;
+ [$($proj_path: tt)+]
+ ) => {
+ $($proj_path)*
+ };
+
+ // =============================================================================================
+ // struct:make_proj_method
+ (@struct=>make_proj_method;
+ [$proj_vis:vis]
+ [$proj_ty_ident:ident][$_proj_ty_ident:ident]
+ [$method_ident:ident $get_method:ident $($mut:ident)?]
+ [$($ty_generics:tt)*]
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident
+ ),+
+ }
+ ) => {
+ $proj_vis fn $method_ident<'__pin>(
+ self: $crate::__private::Pin<&'__pin $($mut)? Self>,
+ ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
+ unsafe {
+ let Self { $($field),* } = self.$get_method();
+ $proj_ty_ident {
+ $(
+ $field: $crate::__pin_project_internal!(@make_unsafe_field_proj;
+ $(#[$pin])? $field
+ )
+ ),+
+ }
+ }
+ }
+ };
+ (@struct=>make_proj_method;
+ [$proj_vis:vis]
+ [][$proj_ty_ident:ident]
+ [$method_ident:ident $get_method:ident $($mut:ident)?]
+ [$($ty_generics:tt)*]
+ $($variant:tt)*
+ ) => {
+ $crate::__pin_project_internal! { @struct=>make_proj_method;
+ [$proj_vis]
+ [$proj_ty_ident][$proj_ty_ident]
+ [$method_ident $get_method $($mut)?]
+ [$($ty_generics)*]
+ $($variant)*
+ }
+ };
+
+ (@struct=>make_proj_replace_method;
+ [$proj_vis:vis]
+ [$proj_ty_ident:ident][$_proj_ty_ident:ident]
+ [$($ty_generics:tt)*]
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident
+ ),+
+ }
+ ) => {
+ $proj_vis fn project_replace(
+ self: $crate::__private::Pin<&mut Self>,
+ replacement: Self,
+ ) -> $proj_ty_ident <$($ty_generics)*> {
+ unsafe {
+ let __self_ptr: *mut Self = self.get_unchecked_mut();
+
+ // Destructors will run in reverse order, so next create a guard to overwrite
+ // `self` with the replacement value without calling destructors.
+ let __guard = $crate::__private::UnsafeOverwriteGuard {
+ target: __self_ptr,
+ value: $crate::__private::ManuallyDrop::new(replacement),
+ };
+
+ let Self { $($field),* } = &mut *__self_ptr;
+
+ $crate::__pin_project_internal!{@make_proj_replace_block;
+ [$proj_ty_ident]
+ {
+ $(
+ $(#[$pin])?
+ $field
+ ),+
+ }
+ }
+ }
+ }
+ };
+ (@struct=>make_proj_replace_method;
+ [$proj_vis:vis]
+ [][$proj_ty_ident:ident]
+ [$($ty_generics:tt)*]
+ $($variant:tt)*
+ ) => {
+ };
+
+ // =============================================================================================
+ // enum:make_proj_method
+ (@enum=>make_proj_method;
+ [$proj_vis:vis]
+ [$proj_ty_ident:ident]
+ [$method_ident:ident $get_method:ident $($mut:ident)?]
+ [$($ty_generics:tt)*]
+ {
+ $(
+ $variant:ident $({
+ $(
+ $(#[$pin:ident])?
+ $field:ident
+ ),+
+ })?
+ ),+
+ }
+ ) => {
+ $proj_vis fn $method_ident<'__pin>(
+ self: $crate::__private::Pin<&'__pin $($mut)? Self>,
+ ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
+ unsafe {
+ match self.$get_method() {
+ $(
+ Self::$variant $({
+ $($field),+
+ })? => {
+ $proj_ty_ident::$variant $({
+ $(
+ $field: $crate::__pin_project_internal!(
+ @make_unsafe_field_proj;
+ $(#[$pin])? $field
+ )
+ ),+
+ })?
+ }
+ ),+
+ }
+ }
+ }
+ };
+ (@enum=>make_proj_method;
+ [$proj_vis:vis]
+ []
+ [$method_ident:ident $get_method:ident $($mut:ident)?]
+ [$($ty_generics:tt)*]
+ $($variant:tt)*
+ ) => {};
+
+ (@enum=>make_proj_replace_method;
+ [$proj_vis:vis]
+ [$proj_ty_ident:ident]
+ [$($ty_generics:tt)*]
+ {
+ $(
+ $variant:ident $({
+ $(
+ $(#[$pin:ident])?
+ $field:ident
+ ),+
+ })?
+ ),+
+ }
+ ) => {
+ $proj_vis fn project_replace(
+ self: $crate::__private::Pin<&mut Self>,
+ replacement: Self,
+ ) -> $proj_ty_ident <$($ty_generics)*> {
+ unsafe {
+ let __self_ptr: *mut Self = self.get_unchecked_mut();
+
+ // Destructors will run in reverse order, so next create a guard to overwrite
+ // `self` with the replacement value without calling destructors.
+ let __guard = $crate::__private::UnsafeOverwriteGuard {
+ target: __self_ptr,
+ value: $crate::__private::ManuallyDrop::new(replacement),
+ };
+
+ match &mut *__self_ptr {
+ $(
+ Self::$variant $({
+ $($field),+
+ })? => {
+ $crate::__pin_project_internal!{@make_proj_replace_block;
+ [$proj_ty_ident :: $variant]
+ $({
+ $(
+ $(#[$pin])?
+ $field
+ ),+
+ })?
+ }
+ }
+ ),+
+ }
+ }
+ }
+ };
+ (@enum=>make_proj_replace_method;
+ [$proj_vis:vis]
+ []
+ [$($ty_generics:tt)*]
+ $($variant:tt)*
+ ) => {};
+
+ // =============================================================================================
+ // make_unpin_impl
+ (@make_unpin_impl;
+ [$vis:vis $ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ $($field:tt)*
+ ) => {
+ // Automatically create the appropriate conditional `Unpin` implementation.
+ //
+ // Basically this is equivalent to the following code:
+ // ```rust
+ // impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
+ // ```
+ //
+ // However, if struct is public and there is a private type field,
+ // this would cause an E0446 (private type in public interface).
+ //
+ // When RFC 2145 is implemented (rust-lang/rust#48054),
+ // this will become a lint, rather then a hard error.
+ //
+ // As a workaround for this, we generate a new struct, containing all of the pinned
+ // fields from our #[pin_project] type. This struct is delcared within
+ // a function, which makes it impossible to be named by user code.
+ // This guarnatees that it will use the default auto-trait impl for Unpin -
+ // that is, it will implement Unpin iff all of its fields implement Unpin.
+ // This type can be safely declared as 'public', satisfiying the privacy
+ // checker without actually allowing user code to access it.
+ //
+ // This allows users to apply the #[pin_project] attribute to types
+ // regardless of the privacy of the types of their fields.
+ //
+ // See also https://github.com/taiki-e/pin-project/pull/53.
+ #[allow(non_snake_case)]
+ $vis struct __Origin <'__pin, $($impl_generics)*>
+ $(where
+ $($where_clause)*)?
+ {
+ __dummy_lifetime: $crate::__private::PhantomData<&'__pin ()>,
+ $($field)*
+ }
+ impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>
+ where
+ __Origin <'__pin, $($ty_generics)*>: $crate::__private::Unpin
+ $(, $($where_clause)*)?
+ {
+ }
+ };
+
+ // =============================================================================================
+ // make_drop_impl
+ (@make_drop_impl;
+ [$ident:ident]
+ [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+ ) => {
+ // Ensure that struct does not implement `Drop`.
+ //
+ // There are two possible cases:
+ // 1. The user type does not implement Drop. In this case,
+ // the first blanked impl will not apply to it. This code
+ // will compile, as there is only one impl of MustNotImplDrop for the user type
+ // 2. The user type does impl Drop. This will make the blanket impl applicable,
+ // which will then comflict with the explicit MustNotImplDrop impl below.
+ // This will result in a compilation error, which is exactly what we want.
+ trait MustNotImplDrop {}
+ #[allow(clippy::drop_bounds, drop_bounds)]
+ impl<T: $crate::__private::Drop> MustNotImplDrop for T {}
+ impl <$($impl_generics)*> MustNotImplDrop for $ident <$($ty_generics)*>
+ $(where
+ $($where_clause)*)?
+ {
+ }
+ };
+
+ // =============================================================================================
+ // make_unpin_bound
+ (@make_unpin_bound;
+ #[pin]
+ $field_ty:ty
+ ) => {
+ $field_ty
+ };
+ (@make_unpin_bound;
+ $field_ty:ty
+ ) => {
+ $crate::__private::AlwaysUnpin<$field_ty>
+ };
+
+ // =============================================================================================
+ // make_unsafe_field_proj
+ (@make_unsafe_field_proj;
+ #[pin]
+ $field:ident
+ ) => {
+ $crate::__private::Pin::new_unchecked($field)
+ };
+ (@make_unsafe_field_proj;
+ $field:ident
+ ) => {
+ $field
+ };
+
+ // =============================================================================================
+ // make_replace_field_proj
+ (@make_replace_field_proj;
+ #[pin]
+ $field:ident
+ ) => {
+ $crate::__private::PhantomData
+ };
+ (@make_replace_field_proj;
+ $field:ident
+ ) => {
+ $crate::__private::ptr::read($field)
+ };
+
+
+ // =============================================================================================
+ // make_unsafe_drop_in_place_guard
+ (@make_unsafe_drop_in_place_guard;
+ #[pin]
+ $field:ident
+ ) => {
+ $crate::__private::UnsafeDropInPlaceGuard($field)
+ };
+ (@make_unsafe_drop_in_place_guard;
+ $field:ident
+ ) => {
+ ()
+ };
+
+ // =============================================================================================
+ // make_proj_field
+ (@make_proj_field_mut;
+ #[pin]
+ $field_ty:ty
+ ) => {
+ $crate::__private::Pin<&'__pin mut ($field_ty)>
+ };
+ (@make_proj_field_mut;
+ $field_ty:ty
+ ) => {
+ &'__pin mut ($field_ty)
+ };
+ (@make_proj_field_ref;
+ #[pin]
+ $field_ty:ty
+ ) => {
+ $crate::__private::Pin<&'__pin ($field_ty)>
+ };
+ (@make_proj_field_ref;
+ $field_ty:ty
+ ) => {
+ &'__pin ($field_ty)
+ };
+
+ (@make_proj_field_replace;
+ #[pin]
+ $field_ty:ty
+ ) => {
+ $crate::__private::PhantomData<$field_ty>
+ };
+ (@make_proj_field_replace;
+ $field_ty:ty
+ ) => {
+ $field_ty
+ };
+
+ // =============================================================================================
+ // Parses input and determines visibility
+ // struct
+ (
+ [$($proj_mut_ident:ident)?]
+ [$($proj_ref_ident:ident)?]
+ [$($proj_replace_ident:ident)?]
+
+ $(#[$attrs:meta])*
+ pub struct $ident:ident $(<
+ $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
+ $( $generics:ident
+ $(: $generics_bound:path)?
+ $(: ?$generics_unsized_bound:path)?
+ $(: $generics_lifetime_bound:lifetime)?
+ $(= $generics_default:ty)?
+ ),* $(,)?
+ >)?
+ $(where
+ $( $where_clause_ty:ty
+ $(: $where_clause_bound:path)?
+ $(: ?$where_clause_unsized_bound:path)?
+ $(: $where_clause_lifetime_bound:lifetime)?
+ ),* $(,)?
+ )?
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+ $(,)?
+ }
+ ) => {
+ $crate::__pin_project_internal! { @struct=>internal;
+ [$($proj_mut_ident)?]
+ [$($proj_ref_ident)?]
+ [$($proj_replace_ident)?]
+ [pub(crate)]
+ [$(#[$attrs])* pub struct $ident]
+ [$(<
+ $( $lifetime $(: $lifetime_bound)? ,)*
+ $( $generics
+ $(: $generics_bound)?
+ $(: ?$generics_unsized_bound)?
+ $(: $generics_lifetime_bound)?
+ $(= $generics_default)?
+ ),*
+ >)?]
+ [$(
+ $( $lifetime $(: $lifetime_bound)? ,)*
+ $( $generics
+ $(: $generics_bound)?
+ $(: ?$generics_unsized_bound)?
+ $(: $generics_lifetime_bound)?
+ ),*
+ )?]
+ [$( $( $lifetime ,)* $( $generics ),* )?]
+ [$(where $( $where_clause_ty
+ $(: $where_clause_bound)?
+ $(: ?$where_clause_unsized_bound)?
+ $(: $where_clause_lifetime_bound)?
+ ),* )?]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+ };
+ (
+ [$($proj_mut_ident:ident)?]
+ [$($proj_ref_ident:ident)?]
+ [$($proj_replace_ident:ident)?]
+
+ $(#[$attrs:meta])*
+ $vis:vis struct $ident:ident $(<
+ $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
+ $( $generics:ident
+ $(: $generics_bound:path)?
+ $(: ?$generics_unsized_bound:path)?
+ $(: $generics_lifetime_bound:lifetime)?
+ $(= $generics_default:ty)?
+ ),* $(,)?
+ >)?
+ $(where
+ $( $where_clause_ty:ty
+ $(: $where_clause_bound:path)?
+ $(: ?$where_clause_unsized_bound:path)?
+ $(: $where_clause_lifetime_bound:lifetime)?
+ ),* $(,)?
+ )?
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+ $(,)?
+ }
+ ) => {
+ $crate::__pin_project_internal! { @struct=>internal;
+ [$($proj_mut_ident)?]
+ [$($proj_ref_ident)?]
+ [$($proj_replace_ident)?]
+ [$vis]
+ [$(#[$attrs])* $vis struct $ident]
+ [$(<
+ $( $lifetime $(: $lifetime_bound)? ,)*
+ $( $generics
+ $(: $generics_bound)?
+ $(: ?$generics_unsized_bound)?
+ $(: $generics_lifetime_bound)?
+ $(= $generics_default)?
+ ),*
+ >)?]
+ [$(
+ $( $lifetime $(: $lifetime_bound)? ,)*
+ $( $generics
+ $(: $generics_bound)?
+ $(: ?$generics_unsized_bound)?
+ $(: $generics_lifetime_bound)?
+ ),*
+ )?]
+ [$( $( $lifetime ,)* $( $generics ),* )?]
+ [$(where $( $where_clause_ty
+ $(: $where_clause_bound)?
+ $(: ?$where_clause_unsized_bound)?
+ $(: $where_clause_lifetime_bound)?
+ ),* )?]
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+ };
+ // enum
+ (
+ [$($proj_mut_ident:ident)?]
+ [$($proj_ref_ident:ident)?]
+ [$($proj_replace_ident:ident)?]
+
+ $(#[$attrs:meta])*
+ pub enum $ident:ident $(<
+ $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
+ $( $generics:ident
+ $(: $generics_bound:path)?
+ $(: ?$generics_unsized_bound:path)?
+ $(: $generics_lifetime_bound:lifetime)?
+ $(= $generics_default:ty)?
+ ),* $(,)?
+ >)?
+ $(where
+ $( $where_clause_ty:ty
+ $(: $where_clause_bound:path)?
+ $(: ?$where_clause_unsized_bound:path)?
+ $(: $where_clause_lifetime_bound:lifetime)?
+ ),* $(,)?
+ )?
+ {
+ $(
+ $(#[$variant_attrs:meta])*
+ $variant:ident $({
+ $(
+ $(#[$pin:ident])?
+ $field:ident: $field_ty:ty
+ ),+ $(,)?
+ })?
+ ),+ $(,)?
+ }
+ ) => {
+ $crate::__pin_project_internal! { @enum=>internal;
+ [$($proj_mut_ident)?]
+ [$($proj_ref_ident)?]
+ [$($proj_replace_ident)?]
+ [pub(crate)]
+ [$(#[$attrs])* pub enum $ident]
+ [$(<
+ $( $lifetime $(: $lifetime_bound)? ,)*
+ $( $generics
+ $(: $generics_bound)?
+ $(: ?$generics_unsized_bound)?
+ $(: $generics_lifetime_bound)?
+ $(= $generics_default)?
+ ),*
+ >)?]
+ [$(
+ $( $lifetime $(: $lifetime_bound)? ,)*
+ $( $generics
+ $(: $generics_bound)?
+ $(: ?$generics_unsized_bound)?
+ $(: $generics_lifetime_bound)?
+ ),*
+ )?]
+ [$( $( $lifetime ,)* $( $generics ),* )?]
+ [$(where $( $where_clause_ty
+ $(: $where_clause_bound)?
+ $(: ?$where_clause_unsized_bound)?
+ $(: $where_clause_lifetime_bound)?
+ ),* )?]
+ {
+ $(
+ $(#[$variant_attrs])*
+ $variant $({
+ $(
+ $(#[$pin])?
+ $field: $field_ty
+ ),+
+ })?
+ ),+
+ }
+ }
+ };
+ (
+ [$($proj_mut_ident:ident)?]
+ [$($proj_ref_ident:ident)?]
+ [$($proj_replace_ident:ident)?]
+
+ $(#[$attrs:meta])*
+ $vis:vis enum $ident:ident $(<
+ $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
+ $( $generics:ident
+ $(: $generics_bound:path)?
+ $(: ?$generics_unsized_bound:path)?
+ $(: $generics_lifetime_bound:lifetime)?
+ $(= $generics_default:ty)?
+ ),* $(,)?
+ >)?
+ $(where
+ $( $where_clause_ty:ty
+ $(: $where_clause_bound:path)?
+ $(: ?$where_clause_unsized_bound:path)?
+ $(: $where_clause_lifetime_bound:lifetime)?
+ ),* $(,)?
+ )?
+ {
+ $(
+ $(#[$variant_attrs:meta])*
+ $variant:ident $({
+ $(
+ $(#[$pin:ident])?
+ $field:ident: $field_ty:ty
+ ),+ $(,)?
+ })?
+ ),+ $(,)?
+ }
+ ) => {
+ $crate::__pin_project_internal! { @enum=>internal;
+ [$($proj_mut_ident)?]
+ [$($proj_ref_ident)?]
+ [$($proj_replace_ident)?]
+ [$vis]
+ [$(#[$attrs])* $vis enum $ident]
+ [$(<
+ $( $lifetime $(: $lifetime_bound)? ,)*
+ $( $generics
+ $(: $generics_bound)?
+ $(: ?$generics_unsized_bound)?
+ $(: $generics_lifetime_bound)?
+ $(= $generics_default)?
+ ),*
+ >)?]
+ [$(
+ $( $lifetime $(: $lifetime_bound)? ,)*
+ $( $generics
+ $(: $generics_bound)?
+ $(: ?$generics_unsized_bound)?
+ $(: $generics_lifetime_bound)?
+ ),*
+ )?]
+ [$( $( $lifetime ,)* $( $generics ),* )?]
+ [$(where $( $where_clause_ty
+ $(: $where_clause_bound)?
+ $(: ?$where_clause_unsized_bound)?
+ $(: $where_clause_lifetime_bound)?
+ ),* )?]
+ {
+ $(
+ $(#[$variant_attrs])*
+ $variant $({
+ $(
+ $(#[$pin])?
+ $field: $field_ty
+ ),+
+ })?
+ ),+
+ }
+ }
+ };
+}
+
+// Not public API.
+#[doc(hidden)]
+pub mod __private {
+ #[doc(hidden)]
+ pub use core::{
+ marker::{PhantomData, Unpin},
+ mem::ManuallyDrop,
+ ops::Drop,
+ pin::Pin,
+ ptr,
+ };
+
+ // This is an internal helper struct used by `pin_project!`.
+ #[doc(hidden)]
+ pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);
+
+ impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
+
+ // This is an internal helper used to ensure a value is dropped.
+ #[doc(hidden)]
+ pub struct UnsafeDropInPlaceGuard<T: ?Sized>(pub *mut T);
+
+ impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
+ fn drop(&mut self) {
+ unsafe {
+ ptr::drop_in_place(self.0);
+ }
+ }
+ }
+
+ // This is an internal helper used to ensure a value is overwritten without
+ // its destructor being called.
+ #[doc(hidden)]
+ pub struct UnsafeOverwriteGuard<T> {
+ pub value: ManuallyDrop<T>,
+ pub target: *mut T,
+ }
+
+ impl<T> Drop for UnsafeOverwriteGuard<T> {
+ fn drop(&mut self) {
+ unsafe {
+ ptr::write(self.target, ptr::read(&*self.value));
+ }
+ }
+ }
+}