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