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