@@ -27,8 +27,8 @@ impl<Fut1, Fut2, Data> TryChain<Fut1, Fut2, Data>
2727
2828 pub ( crate ) fn is_terminated ( & self ) -> bool {
2929 match self {
30- TryChain :: First ( ..) | TryChain :: Second ( _) => true ,
31- TryChain :: Empty => false ,
30+ TryChain :: First ( ..) | TryChain :: Second ( _) => false ,
31+ TryChain :: Empty => true ,
3232 }
3333 }
3434
@@ -53,7 +53,12 @@ impl<Fut1, Fut2, Data> TryChain<Fut1, Fut2, Data>
5353 }
5454 TryChain :: Second ( fut2) => {
5555 // 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+ } ) ;
5762 }
5863 TryChain :: Empty => {
5964 panic ! ( "future must not be polled after it returned `Poll::Ready`" ) ;
@@ -69,3 +74,33 @@ impl<Fut1, Fut2, Data> TryChain<Fut1, Fut2, Data>
6974 }
7075 }
7176}
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