1 // Original code (./struct-default.rs):
2 //
3 // ```rust
4 // #![allow(dead_code)]
5 //
6 // use pin_project::pin_project;
7 //
8 // #[pin_project]
9 // struct Struct<T, U> {
10 // #[pin]
11 // pinned: T,
12 // unpinned: U,
13 // }
14 //
15 // fn main() {}
16 // ```
17
18 #![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
19 #![allow(clippy::needless_lifetimes)]
20
21 use pin_project::pin_project;
22
23 // #[pin_project]
24 struct Struct<T, U> {
25 // #[pin]
26 pinned: T,
27 unpinned: U,
28 }
29
30 const _: () = {
31 struct __StructProjection<'pin, T, U>
32 where
33 Struct<T, U>: 'pin,
34 {
35 pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
36 unpinned: &'pin mut (U),
37 }
38 struct __StructProjectionRef<'pin, T, U>
39 where
40 Struct<T, U>: 'pin,
41 {
42 pinned: ::pin_project::__private::Pin<&'pin (T)>,
43 unpinned: &'pin (U),
44 }
45
46 impl<T, U> Struct<T, U> {
project<'pin>( self: ::pin_project::__private::Pin<&'pin mut Self>, ) -> __StructProjection<'pin, T, U>47 fn project<'pin>(
48 self: ::pin_project::__private::Pin<&'pin mut Self>,
49 ) -> __StructProjection<'pin, T, U> {
50 unsafe {
51 let Self { pinned, unpinned } = self.get_unchecked_mut();
52 __StructProjection {
53 pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
54 unpinned,
55 }
56 }
57 }
project_ref<'pin>( self: ::pin_project::__private::Pin<&'pin Self>, ) -> __StructProjectionRef<'pin, T, U>58 fn project_ref<'pin>(
59 self: ::pin_project::__private::Pin<&'pin Self>,
60 ) -> __StructProjectionRef<'pin, T, U> {
61 unsafe {
62 let Self { pinned, unpinned } = self.get_ref();
63 __StructProjectionRef {
64 pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
65 unpinned,
66 }
67 }
68 }
69 }
70
71 // Ensure that it's impossible to use pin projections on a #[repr(packed)]
72 // struct.
73 //
74 // Taking a reference to a packed field is unsafe, and applying
75 // #[forbid(safe_packed_borrows)] makes sure that doing this without
76 // an 'unsafe' block (which we deliberately do not generate)
77 // is a hard error.
78 //
79 // If the struct ends up having #[repr(packed)] applied somehow,
80 // this will generate an (unfriendly) error message. Under all reasonable
81 // circumstances, we'll detect the #[repr(packed)] attribute, and generate
82 // a much nicer error above.
83 //
84 // See https://github.com/taiki-e/pin-project/pull/34 for more details.
85 #[forbid(safe_packed_borrows)]
__assert_not_repr_packed<T, U>(this: &Struct<T, U>)86 fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
87 let _ = &this.pinned;
88 let _ = &this.unpinned;
89 }
90
91 // Automatically create the appropriate conditional `Unpin` implementation.
92 //
93 // Basically this is equivalent to the following code:
94 //
95 // ```rust
96 // impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
97 // ```
98 //
99 // However, if struct is public and there is a private type field,
100 // this would cause an E0446 (private type in public interface).
101 //
102 // When RFC 2145 is implemented (rust-lang/rust#48054),
103 // this will become a lint, rather then a hard error.
104 //
105 // As a workaround for this, we generate a new struct, containing all of
106 // the pinned fields from our #[pin_project] type. This struct is declared
107 // within a function, which makes it impossible to be named by user code.
108 // This guarantees that it will use the default auto-trait impl for Unpin -
109 // that is, it will implement Unpin iff all of its fields implement Unpin.
110 // This type can be safely declared as 'public', satisfying the privacy
111 // checker without actually allowing user code to access it.
112 //
113 // This allows users to apply the #[pin_project] attribute to types
114 // regardless of the privacy of the types of their fields.
115 //
116 // See also https://github.com/taiki-e/pin-project/pull/53.
117 struct __Struct<'pin, T, U> {
118 __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
119 'pin,
120 (::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
121 >,
122 __field0: T,
123 }
124 impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
125 __Struct<'pin, T, U>: ::pin_project::__private::Unpin
126 {
127 }
128 // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
129 //
130 // To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
131 // impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin`
132 // impl, they'll get a "conflicting implementations of trait" error when
133 // coherence checks are run.
134 #[doc(hidden)]
135 unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
136 __Struct<'pin, T, U>: ::pin_project::__private::Unpin
137 {
138 }
139
140 // Ensure that struct does not implement `Drop`.
141 //
142 // If you attempt to provide an Drop impl, the blanket impl will
143 // then apply to your type, causing a compile-time error due to
144 // the conflict with the second impl.
145 trait StructMustNotImplDrop {}
146 #[allow(clippy::drop_bounds, drop_bounds)]
147 impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
148 impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
149 // A dummy impl of `PinnedDrop`, to ensure that users don't accidentally
150 // write a non-functional `PinnedDrop` impls.
151 #[doc(hidden)]
152 impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
drop(self: ::pin_project::__private::Pin<&mut Self>)153 unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
154 }
155 };
156
main()157 fn main() {}
158