pin_project/
lib.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3/*!
4<!-- tidy:crate-doc:start -->
5A crate for safe and ergonomic [pin-projection].
6
7## Usage
8
9Add this to your `Cargo.toml`:
10
11```toml
12[dependencies]
13pin-project = "1"
14```
15
16## Examples
17
18[`#[pin_project]`][`pin_project`] attribute creates projection types
19covering all the fields of struct or enum.
20
21```rust
22use std::pin::Pin;
23
24use pin_project::pin_project;
25
26#[pin_project]
27struct Struct<T, U> {
28    #[pin]
29    pinned: T,
30    unpinned: U,
31}
32
33impl<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
44To use `#[pin_project]` on enums, you need to name the projection type
45returned from the method.
46
47```rust
48use std::pin::Pin;
49
50use pin_project::pin_project;
51
52#[pin_project(project = EnumProj)]
53enum Enum<T, U> {
54    Pinned(#[pin] T),
55    Unpinned(U),
56}
57
58impl<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
74See [`#[pin_project]`][`pin_project`] attribute for more details, and
75see [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)]
114pub use pin_project_internal::pin_project;
115#[doc(inline)]
116pub 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
178pub unsafe trait UnsafeUnpin {}
179
180// Not public API.
181#[doc(hidden)]
182#[allow(missing_debug_implementations)]
183pub 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)]
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)]
311        pub unsafe fn new(ptr: *mut T) -> Self {
312            Self(ptr)
313        }
314    }
315    impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
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)]
334        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> {
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}