• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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