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