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
21use pin_project::pin_project;
22
23// #[pin_project]
24struct Struct<T, U> {
25 // #[pin]
26 pinned: T,
27 unpinned: U,
28}
29
30const _: () = {
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> {
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 }
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 UB, and applying
75 // `#[forbid(unaligned_references)]` makes sure that doing this is a hard error.
76 //
77 // If the struct ends up having #[repr(packed)] applied somehow,
78 // this will generate an (unfriendly) error message. Under all reasonable
79 // circumstances, we'll detect the #[repr(packed)] attribute, and generate
80 // a much nicer error above.
81 //
82 // See https://github.com/taiki-e/pin-project/pull/34 for more details.
83 #[forbid(unaligned_references, safe_packed_borrows)]
84 fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
85 let _ = &this.pinned;
86 let _ = &this.unpinned;
87 }
88
89 // Automatically create the appropriate conditional `Unpin` implementation.
90 //
91 // Basically this is equivalent to the following code:
92 //
93 // ```rust
94 // impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
95 // ```
96 //
97 // However, if struct is public and there is a private type field,
98 // this would cause an E0446 (private type in public interface).
99 //
100 // When RFC 2145 is implemented (rust-lang/rust#48054),
101 // this will become a lint, rather then a hard error.
102 //
103 // As a workaround for this, we generate a new struct, containing all of
104 // the pinned fields from our #[pin_project] type. This struct is declared
105 // within a function, which makes it impossible to be named by user code.
106 // This guarantees that it will use the default auto-trait impl for Unpin -
107 // that is, it will implement Unpin iff all of its fields implement Unpin.
108 // This type can be safely declared as 'public', satisfying the privacy
109 // checker without actually allowing user code to access it.
110 //
111 // This allows users to apply the #[pin_project] attribute to types
112 // regardless of the privacy of the types of their fields.
113 //
114 // See also https://github.com/taiki-e/pin-project/pull/53.
115 struct __Struct<'pin, T, U> {
116 __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
117 'pin,
118 (::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
119 >,
120 __field0: T,
121 }
122 impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
123 __Struct<'pin, T, U>: ::pin_project::__private::Unpin
124 {
125 }
126 // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
127 //
128 // To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
129 // impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin`
130 // impl, they'll get a "conflicting implementations of trait" error when
131 // coherence checks are run.
132 #[doc(hidden)]
133 unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
134 __Struct<'pin, T, U>: ::pin_project::__private::Unpin
135 {
136 }
137
138 // Ensure that struct does not implement `Drop`.
139 //
140 // If you attempt to provide an Drop impl, the blanket impl will
141 // then apply to your type, causing a compile-time error due to
142 // the conflict with the second impl.
143 trait StructMustNotImplDrop {}
144 #[allow(clippy::drop_bounds, drop_bounds)]
145 impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
146 impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
147 // A dummy impl of `PinnedDrop`, to ensure that users don't accidentally
148 // write a non-functional `PinnedDrop` impls.
149 #[doc(hidden)]
150 impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
151 unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
152 }
153};
154
155fn main() {}
156