1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
// Original code (./struct-default.rs):
//
// ```rust
// #![allow(dead_code)]
//
// use pin_project::pin_project;
//
// #[pin_project]
// struct Struct<T, U> {
// #[pin]
// pinned: T,
// unpinned: U,
// }
//
// fn main() {}
// ```
#![allow(dead_code, unused_imports, unused_parens)]
use pin_project::pin_project;
struct Struct<T, U> {
// #[pin]
pinned: T,
unpinned: U,
}
#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
#[allow(dead_code)] // This lint warns unused fields/variants.
struct __StructProjection<'pin, T, U> {
pinned: ::core::pin::Pin<&'pin mut (T)>,
unpinned: &'pin mut (U),
}
#[allow(dead_code)] // This lint warns unused fields/variants.
struct __StructProjectionRef<'pin, T, U> {
pinned: ::core::pin::Pin<&'pin (T)>,
unpinned: &'pin (U),
}
impl<T, U> Struct<T, U> {
fn project<'pin>(self: ::core::pin::Pin<&'pin mut Self>) -> __StructProjection<'pin, T, U> {
unsafe {
let Struct { pinned, unpinned } = self.get_unchecked_mut();
__StructProjection { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
}
}
fn project_ref<'pin>(self: ::core::pin::Pin<&'pin Self>) -> __StructProjectionRef<'pin, T, U> {
unsafe {
let Struct { pinned, unpinned } = self.get_ref();
__StructProjectionRef { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
}
}
}
// Automatically create the appropriate conditional `Unpin` implementation.
//
// Basically this is equivalent to the following code:
// ```rust
// impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
// ```
//
// However, if struct is public and there is a private type field,
// this would cause an E0446 (private type in public interface).
//
// When RFC 2145 is implemented (rust-lang/rust#48054),
// this will become a lint, rather then a hard error.
//
// As a workaround for this, we generate a new struct, containing all of the pinned
// fields from our #[pin_project] type. This struct is declared within
// a function, which makes it impossible to be named by user code.
// This guarantees that it will use the default auto-trait impl for Unpin -
// that is, it will implement Unpin iff all of its fields implement Unpin.
// This type can be safely declared as 'public', satisfying the privacy
// checker without actually allowing user code to access it.
//
// This allows users to apply the #[pin_project] attribute to types
// regardless of the privacy of the types of their fields.
//
// See also https://github.com/taiki-e/pin-project/pull/53.
#[allow(non_snake_case)]
fn __unpin_scope_Struct() {
struct __Struct<'pin, T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
__field0: T,
}
impl<'pin, T, U> ::core::marker::Unpin for Struct<T, U> where
__Struct<'pin, T, U>: ::core::marker::Unpin
{
}
}
// Ensure that struct does not implement `Drop`.
//
// There are two possible cases:
// 1. The user type does not implement Drop. In this case,
// the first blanked impl will not apply to it. This code
// will compile, as there is only one impl of MustNotImplDrop for the user type
// 2. The user type does impl Drop. This will make the blanket impl applicable,
// which will then conflict with the explicit MustNotImplDrop impl below.
// This will result in a compilation error, which is exactly what we want.
trait StructMustNotImplDrop {}
#[allow(clippy::drop_bounds)]
impl<T: ::core::ops::Drop> StructMustNotImplDrop for T {}
#[allow(single_use_lifetimes)]
impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
//
// Taking a reference to a packed field is unsafe, and applying
// #[deny(safe_packed_borrows)] makes sure that doing this without
// an 'unsafe' block (which we deliberately do not generate)
// is a hard error.
//
// If the struct ends up having #[repr(packed)] applied somehow,
// this will generate an (unfriendly) error message. Under all reasonable
// circumstances, we'll detect the #[repr(packed)] attribute, and generate
// a much nicer error above.
//
// See https://github.com/taiki-e/pin-project/pull/34 for more details.
#[allow(single_use_lifetimes)]
#[allow(non_snake_case)]
#[deny(safe_packed_borrows)]
fn __pin_project_assert_not_repr_packed_Struct<T, U>(val: &Struct<T, U>) {
&val.pinned;
&val.unpinned;
}
fn main() {}
|