1 | // Original code (./unsafe_unpin.rs): |
2 | // |
3 | // ```rust |
4 | // #![allow(dead_code)] |
5 | // |
6 | // use pin_project::{pin_project, UnsafeUnpin}; |
7 | // |
8 | // #[pin_project(UnsafeUnpin)] |
9 | // pub struct Struct<T, U> { |
10 | // #[pin] |
11 | // pinned: T, |
12 | // unpinned: U, |
13 | // } |
14 | // |
15 | // unsafe impl<T: Unpin, U> UnsafeUnpin for Struct<T, U> {} |
16 | // |
17 | // fn main() {} |
18 | // ``` |
19 | |
20 | #![allow (dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)] |
21 | #![allow (clippy::needless_lifetimes)] |
22 | |
23 | use pin_project::{pin_project , UnsafeUnpin}; |
24 | |
25 | // #[pin_project(UnsafeUnpin)] |
26 | pub struct Struct<T, U> { |
27 | // #[pin] |
28 | pinned: T, |
29 | unpinned: U, |
30 | } |
31 | |
32 | const _: () = { |
33 | pub(crate) struct __StructProjection<'pin, T, U> |
34 | where |
35 | Struct<T, U>: 'pin, |
36 | { |
37 | pinned: ::pin_project::__private::Pin<&'pin mut (T)>, |
38 | unpinned: &'pin mut (U), |
39 | } |
40 | pub(crate) struct __StructProjectionRef<'pin, T, U> |
41 | where |
42 | Struct<T, U>: 'pin, |
43 | { |
44 | pinned: ::pin_project::__private::Pin<&'pin (T)>, |
45 | unpinned: &'pin (U), |
46 | } |
47 | |
48 | impl<T, U> Struct<T, U> { |
49 | pub(crate) fn project<'pin>( |
50 | self: ::pin_project::__private::Pin<&'pin mut Self>, |
51 | ) -> __StructProjection<'pin, T, U> { |
52 | unsafe { |
53 | let Self { pinned, unpinned } = self.get_unchecked_mut(); |
54 | __StructProjection { |
55 | pinned: ::pin_project::__private::Pin::new_unchecked(pinned), |
56 | unpinned, |
57 | } |
58 | } |
59 | } |
60 | pub(crate) fn project_ref<'pin>( |
61 | self: ::pin_project::__private::Pin<&'pin Self>, |
62 | ) -> __StructProjectionRef<'pin, T, U> { |
63 | unsafe { |
64 | let Self { pinned, unpinned } = self.get_ref(); |
65 | __StructProjectionRef { |
66 | pinned: ::pin_project::__private::Pin::new_unchecked(pinned), |
67 | unpinned, |
68 | } |
69 | } |
70 | } |
71 | } |
72 | |
73 | // Ensure that it's impossible to use pin projections on a #[repr(packed)] |
74 | // struct. |
75 | // |
76 | // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34 |
77 | // for details. |
78 | #[forbid (unaligned_references, safe_packed_borrows)] |
79 | fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) { |
80 | let _ = &this.pinned; |
81 | let _ = &this.unpinned; |
82 | } |
83 | |
84 | // Implement `Unpin` via `UnsafeUnpin`. |
85 | impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where |
86 | ::pin_project::__private::Wrapper<'pin, Self>: ::pin_project::UnsafeUnpin |
87 | { |
88 | } |
89 | |
90 | // Ensure that struct does not implement `Drop`. |
91 | // |
92 | // See ./struct-default-expanded.rs for details. |
93 | trait StructMustNotImplDrop {} |
94 | #[allow (clippy::drop_bounds, drop_bounds)] |
95 | impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {} |
96 | impl<T, U> StructMustNotImplDrop for Struct<T, U> {} |
97 | // A dummy impl of `PinnedDrop`, to ensure that users don't accidentally |
98 | // write a non-functional `PinnedDrop` impls. |
99 | #[doc (hidden)] |
100 | impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> { |
101 | unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {} |
102 | } |
103 | }; |
104 | |
105 | unsafe impl<T: Unpin, U> UnsafeUnpin for Struct<T, U> {} |
106 | |
107 | fn main() {} |
108 | |