@@ -33,11 +33,31 @@ pub enum Either<A, B> {
33
33
}
34
34
35
35
impl < A , B > Either < A , B > {
36
- fn project ( self : Pin < & mut Self > ) -> Either < Pin < & mut A > , Pin < & mut B > > {
36
+ /// Convert `Pin<&Either<A, B>>` to `Either<Pin<&A>, Pin<&B>>`,
37
+ /// pinned projections of the inner variants.
38
+ pub fn as_pin_ref ( self : Pin < & Self > ) -> Either < Pin < & A > , Pin < & B > > {
39
+ // SAFETY: We can use `new_unchecked` because the `inner` parts are
40
+ // guaranteed to be pinned, as they come from `self` which is pinned.
37
41
unsafe {
38
- match self . get_unchecked_mut ( ) {
39
- Either :: Left ( a) => Either :: Left ( Pin :: new_unchecked ( a) ) ,
40
- Either :: Right ( b) => Either :: Right ( Pin :: new_unchecked ( b) ) ,
42
+ match * Pin :: get_ref ( self ) {
43
+ Either :: Left ( ref inner) => Either :: Left ( Pin :: new_unchecked ( inner) ) ,
44
+ Either :: Right ( ref inner) => Either :: Right ( Pin :: new_unchecked ( inner) ) ,
45
+ }
46
+ }
47
+ }
48
+
49
+ /// Convert `Pin<&mut Either<A, B>>` to `Either<Pin<&mut A>, Pin<&mut B>>`,
50
+ /// pinned projections of the inner variants.
51
+ pub fn as_pin_mut ( self : Pin < & mut Self > ) -> Either < Pin < & mut A > , Pin < & mut B > > {
52
+ // SAFETY: `get_unchecked_mut` is fine because we don't move anything.
53
+ // We can use `new_unchecked` because the `inner` parts are guaranteed
54
+ // to be pinned, as they come from `self` which is pinned, and we never
55
+ // offer an unpinned `&mut A` or `&mut B` through `Pin<&mut Self>`. We
56
+ // also don't have an implementation of `Drop`, nor manual `Unpin`.
57
+ unsafe {
58
+ match * Pin :: get_unchecked_mut ( self ) {
59
+ Either :: Left ( ref mut inner) => Either :: Left ( Pin :: new_unchecked ( inner) ) ,
60
+ Either :: Right ( ref mut inner) => Either :: Right ( Pin :: new_unchecked ( inner) ) ,
41
61
}
42
62
}
43
63
}
85
105
type Output = A :: Output ;
86
106
87
107
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
88
- match self . project ( ) {
108
+ match self . as_pin_mut ( ) {
89
109
Either :: Left ( x) => x. poll ( cx) ,
90
110
Either :: Right ( x) => x. poll ( cx) ,
91
111
}
@@ -113,7 +133,7 @@ where
113
133
type Item = A :: Item ;
114
134
115
135
fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
116
- match self . project ( ) {
136
+ match self . as_pin_mut ( ) {
117
137
Either :: Left ( x) => x. poll_next ( cx) ,
118
138
Either :: Right ( x) => x. poll_next ( cx) ,
119
139
}
@@ -149,28 +169,28 @@ where
149
169
type Error = A :: Error ;
150
170
151
171
fn poll_ready ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
152
- match self . project ( ) {
172
+ match self . as_pin_mut ( ) {
153
173
Either :: Left ( x) => x. poll_ready ( cx) ,
154
174
Either :: Right ( x) => x. poll_ready ( cx) ,
155
175
}
156
176
}
157
177
158
178
fn start_send ( self : Pin < & mut Self > , item : Item ) -> Result < ( ) , Self :: Error > {
159
- match self . project ( ) {
179
+ match self . as_pin_mut ( ) {
160
180
Either :: Left ( x) => x. start_send ( item) ,
161
181
Either :: Right ( x) => x. start_send ( item) ,
162
182
}
163
183
}
164
184
165
185
fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
166
- match self . project ( ) {
186
+ match self . as_pin_mut ( ) {
167
187
Either :: Left ( x) => x. poll_flush ( cx) ,
168
188
Either :: Right ( x) => x. poll_flush ( cx) ,
169
189
}
170
190
}
171
191
172
192
fn poll_close ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
173
- match self . project ( ) {
193
+ match self . as_pin_mut ( ) {
174
194
Either :: Left ( x) => x. poll_close ( cx) ,
175
195
Either :: Right ( x) => x. poll_close ( cx) ,
176
196
}
@@ -198,7 +218,7 @@ mod if_std {
198
218
cx : & mut Context < ' _ > ,
199
219
buf : & mut [ u8 ] ,
200
220
) -> Poll < Result < usize > > {
201
- match self . project ( ) {
221
+ match self . as_pin_mut ( ) {
202
222
Either :: Left ( x) => x. poll_read ( cx, buf) ,
203
223
Either :: Right ( x) => x. poll_read ( cx, buf) ,
204
224
}
@@ -209,7 +229,7 @@ mod if_std {
209
229
cx : & mut Context < ' _ > ,
210
230
bufs : & mut [ IoSliceMut < ' _ > ] ,
211
231
) -> Poll < Result < usize > > {
212
- match self . project ( ) {
232
+ match self . as_pin_mut ( ) {
213
233
Either :: Left ( x) => x. poll_read_vectored ( cx, bufs) ,
214
234
Either :: Right ( x) => x. poll_read_vectored ( cx, bufs) ,
215
235
}
@@ -226,7 +246,7 @@ mod if_std {
226
246
cx : & mut Context < ' _ > ,
227
247
buf : & [ u8 ] ,
228
248
) -> Poll < Result < usize > > {
229
- match self . project ( ) {
249
+ match self . as_pin_mut ( ) {
230
250
Either :: Left ( x) => x. poll_write ( cx, buf) ,
231
251
Either :: Right ( x) => x. poll_write ( cx, buf) ,
232
252
}
@@ -237,21 +257,21 @@ mod if_std {
237
257
cx : & mut Context < ' _ > ,
238
258
bufs : & [ IoSlice < ' _ > ] ,
239
259
) -> Poll < Result < usize > > {
240
- match self . project ( ) {
260
+ match self . as_pin_mut ( ) {
241
261
Either :: Left ( x) => x. poll_write_vectored ( cx, bufs) ,
242
262
Either :: Right ( x) => x. poll_write_vectored ( cx, bufs) ,
243
263
}
244
264
}
245
265
246
266
fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) > > {
247
- match self . project ( ) {
267
+ match self . as_pin_mut ( ) {
248
268
Either :: Left ( x) => x. poll_flush ( cx) ,
249
269
Either :: Right ( x) => x. poll_flush ( cx) ,
250
270
}
251
271
}
252
272
253
273
fn poll_close ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) > > {
254
- match self . project ( ) {
274
+ match self . as_pin_mut ( ) {
255
275
Either :: Left ( x) => x. poll_close ( cx) ,
256
276
Either :: Right ( x) => x. poll_close ( cx) ,
257
277
}
@@ -268,7 +288,7 @@ mod if_std {
268
288
cx : & mut Context < ' _ > ,
269
289
pos : SeekFrom ,
270
290
) -> Poll < Result < u64 > > {
271
- match self . project ( ) {
291
+ match self . as_pin_mut ( ) {
272
292
Either :: Left ( x) => x. poll_seek ( cx, pos) ,
273
293
Either :: Right ( x) => x. poll_seek ( cx, pos) ,
274
294
}
@@ -281,14 +301,14 @@ mod if_std {
281
301
B : AsyncBufRead ,
282
302
{
283
303
fn poll_fill_buf ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < & [ u8 ] > > {
284
- match self . project ( ) {
304
+ match self . as_pin_mut ( ) {
285
305
Either :: Left ( x) => x. poll_fill_buf ( cx) ,
286
306
Either :: Right ( x) => x. poll_fill_buf ( cx) ,
287
307
}
288
308
}
289
309
290
310
fn consume ( self : Pin < & mut Self > , amt : usize ) {
291
- match self . project ( ) {
311
+ match self . as_pin_mut ( ) {
292
312
Either :: Left ( x) => x. consume ( amt) ,
293
313
Either :: Right ( x) => x. consume ( amt) ,
294
314
}
0 commit comments