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