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