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