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