Skip to content

Commit 3780e76

Browse files
Thomasdezeeuwcramertj
authored andcommitted
Fix TryChain::is_terminated
1 parent 98a7dad commit 3780e76

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

futures-util/src/try_future/try_chain.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)