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