• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 OR MIT
2 
3 // Original code (./not_unpin.rs):
4 //
5 // ```
6 // #![allow(dead_code)]
7 //
8 // use pin_project::pin_project;
9 //
10 // #[pin_project(!Unpin)]
11 // struct Struct<T, U> {
12 //     #[pin]
13 //     pinned: T,
14 //     unpinned: U,
15 // }
16 //
17 // fn main() {
18 //     fn _is_unpin<T: Unpin>() {}
19 //     // _is_unpin::<Struct<(), ()>>(); //~ ERROR `std::marker::PhantomPinned` cannot be unpinned
20 // }
21 // ```
22 
23 #![allow(
24     dead_code,
25     unused_imports,
26     unused_parens,
27     unknown_lints,
28     renamed_and_removed_lints,
29     clippy::needless_lifetimes,
30     clippy::undocumented_unsafe_blocks
31 )]
32 
33 use pin_project::pin_project;
34 
35 // #[pin_project(!Unpin)]
36 struct Struct<T, U> {
37     // #[pin]
38     pinned: T,
39     unpinned: U,
40 }
41 
42 const _: () = {
43     struct __StructProjection<'pin, T, U>
44     where
45         Struct<T, U>: 'pin,
46     {
47         pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
48         unpinned: &'pin mut (U),
49     }
50     struct __StructProjectionRef<'pin, T, U>
51     where
52         Struct<T, U>: 'pin,
53     {
54         pinned: ::pin_project::__private::Pin<&'pin (T)>,
55         unpinned: &'pin (U),
56     }
57 
58     impl<T, U> Struct<T, U> {
project<'pin>( self: ::pin_project::__private::Pin<&'pin mut Self>, ) -> __StructProjection<'pin, T, U>59         fn project<'pin>(
60             self: ::pin_project::__private::Pin<&'pin mut Self>,
61         ) -> __StructProjection<'pin, T, U> {
62             unsafe {
63                 let Self { pinned, unpinned } = self.get_unchecked_mut();
64                 __StructProjection {
65                     pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
66                     unpinned,
67                 }
68             }
69         }
project_ref<'pin>( self: ::pin_project::__private::Pin<&'pin Self>, ) -> __StructProjectionRef<'pin, T, U>70         fn project_ref<'pin>(
71             self: ::pin_project::__private::Pin<&'pin Self>,
72         ) -> __StructProjectionRef<'pin, T, U> {
73             unsafe {
74                 let Self { pinned, unpinned } = self.get_ref();
75                 __StructProjectionRef {
76                     pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
77                     unpinned,
78                 }
79             }
80         }
81     }
82 
83     // Ensure that it's impossible to use pin projections on a #[repr(packed)]
84     // struct.
85     //
86     // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
87     // for details.
88     #[forbid(unaligned_references, safe_packed_borrows)]
__assert_not_repr_packed<T, U>(this: &Struct<T, U>)89     fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
90         let _ = &this.pinned;
91         let _ = &this.unpinned;
92     }
93 
94     // Create `Unpin` impl that has trivial `Unpin` bounds.
95     //
96     // See https://github.com/taiki-e/pin-project/issues/102#issuecomment-540472282
97     // for details.
98     #[doc(hidden)]
99     impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
100         ::pin_project::__private::PinnedFieldsOf<
101             ::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>,
102         >: ::pin_project::__private::Unpin
103     {
104     }
105     // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
106     //
107     // To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
108     // impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin`
109     // impl, they'll get a "conflicting implementations of trait" error when
110     // coherence checks are run.
111     #[doc(hidden)]
112     unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
113         ::pin_project::__private::PinnedFieldsOf<
114             ::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>,
115         >: ::pin_project::__private::Unpin
116     {
117     }
118 
119     // Ensure that struct does not implement `Drop`.
120     //
121     // See ./struct-default-expanded.rs for details.
122     trait StructMustNotImplDrop {}
123     #[allow(clippy::drop_bounds, drop_bounds)]
124     impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
125     impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
126     // A dummy impl of `PinnedDrop`, to ensure that users don't accidentally
127     // write a non-functional `PinnedDrop` impls.
128     #[doc(hidden)]
129     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
drop(self: ::pin_project::__private::Pin<&mut Self>)130         unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
131     }
132 };
133 
main()134 fn main() {
135     fn _is_unpin<T: Unpin>() {}
136     // _is_unpin::<Struct<(), ()>>(); //~ ERROR `std::marker::PhantomPinned` cannot be unpinned
137 }
138