1 | // Original code (./not_unpin.rs): |
2 | // |
3 | // ```rust |
4 | // #![allow(dead_code)] |
5 | // |
6 | // use pin_project::pin_project; |
7 | // |
8 | // #[pin_project(!Unpin)] |
9 | // pub struct Struct<T, U> { |
10 | // #[pin] |
11 | // pinned: T, |
12 | // unpinned: U, |
13 | // } |
14 | // |
15 | // fn main() { |
16 | // fn _is_unpin<T: Unpin>() {} |
17 | // // _is_unpin::<Struct<(), ()>>(); //~ ERROR `std::marker::PhantomPinned` cannot be unpinned |
18 | // } |
19 | // ``` |
20 | |
21 | #![allow (dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)] |
22 | #![allow (clippy::needless_lifetimes)] |
23 | |
24 | use pin_project::pin_project ; |
25 | |
26 | // #[pin_project(!Unpin)] |
27 | pub struct Struct<T, U> { |
28 | // #[pin] |
29 | pinned: T, |
30 | unpinned: U, |
31 | } |
32 | |
33 | const _: () = { |
34 | pub(crate) struct __StructProjection<'pin, T, U> |
35 | where |
36 | Struct<T, U>: 'pin, |
37 | { |
38 | pinned: ::pin_project::__private::Pin<&'pin mut (T)>, |
39 | unpinned: &'pin mut (U), |
40 | } |
41 | pub(crate) struct __StructProjectionRef<'pin, T, U> |
42 | where |
43 | Struct<T, U>: 'pin, |
44 | { |
45 | pinned: ::pin_project::__private::Pin<&'pin (T)>, |
46 | unpinned: &'pin (U), |
47 | } |
48 | |
49 | impl<T, U> Struct<T, U> { |
50 | pub(crate) fn project<'pin>( |
51 | self: ::pin_project::__private::Pin<&'pin mut Self>, |
52 | ) -> __StructProjection<'pin, T, U> { |
53 | unsafe { |
54 | let Self { pinned, unpinned } = self.get_unchecked_mut(); |
55 | __StructProjection { |
56 | pinned: ::pin_project::__private::Pin::new_unchecked(pinned), |
57 | unpinned, |
58 | } |
59 | } |
60 | } |
61 | pub(crate) fn project_ref<'pin>( |
62 | self: ::pin_project::__private::Pin<&'pin Self>, |
63 | ) -> __StructProjectionRef<'pin, T, U> { |
64 | unsafe { |
65 | let Self { pinned, unpinned } = self.get_ref(); |
66 | __StructProjectionRef { |
67 | pinned: ::pin_project::__private::Pin::new_unchecked(pinned), |
68 | unpinned, |
69 | } |
70 | } |
71 | } |
72 | } |
73 | |
74 | // Ensure that it's impossible to use pin projections on a #[repr(packed)] |
75 | // struct. |
76 | // |
77 | // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34 |
78 | // for details. |
79 | #[forbid (unaligned_references, safe_packed_borrows)] |
80 | fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) { |
81 | let _ = &this.pinned; |
82 | let _ = &this.unpinned; |
83 | } |
84 | |
85 | // Create `Unpin` impl that has trivial `Unpin` bounds. |
86 | // |
87 | // See https://github.com/taiki-e/pin-project/issues/102#issuecomment-540472282 |
88 | // for details. |
89 | impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where |
90 | ::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>: |
91 | ::pin_project::__private::Unpin |
92 | { |
93 | } |
94 | // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it. |
95 | // |
96 | // To ensure that users don't accidentally write a non-functional `UnsafeUnpin` |
97 | // impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin` |
98 | // impl, they'll get a "conflicting implementations of trait" error when |
99 | // coherence checks are run. |
100 | #[doc (hidden)] |
101 | unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where |
102 | ::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>: |
103 | ::pin_project::__private::Unpin |
104 | { |
105 | } |
106 | |
107 | // Ensure that struct does not implement `Drop`. |
108 | // |
109 | // See ./struct-default-expanded.rs for details. |
110 | trait StructMustNotImplDrop {} |
111 | #[allow (clippy::drop_bounds, drop_bounds)] |
112 | impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {} |
113 | impl<T, U> StructMustNotImplDrop for Struct<T, U> {} |
114 | // A dummy impl of `PinnedDrop`, to ensure that users don't accidentally |
115 | // write a non-functional `PinnedDrop` impls. |
116 | #[doc (hidden)] |
117 | impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> { |
118 | unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {} |
119 | } |
120 | }; |
121 | |
122 | fn main() { |
123 | fn _is_unpin<T: Unpin>() {} |
124 | // _is_unpin::<Struct<(), ()>>(); //~ ERROR `std::marker::PhantomPinned` cannot be unpinned |
125 | } |
126 | |