1//! A crate for safe and ergonomic [pin-projection]. 2//! 3//! # Examples 4//! 5//! [`#[pin_project]`][`pin_project`] attribute creates projection types 6//! covering all the fields of struct or enum. 7//! 8//! ```rust 9//! use std::pin::Pin; 10//! 11//! use pin_project::pin_project; 12//! 13//! #[pin_project] 14//! struct Struct<T, U> { 15//! #[pin] 16//! pinned: T, 17//! unpinned: U, 18//! } 19//! 20//! impl<T, U> Struct<T, U> { 21//! fn method(self: Pin<&mut Self>) { 22//! let this = self.project(); 23//! let _: Pin<&mut T> = this.pinned; // Pinned reference to the field 24//! let _: &mut U = this.unpinned; // Normal reference to the field 25//! } 26//! } 27//! ``` 28//! 29//! [*code like this will be generated*][struct-default-expanded] 30//! 31//! To use `#[pin_project]` on enums, you need to name the projection type 32//! returned from the method. 33//! 34//! ```rust 35//! use std::pin::Pin; 36//! 37//! use pin_project::pin_project; 38//! 39//! #[pin_project(project = EnumProj)] 40//! enum Enum<T, U> { 41//! Pinned(#[pin] T), 42//! Unpinned(U), 43//! } 44//! 45//! impl<T, U> Enum<T, U> { 46//! fn method(self: Pin<&mut Self>) { 47//! match self.project() { 48//! EnumProj::Pinned(x) => { 49//! let _: Pin<&mut T> = x; 50//! } 51//! EnumProj::Unpinned(y) => { 52//! let _: &mut U = y; 53//! } 54//! } 55//! } 56//! } 57//! ``` 58//! 59//! [*code like this will be generated*][enum-default-expanded] 60//! 61//! See [`#[pin_project]`][`pin_project`] attribute for more details, and 62//! see [examples] directory for more examples and generated code. 63//! 64//! [examples]: https://github.com/taiki-e/pin-project/blob/HEAD/examples/README.md 65//! [enum-default-expanded]: https://github.com/taiki-e/pin-project/blob/HEAD/examples/enum-default-expanded.rs 66//! [pin-projection]: core::pin#projections-and-structural-pinning 67//! [struct-default-expanded]: https://github.com/taiki-e/pin-project/blob/HEAD/examples/struct-default-expanded.rs 68 69#![no_std] 70#![doc(test( 71 no_crate_inject, 72 attr( 73 deny(warnings, rust_2018_idioms, single_use_lifetimes), 74 allow(dead_code, unused_variables) 75 ) 76))] 77#![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)] 78#![warn(missing_docs)] 79#![warn(clippy::all, clippy::default_trait_access)] 80#![allow(clippy::needless_doctest_main)] 81 82#[doc(inline)] 83pub use pin_project_internal::pin_project; 84#[doc(inline)] 85pub use pin_project_internal::pinned_drop; 86 87/// A trait used for custom implementations of [`Unpin`]. 88/// 89/// This trait is used in conjunction with the `UnsafeUnpin` argument to 90/// the [`#[pin_project]`][macro@pin_project] attribute. 91/// 92/// The Rust [`Unpin`] trait is safe to implement - by itself, 93/// implementing it cannot lead to [undefined behavior][undefined-behavior]. 94/// Undefined behavior can only occur when other unsafe code is used. 95/// 96/// It turns out that using pin projections, which requires unsafe code, 97/// imposes additional requirements on an [`Unpin`] impl. Normally, all of this 98/// unsafety is contained within this crate, ensuring that it's impossible for 99/// you to violate any of the guarantees required by pin projection. 100/// 101/// However, things change if you want to provide a custom [`Unpin`] impl 102/// for your `#[pin_project]` type. As stated in [the Rust 103/// documentation][pin-projection], you must be sure to only implement [`Unpin`] 104/// when all of your `#[pin]` fields (i.e. structurally pinned fields) are also 105/// [`Unpin`]. 106/// 107/// To help highlight this unsafety, the `UnsafeUnpin` trait is provided. 108/// Implementing this trait is logically equivalent to implementing [`Unpin`] - 109/// this crate will generate an [`Unpin`] impl for your type that 'forwards' to 110/// your `UnsafeUnpin` impl. However, this trait is `unsafe` - since your type 111/// uses structural pinning (otherwise, you wouldn't be using this crate!), 112/// you must be sure that your `UnsafeUnpin` impls follows all of 113/// the requirements for an [`Unpin`] impl of a structurally-pinned type. 114/// 115/// Note that if you specify `#[pin_project(UnsafeUnpin)]`, but do *not* 116/// provide an impl of `UnsafeUnpin`, your type will never implement [`Unpin`]. 117/// This is effectively the same thing as adding a [`PhantomPinned`] to your 118/// type. 119/// 120/// Since this trait is `unsafe`, impls of it will be detected by the 121/// `unsafe_code` lint, and by tools like [`cargo geiger`][cargo-geiger]. 122/// 123/// # Examples 124/// 125/// An `UnsafeUnpin` impl which, in addition to requiring that structurally 126/// pinned fields be [`Unpin`], imposes an additional requirement: 127/// 128/// ```rust 129/// use pin_project::{pin_project, UnsafeUnpin}; 130/// 131/// #[pin_project(UnsafeUnpin)] 132/// struct Struct<K, V> { 133/// #[pin] 134/// field_1: K, 135/// field_2: V, 136/// } 137/// 138/// unsafe impl<K, V> UnsafeUnpin for Struct<K, V> where K: Unpin + Clone {} 139/// ``` 140/// 141/// [`PhantomPinned`]: core::marker::PhantomPinned 142/// [cargo-geiger]: https://github.com/rust-secure-code/cargo-geiger 143/// [pin-projection]: core::pin#projections-and-structural-pinning 144/// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html 145pub unsafe trait UnsafeUnpin {} 146 147// Not public API. 148#[doc(hidden)] 149pub mod __private { 150 #[doc(hidden)] 151 pub use core::{ 152 marker::{PhantomData, PhantomPinned, Unpin}, 153 mem::ManuallyDrop, 154 ops::Drop, 155 pin::Pin, 156 ptr, 157 }; 158 159 #[doc(hidden)] 160 pub use pin_project_internal::__PinProjectInternalDerive; 161 162 use super::UnsafeUnpin; 163 164 // An internal trait used for custom implementations of [`Drop`]. 165 // 166 // **Do not call or implement this trait directly.** 167 // 168 // # Why this trait is private and `#[pinned_drop]` attribute is needed? 169 // 170 // Implementing `PinnedDrop::drop` is safe, but calling it is not safe. 171 // This is because destructors can be called multiple times in safe code and 172 // [double dropping is unsound][rust-lang/rust#62360]. 173 // 174 // Ideally, it would be desirable to be able to forbid manual calls in 175 // the same way as [`Drop::drop`], but the library cannot do it. So, by using 176 // macros and replacing them with private traits, 177 // this crate prevent users from calling `PinnedDrop::drop` in safe code. 178 // 179 // This allows implementing [`Drop`] safely using `#[pinned_drop]`. 180 // Also by using the [`drop`] function just like dropping a type that directly 181 // implements [`Drop`], can drop safely a type that implements `PinnedDrop`. 182 // 183 // [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360 184 #[doc(hidden)] 185 pub trait PinnedDrop { 186 #[doc(hidden)] 187 unsafe fn drop(self: Pin<&mut Self>); 188 } 189 190 // This is an internal helper struct used by `pin-project-internal`. 191 // This allows us to force an error if the user tries to provide 192 // a regular `Unpin` impl when they specify the `UnsafeUnpin` argument. 193 // This is why we need Wrapper: 194 // 195 // Supposed we have the following code: 196 // 197 // ```rust 198 // #[pin_project(UnsafeUnpin)] 199 // struct MyStruct<T> { 200 // #[pin] field: T 201 // } 202 // 203 // impl<T> Unpin for MyStruct<T> where MyStruct<T>: UnsafeUnpin {} // generated by pin-project-internal 204 // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user 205 // ``` 206 // 207 // We want this code to be rejected - the user is completely bypassing 208 // `UnsafeUnpin`, and providing an unsound Unpin impl in safe code! 209 // 210 // Unfortunately, the Rust compiler will accept the above code. 211 // Because MyStruct is declared in the same crate as the user-provided impl, 212 // the compiler will notice that `MyStruct<T>: UnsafeUnpin` never holds. 213 // 214 // The solution is to introduce the `Wrapper` struct, which is defined 215 // in the `pin-project` crate. 216 // 217 // We now have code that looks like this: 218 // 219 // ```rust 220 // impl<T> Unpin for MyStruct<T> where Wrapper<MyStruct<T>>: UnsafeUnpin {} // generated by pin-project-internal 221 // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user 222 // ``` 223 // 224 // We also have `unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}` 225 // in the `pin-project` crate. 226 // 227 // Now, our generated impl has a bound involving a type defined in another 228 // crate - Wrapper. This will cause rust to conservatively assume that 229 // `Wrapper<MyStruct<T>>: UnsafeUnpin` holds, in the interest of preserving 230 // forwards compatibility (in case such an impl is added for Wrapper<T> in 231 // a new version of the crate). 232 // 233 // This will cause rust to reject any other `Unpin` impls for MyStruct<T>, 234 // since it will assume that our generated impl could potentially apply in 235 // any situation. 236 // 237 // This achieves the desired effect - when the user writes 238 // `#[pin_project(UnsafeUnpin)]`, the user must either provide no impl of 239 // `UnsafeUnpin` (which is equivalent to making the type never implement 240 // Unpin), or provide an impl of `UnsafeUnpin`. It is impossible for them to 241 // provide an impl of `Unpin` 242 #[doc(hidden)] 243 pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T); 244 245 unsafe impl<T: ?Sized> UnsafeUnpin for Wrapper<'_, T> where T: UnsafeUnpin {} 246 247 // This is an internal helper struct used by `pin-project-internal`. 248 // 249 // See https://github.com/taiki-e/pin-project/pull/53 for more details. 250 #[doc(hidden)] 251 pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData<T>); 252 253 impl<T> Unpin for AlwaysUnpin<'_, T> {} 254 255 // This is an internal helper used to ensure a value is dropped. 256 #[doc(hidden)] 257 pub struct UnsafeDropInPlaceGuard<T: ?Sized>(pub *mut T); 258 259 impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> { 260 fn drop(&mut self) { 261 unsafe { 262 ptr::drop_in_place(self.0); 263 } 264 } 265 } 266 267 // This is an internal helper used to ensure a value is overwritten without 268 // its destructor being called. 269 #[doc(hidden)] 270 pub struct UnsafeOverwriteGuard<T> { 271 pub value: ManuallyDrop<T>, 272 pub target: *mut T, 273 } 274 275 impl<T> Drop for UnsafeOverwriteGuard<T> { 276 fn drop(&mut self) { 277 unsafe { 278 ptr::write(self.target, ptr::read(&*self.value)); 279 } 280 } 281 } 282} 283