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 // ANDROID: Use std to allow building as a dylib. 83 extern crate std; 84 85 #[doc(inline)] 86 pub use pin_project_internal::pin_project; 87 #[doc(inline)] 88 pub use pin_project_internal::pinned_drop; 89 90 /// A trait used for custom implementations of [`Unpin`]. 91 /// 92 /// This trait is used in conjunction with the `UnsafeUnpin` argument to 93 /// the [`#[pin_project]`][macro@pin_project] attribute. 94 /// 95 /// The Rust [`Unpin`] trait is safe to implement - by itself, 96 /// implementing it cannot lead to [undefined behavior][undefined-behavior]. 97 /// Undefined behavior can only occur when other unsafe code is used. 98 /// 99 /// It turns out that using pin projections, which requires unsafe code, 100 /// imposes additional requirements on an [`Unpin`] impl. Normally, all of this 101 /// unsafety is contained within this crate, ensuring that it's impossible for 102 /// you to violate any of the guarantees required by pin projection. 103 /// 104 /// However, things change if you want to provide a custom [`Unpin`] impl 105 /// for your `#[pin_project]` type. As stated in [the Rust 106 /// documentation][pin-projection], you must be sure to only implement [`Unpin`] 107 /// when all of your `#[pin]` fields (i.e. structurally pinned fields) are also 108 /// [`Unpin`]. 109 /// 110 /// To help highlight this unsafety, the `UnsafeUnpin` trait is provided. 111 /// Implementing this trait is logically equivalent to implementing [`Unpin`] - 112 /// this crate will generate an [`Unpin`] impl for your type that 'forwards' to 113 /// your `UnsafeUnpin` impl. However, this trait is `unsafe` - since your type 114 /// uses structural pinning (otherwise, you wouldn't be using this crate!), 115 /// you must be sure that your `UnsafeUnpin` impls follows all of 116 /// the requirements for an [`Unpin`] impl of a structurally-pinned type. 117 /// 118 /// Note that if you specify `#[pin_project(UnsafeUnpin)]`, but do *not* 119 /// provide an impl of `UnsafeUnpin`, your type will never implement [`Unpin`]. 120 /// This is effectively the same thing as adding a [`PhantomPinned`] to your 121 /// type. 122 /// 123 /// Since this trait is `unsafe`, impls of it will be detected by the 124 /// `unsafe_code` lint, and by tools like [`cargo geiger`][cargo-geiger]. 125 /// 126 /// # Examples 127 /// 128 /// An `UnsafeUnpin` impl which, in addition to requiring that structurally 129 /// pinned fields be [`Unpin`], imposes an additional requirement: 130 /// 131 /// ```rust 132 /// use pin_project::{pin_project, UnsafeUnpin}; 133 /// 134 /// #[pin_project(UnsafeUnpin)] 135 /// struct Struct<K, V> { 136 /// #[pin] 137 /// field_1: K, 138 /// field_2: V, 139 /// } 140 /// 141 /// unsafe impl<K, V> UnsafeUnpin for Struct<K, V> where K: Unpin + Clone {} 142 /// ``` 143 /// 144 /// [`PhantomPinned`]: core::marker::PhantomPinned 145 /// [cargo-geiger]: https://github.com/rust-secure-code/cargo-geiger 146 /// [pin-projection]: core::pin#projections-and-structural-pinning 147 /// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html 148 pub unsafe trait UnsafeUnpin {} 149 150 // Not public API. 151 #[doc(hidden)] 152 pub mod __private { 153 #[doc(hidden)] 154 pub use core::{ 155 marker::{PhantomData, PhantomPinned, Unpin}, 156 mem::ManuallyDrop, 157 ops::Drop, 158 pin::Pin, 159 ptr, 160 }; 161 162 #[doc(hidden)] 163 pub use pin_project_internal::__PinProjectInternalDerive; 164 165 use super::UnsafeUnpin; 166 167 // An internal trait used for custom implementations of [`Drop`]. 168 // 169 // **Do not call or implement this trait directly.** 170 // 171 // # Why this trait is private and `#[pinned_drop]` attribute is needed? 172 // 173 // Implementing `PinnedDrop::drop` is safe, but calling it is not safe. 174 // This is because destructors can be called multiple times in safe code and 175 // [double dropping is unsound][rust-lang/rust#62360]. 176 // 177 // Ideally, it would be desirable to be able to forbid manual calls in 178 // the same way as [`Drop::drop`], but the library cannot do it. So, by using 179 // macros and replacing them with private traits, 180 // this crate prevent users from calling `PinnedDrop::drop` in safe code. 181 // 182 // This allows implementing [`Drop`] safely using `#[pinned_drop]`. 183 // Also by using the [`drop`] function just like dropping a type that directly 184 // implements [`Drop`], can drop safely a type that implements `PinnedDrop`. 185 // 186 // [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360 187 #[doc(hidden)] 188 pub trait PinnedDrop { 189 #[doc(hidden)] drop(self: Pin<&mut Self>)190 unsafe fn drop(self: Pin<&mut Self>); 191 } 192 193 // This is an internal helper struct used by `pin-project-internal`. 194 // This allows us to force an error if the user tries to provide 195 // a regular `Unpin` impl when they specify the `UnsafeUnpin` argument. 196 // This is why we need Wrapper: 197 // 198 // Supposed we have the following code: 199 // 200 // ```rust 201 // #[pin_project(UnsafeUnpin)] 202 // struct MyStruct<T> { 203 // #[pin] field: T 204 // } 205 // 206 // impl<T> Unpin for MyStruct<T> where MyStruct<T>: UnsafeUnpin {} // generated by pin-project-internal 207 // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user 208 // ``` 209 // 210 // We want this code to be rejected - the user is completely bypassing 211 // `UnsafeUnpin`, and providing an unsound Unpin impl in safe code! 212 // 213 // Unfortunately, the Rust compiler will accept the above code. 214 // Because MyStruct is declared in the same crate as the user-provided impl, 215 // the compiler will notice that `MyStruct<T>: UnsafeUnpin` never holds. 216 // 217 // The solution is to introduce the `Wrapper` struct, which is defined 218 // in the `pin-project` crate. 219 // 220 // We now have code that looks like this: 221 // 222 // ```rust 223 // impl<T> Unpin for MyStruct<T> where Wrapper<MyStruct<T>>: UnsafeUnpin {} // generated by pin-project-internal 224 // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user 225 // ``` 226 // 227 // We also have `unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}` 228 // in the `pin-project` crate. 229 // 230 // Now, our generated impl has a bound involving a type defined in another 231 // crate - Wrapper. This will cause rust to conservatively assume that 232 // `Wrapper<MyStruct<T>>: UnsafeUnpin` holds, in the interest of preserving 233 // forwards compatibility (in case such an impl is added for Wrapper<T> in 234 // a new version of the crate). 235 // 236 // This will cause rust to reject any other `Unpin` impls for MyStruct<T>, 237 // since it will assume that our generated impl could potentially apply in 238 // any situation. 239 // 240 // This achieves the desired effect - when the user writes 241 // `#[pin_project(UnsafeUnpin)]`, the user must either provide no impl of 242 // `UnsafeUnpin` (which is equivalent to making the type never implement 243 // Unpin), or provide an impl of `UnsafeUnpin`. It is impossible for them to 244 // provide an impl of `Unpin` 245 #[doc(hidden)] 246 pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T); 247 248 unsafe impl<T: ?Sized> UnsafeUnpin for Wrapper<'_, T> where T: UnsafeUnpin {} 249 250 // This is an internal helper struct used by `pin-project-internal`. 251 // 252 // See https://github.com/taiki-e/pin-project/pull/53 for more details. 253 #[doc(hidden)] 254 pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData<T>); 255 256 impl<T> Unpin for AlwaysUnpin<'_, T> {} 257 258 // This is an internal helper used to ensure a value is dropped. 259 #[doc(hidden)] 260 pub struct UnsafeDropInPlaceGuard<T: ?Sized>(pub *mut T); 261 262 impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> { drop(&mut self)263 fn drop(&mut self) { 264 unsafe { 265 ptr::drop_in_place(self.0); 266 } 267 } 268 } 269 270 // This is an internal helper used to ensure a value is overwritten without 271 // its destructor being called. 272 #[doc(hidden)] 273 pub struct UnsafeOverwriteGuard<T> { 274 pub value: ManuallyDrop<T>, 275 pub target: *mut T, 276 } 277 278 impl<T> Drop for UnsafeOverwriteGuard<T> { drop(&mut self)279 fn drop(&mut self) { 280 unsafe { 281 ptr::write(self.target, ptr::read(&*self.value)); 282 } 283 } 284 } 285 } 286