1+ use pin_project_lite:: pin_project;
12use std:: future:: Future ;
23use std:: pin:: Pin ;
34
45use crate :: future:: IntoFuture ;
56use crate :: task:: { ready, Context , Poll } ;
67
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+ }
1115}
1216
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+ }
1831}
1932
2033impl < 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 > {
2235 FlattenFuture {
23- state : State :: First ( future ) ,
36+ state : State :: First { fut1 } ,
2437 }
2538 }
2639}
@@ -33,19 +46,19 @@ where
3346 type Output = <Fut1 :: Output as IntoFuture >:: Output ;
3447
3548 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 ;
3750 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 } ) ;
4255 }
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 ) ;
4659 return Poll :: Ready ( v) ;
4760 }
48- State :: Empty => panic ! ( "polled a completed future" ) ,
61+ StateProj :: Empty => panic ! ( "polled a completed future" ) ,
4962 }
5063 }
5164 }
0 commit comments