@@ -53,11 +53,18 @@ impl<T> MaybeFuture<T> {
53
53
impl < T : Future > Future for MaybeFuture < T > {
54
54
type Output = T :: Output ;
55
55
56
- fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
57
- let this = self . project ( ) ;
58
- match this {
59
- MaybeFutureProj :: Some ( t) => t. poll ( cx) ,
56
+ fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
57
+ let mut this = self . as_mut ( ) . project ( ) ;
58
+ let poll_res = match this {
59
+ MaybeFutureProj :: Some ( ref mut t) => t. as_mut ( ) . poll ( cx) ,
60
60
MaybeFutureProj :: None => Poll :: Pending ,
61
+ } ;
62
+ match poll_res {
63
+ Poll :: Ready ( val) => {
64
+ self . as_mut ( ) . project_replace ( Self :: None ) ;
65
+ Poll :: Ready ( val)
66
+ }
67
+ Poll :: Pending => Poll :: Pending ,
61
68
}
62
69
}
63
70
}
@@ -70,3 +77,25 @@ impl<T: Future> Future for MaybeFuture<T> {
70
77
pub ( crate ) fn relay_only_mode ( ) -> bool {
71
78
std:: option_env!( "DEV_RELAY_ONLY" ) . is_some ( )
72
79
}
80
+
81
+ #[ cfg( test) ]
82
+ mod tests {
83
+ use std:: pin:: pin;
84
+
85
+ use tokio:: time:: Duration ;
86
+
87
+ use super :: * ;
88
+
89
+ #[ tokio:: test]
90
+ async fn test_maybefuture_poll_after_use ( ) {
91
+ let fut = async move { "hello" } ;
92
+ let mut maybe_fut = pin ! ( MaybeFuture :: Some ( fut) ) ;
93
+ let res = ( & mut maybe_fut) . await ;
94
+
95
+ assert_eq ! ( res, "hello" ) ;
96
+
97
+ // Now poll again
98
+ let res = tokio:: time:: timeout ( Duration :: from_millis ( 10 ) , maybe_fut) . await ;
99
+ assert ! ( res. is_err( ) ) ;
100
+ }
101
+ }
0 commit comments