1
+ use pin_project_lite:: pin_project;
1
2
use std:: future:: Future ;
2
3
use std:: pin:: Pin ;
3
4
4
5
use crate :: future:: IntoFuture ;
5
6
use crate :: task:: { ready, Context , Poll } ;
6
7
7
- #[ doc( hidden) ]
8
- #[ allow( missing_debug_implementations) ]
9
- pub struct FlattenFuture < Fut1 , Fut2 > {
10
- state : State < Fut1 , Fut2 > ,
8
+ pin_project ! {
9
+ #[ doc( hidden) ]
10
+ #[ allow( missing_debug_implementations) ]
11
+ pub struct FlattenFuture <Fut1 , Fut2 > {
12
+ #[ pin]
13
+ state: State <Fut1 , Fut2 >,
14
+ }
11
15
}
12
16
13
- #[ derive( Debug ) ]
14
- enum State < Fut1 , Fut2 > {
15
- First ( Fut1 ) ,
16
- Second ( Fut2 ) ,
17
- Empty ,
17
+ pin_project ! {
18
+ #[ project = StateProj ]
19
+ #[ derive( Debug ) ]
20
+ enum State <Fut1 , Fut2 > {
21
+ First {
22
+ #[ pin]
23
+ fut1: Fut1 ,
24
+ } ,
25
+ Second {
26
+ #[ pin]
27
+ fut2: Fut2 ,
28
+ } ,
29
+ Empty ,
30
+ }
18
31
}
19
32
20
33
impl < Fut1 , Fut2 > FlattenFuture < Fut1 , Fut2 > {
21
- pub ( crate ) fn new ( future : Fut1 ) -> FlattenFuture < Fut1 , Fut2 > {
34
+ pub ( crate ) fn new ( fut1 : Fut1 ) -> FlattenFuture < Fut1 , Fut2 > {
22
35
FlattenFuture {
23
- state : State :: First ( future ) ,
36
+ state : State :: First { fut1 } ,
24
37
}
25
38
}
26
39
}
@@ -33,19 +46,19 @@ where
33
46
type Output = <Fut1 :: Output as IntoFuture >:: Output ;
34
47
35
48
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
36
- let Self { state } = unsafe { self . get_unchecked_mut ( ) } ;
49
+ let mut state = self . project ( ) . state ;
37
50
loop {
38
- match state {
39
- State :: First ( fut1) => {
40
- let fut2 = ready ! ( unsafe { Pin :: new_unchecked ( fut1) } . poll( cx) ) . into_future ( ) ;
41
- * state = State :: Second ( fut2) ;
51
+ match state. as_mut ( ) . project ( ) {
52
+ StateProj :: First { fut1 } => {
53
+ let fut2 = ready ! ( fut1. poll( cx) ) . into_future ( ) ;
54
+ state. set ( State :: Second { fut2 } ) ;
42
55
}
43
- State :: Second ( fut2) => {
44
- let v = ready ! ( unsafe { Pin :: new_unchecked ( fut2) } . poll( cx) ) ;
45
- * state = State :: Empty ;
56
+ StateProj :: Second { fut2 } => {
57
+ let v = ready ! ( fut2. poll( cx) ) ;
58
+ state. set ( State :: Empty ) ;
46
59
return Poll :: Ready ( v) ;
47
60
}
48
- State :: Empty => panic ! ( "polled a completed future" ) ,
61
+ StateProj :: Empty => panic ! ( "polled a completed future" ) ,
49
62
}
50
63
}
51
64
}
0 commit comments