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