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