1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 3 /*! 4 <!-- tidy:crate-doc:start --> 5 A crate for safe and ergonomic [pin-projection]. 6 7 ## Usage 8 9 Add this to your `Cargo.toml`: 10 11 ```toml 12 [dependencies] 13 pin-project = "1" 14 ``` 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(unsafe_op_in_unsafe_fn)] 99 #![warn( 100 // Lints that may help when writing public library. 101 missing_debug_implementations, 102 missing_docs, 103 clippy::alloc_instead_of_core, 104 clippy::exhaustive_enums, 105 clippy::exhaustive_structs, 106 clippy::impl_trait_in_params, 107 // clippy::missing_inline_in_public_items, 108 clippy::std_instead_of_alloc, 109 clippy::std_instead_of_core, 110 )] 111 #![allow(clippy::needless_doctest_main)] 112 113 #[doc(inline)] 114 pub use pin_project_internal::pin_project; 115 #[doc(inline)] 116 pub use pin_project_internal::pinned_drop; 117 118 /// A trait used for custom implementations of [`Unpin`]. 119 /// 120 /// This trait is used in conjunction with the `UnsafeUnpin` argument to 121 /// the [`#[pin_project]`][macro@pin_project] attribute. 122 /// 123 /// # Safety 124 /// 125 /// The Rust [`Unpin`] trait is safe to implement - by itself, 126 /// implementing it cannot lead to [undefined behavior][undefined-behavior]. 127 /// Undefined behavior can only occur when other unsafe code is used. 128 /// 129 /// It turns out that using pin projections, which requires unsafe code, 130 /// imposes additional requirements on an [`Unpin`] impl. Normally, all of this 131 /// unsafety is contained within this crate, ensuring that it's impossible for 132 /// you to violate any of the guarantees required by pin projection. 133 /// 134 /// However, things change if you want to provide a custom [`Unpin`] impl 135 /// for your `#[pin_project]` type. As stated in [the Rust 136 /// documentation][pin-projection], you must be sure to only implement [`Unpin`] 137 /// when all of your `#[pin]` fields (i.e. structurally pinned fields) are also 138 /// [`Unpin`]. 139 /// 140 /// To help highlight this unsafety, the `UnsafeUnpin` trait is provided. 141 /// Implementing this trait is logically equivalent to implementing [`Unpin`] - 142 /// this crate will generate an [`Unpin`] impl for your type that 'forwards' to 143 /// your `UnsafeUnpin` impl. However, this trait is `unsafe` - since your type 144 /// uses structural pinning (otherwise, you wouldn't be using this crate!), 145 /// you must be sure that your `UnsafeUnpin` impls follows all of 146 /// the requirements for an [`Unpin`] impl of a structurally-pinned type. 147 /// 148 /// Note that if you specify `#[pin_project(UnsafeUnpin)]`, but do *not* 149 /// provide an impl of `UnsafeUnpin`, your type will never implement [`Unpin`]. 150 /// This is effectively the same thing as adding a [`PhantomPinned`] to your 151 /// type. 152 /// 153 /// Since this trait is `unsafe`, impls of it will be detected by the 154 /// `unsafe_code` lint, and by tools like [`cargo geiger`][cargo-geiger]. 155 /// 156 /// # Examples 157 /// 158 /// An `UnsafeUnpin` impl which, in addition to requiring that structurally 159 /// pinned fields be [`Unpin`], imposes an additional requirement: 160 /// 161 /// ``` 162 /// use pin_project::{pin_project, UnsafeUnpin}; 163 /// 164 /// #[pin_project(UnsafeUnpin)] 165 /// struct Struct<K, V> { 166 /// #[pin] 167 /// field_1: K, 168 /// field_2: V, 169 /// } 170 /// 171 /// unsafe impl<K, V> UnsafeUnpin for Struct<K, V> where K: Unpin + Clone {} 172 /// ``` 173 /// 174 /// [`PhantomPinned`]: core::marker::PhantomPinned 175 /// [cargo-geiger]: https://github.com/rust-secure-code/cargo-geiger 176 /// [pin-projection]: core::pin#projections-and-structural-pinning 177 /// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html 178 pub unsafe trait UnsafeUnpin {} 179 180 // Not public API. 181 #[doc(hidden)] 182 #[allow(missing_debug_implementations)] 183 pub mod __private { 184 use core::mem::ManuallyDrop; 185 #[doc(hidden)] 186 pub use core::{ 187 marker::{PhantomData, PhantomPinned, Unpin}, 188 ops::Drop, 189 pin::Pin, 190 ptr, 191 }; 192 193 #[doc(hidden)] 194 pub use pin_project_internal::__PinProjectInternalDerive; 195 196 use super::UnsafeUnpin; 197 198 // An internal trait used for custom implementations of [`Drop`]. 199 // 200 // **Do not call or implement this trait directly.** 201 // 202 // # Why this trait is private and `#[pinned_drop]` attribute is needed? 203 // 204 // Implementing `PinnedDrop::drop` is safe, but calling it is not safe. 205 // This is because destructors can be called multiple times in safe code and 206 // [double dropping is unsound][rust-lang/rust#62360]. 207 // 208 // Ideally, it would be desirable to be able to forbid manual calls in 209 // the same way as [`Drop::drop`], but the library cannot do it. So, by using 210 // macros and replacing them with private traits, 211 // this crate prevent users from calling `PinnedDrop::drop` in safe code. 212 // 213 // This allows implementing [`Drop`] safely using `#[pinned_drop]`. 214 // Also by using the [`drop`] function just like dropping a type that directly 215 // implements [`Drop`], can drop safely a type that implements `PinnedDrop`. 216 // 217 // [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360 218 #[doc(hidden)] 219 pub trait PinnedDrop { 220 #[doc(hidden)] drop(self: Pin<&mut Self>)221 unsafe fn drop(self: Pin<&mut Self>); 222 } 223 224 // This is an internal helper struct used by `pin-project-internal`. 225 // This allows us to force an error if the user tries to provide 226 // a regular `Unpin` impl when they specify the `UnsafeUnpin` argument. 227 // This is why we need Wrapper: 228 // 229 // Supposed we have the following code: 230 // 231 // ``` 232 // #[pin_project(UnsafeUnpin)] 233 // struct MyStruct<T> { 234 // #[pin] field: T 235 // } 236 // 237 // impl<T> Unpin for MyStruct<T> where MyStruct<T>: UnsafeUnpin {} // generated by pin-project-internal 238 // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user 239 // ``` 240 // 241 // We want this code to be rejected - the user is completely bypassing 242 // `UnsafeUnpin`, and providing an unsound Unpin impl in safe code! 243 // 244 // Unfortunately, the Rust compiler will accept the above code. 245 // Because MyStruct is declared in the same crate as the user-provided impl, 246 // the compiler will notice that `MyStruct<T>: UnsafeUnpin` never holds. 247 // 248 // The solution is to introduce the `Wrapper` struct, which is defined 249 // in the `pin-project` crate. 250 // 251 // We now have code that looks like this: 252 // 253 // ``` 254 // impl<T> Unpin for MyStruct<T> where Wrapper<MyStruct<T>>: UnsafeUnpin {} // generated by pin-project-internal 255 // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user 256 // ``` 257 // 258 // We also have `unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}` 259 // in the `pin-project` crate. 260 // 261 // Now, our generated impl has a bound involving a type defined in another 262 // crate - Wrapper. This will cause rust to conservatively assume that 263 // `Wrapper<MyStruct<T>>: UnsafeUnpin` holds, in the interest of preserving 264 // forwards compatibility (in case such an impl is added for Wrapper<T> in 265 // a new version of the crate). 266 // 267 // This will cause rust to reject any other `Unpin` impls for MyStruct<T>, 268 // since it will assume that our generated impl could potentially apply in 269 // any situation. 270 // 271 // This achieves the desired effect - when the user writes 272 // `#[pin_project(UnsafeUnpin)]`, the user must either provide no impl of 273 // `UnsafeUnpin` (which is equivalent to making the type never implement 274 // Unpin), or provide an impl of `UnsafeUnpin`. It is impossible for them to 275 // provide an impl of `Unpin` 276 #[doc(hidden)] 277 #[allow(dead_code)] 278 pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T); 279 // SAFETY: `T` implements UnsafeUnpin. 280 unsafe impl<T: ?Sized + UnsafeUnpin> UnsafeUnpin for Wrapper<'_, T> {} 281 282 // Workaround for issue on unstable negative_impls feature that allows unsound overlapping Unpin 283 // implementations and rustc bug that leaks unstable negative_impls into stable. 284 // See https://github.com/taiki-e/pin-project/issues/340#issuecomment-2432146009 for details. 285 #[doc(hidden)] 286 pub type PinnedFieldsOf<T> = 287 <PinnedFieldsOfHelperStruct<T> as PinnedFieldsOfHelperTrait>::Actual; 288 // We cannot use <Option<T> as IntoIterator>::Item or similar since we should allow ?Sized in T. 289 #[doc(hidden)] 290 pub trait PinnedFieldsOfHelperTrait { 291 type Actual: ?Sized; 292 } 293 #[doc(hidden)] 294 pub struct PinnedFieldsOfHelperStruct<T: ?Sized>(T); 295 impl<T: ?Sized> PinnedFieldsOfHelperTrait for PinnedFieldsOfHelperStruct<T> { 296 type Actual = T; 297 } 298 299 // This is an internal helper struct used by `pin-project-internal`. 300 // 301 // See https://github.com/taiki-e/pin-project/pull/53 for more details. 302 #[doc(hidden)] 303 pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData<T>); 304 impl<T> Unpin for AlwaysUnpin<'_, T> {} 305 306 // This is an internal helper used to ensure a value is dropped. 307 #[doc(hidden)] 308 pub struct UnsafeDropInPlaceGuard<T: ?Sized>(*mut T); 309 impl<T: ?Sized> UnsafeDropInPlaceGuard<T> { 310 #[doc(hidden)] new(ptr: *mut T) -> Self311 pub unsafe fn new(ptr: *mut T) -> Self { 312 Self(ptr) 313 } 314 } 315 impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> { drop(&mut self)316 fn drop(&mut self) { 317 // SAFETY: the caller of `UnsafeDropInPlaceGuard::new` must guarantee 318 // that `ptr` is valid for drop when this guard is destructed. 319 unsafe { 320 ptr::drop_in_place(self.0); 321 } 322 } 323 } 324 325 // This is an internal helper used to ensure a value is overwritten without 326 // its destructor being called. 327 #[doc(hidden)] 328 pub struct UnsafeOverwriteGuard<T> { 329 target: *mut T, 330 value: ManuallyDrop<T>, 331 } 332 impl<T> UnsafeOverwriteGuard<T> { 333 #[doc(hidden)] new(target: *mut T, value: T) -> Self334 pub unsafe fn new(target: *mut T, value: T) -> Self { 335 Self { target, value: ManuallyDrop::new(value) } 336 } 337 } 338 impl<T> Drop for UnsafeOverwriteGuard<T> { drop(&mut self)339 fn drop(&mut self) { 340 // SAFETY: the caller of `UnsafeOverwriteGuard::new` must guarantee 341 // that `target` is valid for writes when this guard is destructed. 342 unsafe { 343 ptr::write(self.target, ptr::read(&*self.value)); 344 } 345 } 346 } 347 } 348