1 // SPDX-License-Identifier: Apache-2.0 OR MIT
2
3 // Original code (./struct-default.rs):
4 //
5 // ```
6 // #![allow(dead_code)]
7 //
8 // use pin_project::pin_project;
9 //
10 // #[pin_project(project_replace)]
11 // struct Struct<T, U> {
12 // #[pin]
13 // pinned: T,
14 // unpinned: U,
15 // }
16 //
17 // fn main() {}
18 // ```
19
20 #![allow(
21 dead_code,
22 unused_imports,
23 unused_parens,
24 unknown_lints,
25 renamed_and_removed_lints,
26 clippy::needless_lifetimes,
27 clippy::undocumented_unsafe_blocks
28 )]
29
30 use pin_project::pin_project;
31
32 // #[pin_project(project_replace)]
33 struct Struct<T, U> {
34 // #[pin]
35 pinned: T,
36 unpinned: U,
37 }
38
39 const _: () = {
40 struct __StructProjection<'pin, T, U>
41 where
42 Struct<T, U>: 'pin,
43 {
44 pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
45 unpinned: &'pin mut (U),
46 }
47 struct __StructProjectionRef<'pin, T, U>
48 where
49 Struct<T, U>: 'pin,
50 {
51 pinned: ::pin_project::__private::Pin<&'pin (T)>,
52 unpinned: &'pin (U),
53 }
54 struct __StructProjectionOwned<T, U> {
55 pinned: ::pin_project::__private::PhantomData<T>,
56 unpinned: U,
57 }
58
59 impl<T, U> Struct<T, U> {
project<'pin>( self: ::pin_project::__private::Pin<&'pin mut Self>, ) -> __StructProjection<'pin, T, U>60 fn project<'pin>(
61 self: ::pin_project::__private::Pin<&'pin mut Self>,
62 ) -> __StructProjection<'pin, T, U> {
63 unsafe {
64 let Self { pinned, unpinned } = self.get_unchecked_mut();
65 __StructProjection {
66 pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
67 unpinned,
68 }
69 }
70 }
project_ref<'pin>( self: ::pin_project::__private::Pin<&'pin Self>, ) -> __StructProjectionRef<'pin, T, U>71 fn project_ref<'pin>(
72 self: ::pin_project::__private::Pin<&'pin Self>,
73 ) -> __StructProjectionRef<'pin, T, U> {
74 unsafe {
75 let Self { pinned, unpinned } = self.get_ref();
76 __StructProjectionRef {
77 pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
78 unpinned,
79 }
80 }
81 }
project_replace( self: ::pin_project::__private::Pin<&mut Self>, __replacement: Self, ) -> __StructProjectionOwned<T, U>82 fn project_replace(
83 self: ::pin_project::__private::Pin<&mut Self>,
84 __replacement: Self,
85 ) -> __StructProjectionOwned<T, U> {
86 unsafe {
87 let __self_ptr: *mut Self = self.get_unchecked_mut();
88
89 // Destructors will run in reverse order, so next create a guard to overwrite
90 // `self` with the replacement value without calling destructors.
91 let __guard =
92 ::pin_project::__private::UnsafeOverwriteGuard::new(__self_ptr, __replacement);
93
94 let Self { pinned, unpinned } = &mut *__self_ptr;
95
96 // First, extract all the unpinned fields
97 let __result = __StructProjectionOwned {
98 pinned: ::pin_project::__private::PhantomData,
99 unpinned: ::pin_project::__private::ptr::read(unpinned),
100 };
101
102 // Now create guards to drop all the pinned fields
103 //
104 // Due to a compiler bug (https://github.com/rust-lang/rust/issues/47949)
105 // this must be in its own scope, or else `__result` will not be dropped
106 // if any of the destructors panic.
107 {
108 let __guard = ::pin_project::__private::UnsafeDropInPlaceGuard::new(pinned);
109 }
110
111 // Finally, return the result
112 __result
113 }
114 }
115 }
116
117 // Ensure that it's impossible to use pin projections on a #[repr(packed)]
118 // struct.
119 //
120 // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
121 // for details.
122 #[forbid(unaligned_references, safe_packed_borrows)]
__assert_not_repr_packed<T, U>(this: &Struct<T, U>)123 fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
124 let _ = &this.pinned;
125 let _ = &this.unpinned;
126 }
127
128 // Automatically create the appropriate conditional `Unpin` implementation.
129 //
130 // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
131 // for details.
132 struct __Struct<'pin, T, U> {
133 __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
134 'pin,
135 (::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
136 >,
137 __field0: T,
138 }
139 impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
140 ::pin_project::__private::PinnedFieldsOf<__Struct<'pin, T, U>>:
141 ::pin_project::__private::Unpin
142 {
143 }
144 // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
145 #[doc(hidden)]
146 unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
147 ::pin_project::__private::PinnedFieldsOf<__Struct<'pin, T, U>>:
148 ::pin_project::__private::Unpin
149 {
150 }
151
152 // Ensure that struct does not implement `Drop`.
153 //
154 // See ./struct-default-expanded.rs for details.
155 trait StructMustNotImplDrop {}
156 #[allow(clippy::drop_bounds, drop_bounds)]
157 impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
158 impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
159 // A dummy impl of `PinnedDrop`, to ensure that users don't accidentally
160 // write a non-functional `PinnedDrop` impls.
161 #[doc(hidden)]
162 impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
drop(self: ::pin_project::__private::Pin<&mut Self>)163 unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
164 }
165 };
166
main()167 fn main() {}
168