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