// SPDX-License-Identifier: Apache-2.0 OR MIT

/*!
<!-- tidy:crate-doc:start -->
A crate for safe and ergonomic [pin-projection].

## Usage

Add this to your `Cargo.toml`:

```toml
[dependencies]
pin-project = "1"
```

## Examples

[`#[pin_project]`][`pin_project`] attribute creates projection types
covering all the fields of struct or enum.

```rust
use std::pin::Pin;

use pin_project::pin_project;

#[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
    }
}
```

[*code like this will be generated*][struct-default-expanded]

To use `#[pin_project]` on enums, you need to name the projection type
returned from the method.

```rust
use std::pin::Pin;

use pin_project::pin_project;

#[pin_project(project = EnumProj)]
enum Enum<T, U> {
    Pinned(#[pin] T),
    Unpinned(U),
}

impl<T, U> Enum<T, U> {
    fn method(self: Pin<&mut Self>) {
        match self.project() {
            EnumProj::Pinned(x) => {
                let _: Pin<&mut T> = x;
            }
            EnumProj::Unpinned(y) => {
                let _: &mut U = y;
            }
        }
    }
}
```

[*code like this will be generated*][enum-default-expanded]

See [`#[pin_project]`][`pin_project`] attribute for more details, and
see [examples] directory for more examples and generated code.

## Related Projects

- [pin-project-lite]: A lightweight version of pin-project written with declarative macros.

[enum-default-expanded]: https://github.com/taiki-e/pin-project/blob/HEAD/examples/enum-default-expanded.rs
[examples]: https://github.com/taiki-e/pin-project/blob/HEAD/examples/README.md
[pin-project-lite]: https://github.com/taiki-e/pin-project-lite
[pin-projection]: https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning
[struct-default-expanded]: https://github.com/taiki-e/pin-project/blob/HEAD/examples/struct-default-expanded.rs

<!-- tidy:crate-doc:end -->
*/

#![no_std]
#![doc(test(
    no_crate_inject,
    attr(
        deny(warnings, rust_2018_idioms, single_use_lifetimes),
        allow(dead_code, unused_variables)
    )
))]
#![warn(unsafe_op_in_unsafe_fn)]
#![warn(
    // Lints that may help when writing public library.
    missing_debug_implementations,
    missing_docs,
    clippy::alloc_instead_of_core,
    clippy::exhaustive_enums,
    clippy::exhaustive_structs,
    clippy::impl_trait_in_params,
    // clippy::missing_inline_in_public_items,
    clippy::std_instead_of_alloc,
    clippy::std_instead_of_core,
)]
#![allow(clippy::needless_doctest_main)]

#[doc(inline)]
pub use pin_project_internal::pin_project;
#[doc(inline)]
pub use pin_project_internal::pinned_drop;

/// A trait used for custom implementations of [`Unpin`].
///
/// This trait is used in conjunction with the `UnsafeUnpin` argument to
/// the [`#[pin_project]`][macro@pin_project] attribute.
///
/// # Safety
///
/// The Rust [`Unpin`] trait is safe to implement - by itself,
/// implementing it cannot lead to [undefined behavior][undefined-behavior].
/// Undefined behavior can only occur when other unsafe code is used.
///
/// It turns out that using pin projections, which requires unsafe code,
/// imposes additional requirements on an [`Unpin`] impl. Normally, all of this
/// unsafety is contained within this crate, ensuring that it's impossible for
/// you to violate any of the guarantees required by pin projection.
///
/// However, things change if you want to provide a custom [`Unpin`] impl
/// for your `#[pin_project]` type. As stated in [the Rust
/// documentation][pin-projection], you must be sure to only implement [`Unpin`]
/// when all of your `#[pin]` fields (i.e. structurally pinned fields) are also
/// [`Unpin`].
///
/// To help highlight this unsafety, the `UnsafeUnpin` trait is provided.
/// Implementing this trait is logically equivalent to implementing [`Unpin`] -
/// this crate will generate an [`Unpin`] impl for your type that 'forwards' to
/// your `UnsafeUnpin` impl. However, this trait is `unsafe` - since your type
/// uses structural pinning (otherwise, you wouldn't be using this crate!),
/// you must be sure that your `UnsafeUnpin` impls follows all of
/// the requirements for an [`Unpin`] impl of a structurally-pinned type.
///
/// Note that if you specify `#[pin_project(UnsafeUnpin)]`, but do *not*
/// provide an impl of `UnsafeUnpin`, your type will never implement [`Unpin`].
/// This is effectively the same thing as adding a [`PhantomPinned`] to your
/// type.
///
/// Since this trait is `unsafe`, impls of it will be detected by the
/// `unsafe_code` lint, and by tools like [`cargo geiger`][cargo-geiger].
///
/// # Examples
///
/// An `UnsafeUnpin` impl which, in addition to requiring that structurally
/// pinned fields be [`Unpin`], imposes an additional requirement:
///
/// ```
/// use pin_project::{pin_project, UnsafeUnpin};
///
/// #[pin_project(UnsafeUnpin)]
/// struct Struct<K, V> {
///     #[pin]
///     field_1: K,
///     field_2: V,
/// }
///
/// unsafe impl<K, V> UnsafeUnpin for Struct<K, V> where K: Unpin + Clone {}
/// ```
///
/// [`PhantomPinned`]: core::marker::PhantomPinned
/// [cargo-geiger]: https://github.com/rust-secure-code/cargo-geiger
/// [pin-projection]: core::pin#projections-and-structural-pinning
/// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
pub unsafe trait UnsafeUnpin {}

// Not public API.
#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub mod __private {
    use core::mem::ManuallyDrop;
    #[doc(hidden)]
    pub use core::{
        marker::{PhantomData, PhantomPinned, Unpin},
        ops::Drop,
        pin::Pin,
        ptr,
    };

    #[doc(hidden)]
    pub use pin_project_internal::__PinProjectInternalDerive;

    use super::UnsafeUnpin;

    // An internal trait used for custom implementations of [`Drop`].
    //
    // **Do not call or implement this trait directly.**
    //
    // # Why this trait is private and `#[pinned_drop]` attribute is needed?
    //
    // Implementing `PinnedDrop::drop` is safe, but calling it is not safe.
    // This is because destructors can be called multiple times in safe code and
    // [double dropping is unsound][rust-lang/rust#62360].
    //
    // Ideally, it would be desirable to be able to forbid manual calls in
    // the same way as [`Drop::drop`], but the library cannot do it. So, by using
    // macros and replacing them with private traits,
    // this crate prevent users from calling `PinnedDrop::drop` in safe code.
    //
    // This allows implementing [`Drop`] safely using `#[pinned_drop]`.
    // Also by using the [`drop`] function just like dropping a type that directly
    // implements [`Drop`], can drop safely a type that implements `PinnedDrop`.
    //
    // [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360
    #[doc(hidden)]
    pub trait PinnedDrop {
        #[doc(hidden)]
        unsafe fn drop(self: Pin<&mut Self>);
    }

    // This is an internal helper struct used by `pin-project-internal`.
    // This allows us to force an error if the user tries to provide
    // a regular `Unpin` impl when they specify the `UnsafeUnpin` argument.
    // This is why we need Wrapper:
    //
    // Supposed we have the following code:
    //
    // ```
    // #[pin_project(UnsafeUnpin)]
    // struct MyStruct<T> {
    //     #[pin] field: T
    // }
    //
    // impl<T> Unpin for MyStruct<T> where MyStruct<T>: UnsafeUnpin {} // generated by pin-project-internal
    // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user
    // ```
    //
    // We want this code to be rejected - the user is completely bypassing
    // `UnsafeUnpin`, and providing an unsound Unpin impl in safe code!
    //
    // Unfortunately, the Rust compiler will accept the above code.
    // Because MyStruct is declared in the same crate as the user-provided impl,
    // the compiler will notice that `MyStruct<T>: UnsafeUnpin` never holds.
    //
    // The solution is to introduce the `Wrapper` struct, which is defined
    // in the `pin-project` crate.
    //
    // We now have code that looks like this:
    //
    // ```
    // impl<T> Unpin for MyStruct<T> where Wrapper<MyStruct<T>>: UnsafeUnpin {} // generated by pin-project-internal
    // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user
    // ```
    //
    // We also have `unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}`
    // in the `pin-project` crate.
    //
    // Now, our generated impl has a bound involving a type defined in another
    // crate - Wrapper. This will cause rust to conservatively assume that
    // `Wrapper<MyStruct<T>>: UnsafeUnpin` holds, in the interest of preserving
    // forwards compatibility (in case such an impl is added for Wrapper<T> in
    // a new version of the crate).
    //
    // This will cause rust to reject any other `Unpin` impls for MyStruct<T>,
    // since it will assume that our generated impl could potentially apply in
    // any situation.
    //
    // This achieves the desired effect - when the user writes
    // `#[pin_project(UnsafeUnpin)]`, the user must either provide no impl of
    // `UnsafeUnpin` (which is equivalent to making the type never implement
    // Unpin), or provide an impl of `UnsafeUnpin`. It is impossible for them to
    // provide an impl of `Unpin`
    #[doc(hidden)]
    #[allow(dead_code)]
    pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T);
    // SAFETY: `T` implements UnsafeUnpin.
    unsafe impl<T: ?Sized + UnsafeUnpin> UnsafeUnpin for Wrapper<'_, T> {}

    // Workaround for issue on unstable negative_impls feature that allows unsound overlapping Unpin
    // implementations and rustc bug that leaks unstable negative_impls into stable.
    // See https://github.com/taiki-e/pin-project/issues/340#issuecomment-2432146009 for details.
    #[doc(hidden)]
    pub type PinnedFieldsOf<T> =
        <PinnedFieldsOfHelperStruct<T> as PinnedFieldsOfHelperTrait>::Actual;
    // We cannot use <Option<T> as IntoIterator>::Item or similar since we should allow ?Sized in T.
    #[doc(hidden)]
    pub trait PinnedFieldsOfHelperTrait {
        type Actual: ?Sized;
    }
    #[doc(hidden)]
    pub struct PinnedFieldsOfHelperStruct<T: ?Sized>(T);
    impl<T: ?Sized> PinnedFieldsOfHelperTrait for PinnedFieldsOfHelperStruct<T> {
        type Actual = T;
    }

    // This is an internal helper struct used by `pin-project-internal`.
    //
    // See https://github.com/taiki-e/pin-project/pull/53 for more details.
    #[doc(hidden)]
    pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData<T>);
    impl<T> Unpin for AlwaysUnpin<'_, T> {}

    // This is an internal helper used to ensure a value is dropped.
    #[doc(hidden)]
    pub struct UnsafeDropInPlaceGuard<T: ?Sized>(*mut T);
    impl<T: ?Sized> UnsafeDropInPlaceGuard<T> {
        #[doc(hidden)]
        pub unsafe fn new(ptr: *mut T) -> Self {
            Self(ptr)
        }
    }
    impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
        fn drop(&mut self) {
            // SAFETY: the caller of `UnsafeDropInPlaceGuard::new` must guarantee
            // that `ptr` is valid for drop when this guard is destructed.
            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> {
        target: *mut T,
        value: ManuallyDrop<T>,
    }
    impl<T> UnsafeOverwriteGuard<T> {
        #[doc(hidden)]
        pub unsafe fn new(target: *mut T, value: T) -> Self {
            Self { target, value: ManuallyDrop::new(value) }
        }
    }
    impl<T> Drop for UnsafeOverwriteGuard<T> {
        fn drop(&mut self) {
            // SAFETY: the caller of `UnsafeOverwriteGuard::new` must guarantee
            // that `target` is valid for writes when this guard is destructed.
            unsafe {
                ptr::write(self.target, ptr::read(&*self.value));
            }
        }
    }
}
