@@ -27,8 +27,8 @@ impl<Fut1, Fut2, Data> TryChain<Fut1, Fut2, Data>
27
27
28
28
pub ( crate ) fn is_terminated ( & self ) -> bool {
29
29
match self {
30
- TryChain :: First ( ..) | TryChain :: Second ( _) => true ,
31
- TryChain :: Empty => false ,
30
+ TryChain :: First ( ..) | TryChain :: Second ( _) => false ,
31
+ TryChain :: Empty => true ,
32
32
}
33
33
}
34
34
@@ -53,7 +53,12 @@ impl<Fut1, Fut2, Data> TryChain<Fut1, Fut2, Data>
53
53
}
54
54
TryChain :: Second ( fut2) => {
55
55
// Poll the second future
56
- return unsafe { Pin :: new_unchecked ( fut2) } . try_poll ( cx)
56
+ return unsafe { Pin :: new_unchecked ( fut2) }
57
+ . try_poll ( cx)
58
+ . map ( |res| {
59
+ * this = TryChain :: Empty ; // Drop fut2.
60
+ res
61
+ } ) ;
57
62
}
58
63
TryChain :: Empty => {
59
64
panic ! ( "future must not be polled after it returned `Poll::Ready`" ) ;
@@ -69,3 +74,33 @@ impl<Fut1, Fut2, Data> TryChain<Fut1, Fut2, Data>
69
74
}
70
75
}
71
76
}
77
+
78
+ #[ cfg( test) ]
79
+ mod tests {
80
+ use std:: pin:: Pin ;
81
+ use std:: task:: Poll ;
82
+
83
+ use futures_test:: task:: noop_context;
84
+
85
+ use crate :: future:: ready;
86
+
87
+ use super :: { TryChain , TryChainAction } ;
88
+
89
+ #[ test]
90
+ fn try_chain_is_terminated ( ) {
91
+ let mut cx = noop_context ( ) ;
92
+
93
+ let mut future = TryChain :: new ( ready ( Ok ( 1 ) ) , ( ) ) ;
94
+ assert ! ( !future. is_terminated( ) ) ;
95
+
96
+ let res = Pin :: new ( & mut future) . poll (
97
+ & mut cx,
98
+ |res : Result < usize , ( ) > , ( ) | {
99
+ assert ! ( res. is_ok( ) ) ;
100
+ TryChainAction :: Future ( ready ( Ok ( 2 ) ) )
101
+ } ,
102
+ ) ;
103
+ assert_eq ! ( res, Poll :: Ready :: <Result <usize , ( ) >>( Ok ( 2 ) ) ) ;
104
+ assert ! ( future. is_terminated( ) ) ;
105
+ }
106
+ }
0 commit comments