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