@@ -3,11 +3,17 @@ use crate::FutureExt;
3
3
use core:: pin:: Pin ;
4
4
use futures_core:: task:: { Context , Poll } ;
5
5
use futures_core:: { FusedFuture , Future , Stream } ;
6
+ use pin_project_lite:: pin_project;
6
7
7
- /// Future for the [`poll_immediate`](poll_immediate()) function.
8
- #[ derive( Debug , Clone ) ]
9
- #[ must_use = "futures do nothing unless you `.await` or poll them" ]
10
- pub struct PollImmediate < T > ( Option < T > ) ;
8
+ pin_project ! {
9
+ /// Future for the [`poll_immediate`](poll_immediate()) function.
10
+ #[ derive( Debug , Clone ) ]
11
+ #[ must_use = "futures do nothing unless you `.await` or poll them" ]
12
+ pub struct PollImmediate <T > {
13
+ #[ pin]
14
+ future: Option <T >
15
+ }
16
+ }
11
17
12
18
impl < T , F > Future for PollImmediate < F >
13
19
where
@@ -17,21 +23,22 @@ where
17
23
18
24
#[ inline]
19
25
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < T > > {
20
- // # Safety
21
- // This is the only time that this future will ever be polled.
26
+ let mut this = self . project ( ) ;
22
27
let inner =
23
- unsafe { self . get_unchecked_mut ( ) . 0 . take ( ) . expect ( "PollOnce polled after completion" ) } ;
24
- crate :: pin_mut!( inner) ;
28
+ this. future . as_mut ( ) . as_pin_mut ( ) . expect ( "PollImmediate polled after completion" ) ;
25
29
match inner. poll ( cx) {
26
- Poll :: Ready ( t) => Poll :: Ready ( Some ( t) ) ,
30
+ Poll :: Ready ( t) => {
31
+ this. future . set ( None ) ;
32
+ Poll :: Ready ( Some ( t) )
33
+ }
27
34
Poll :: Pending => Poll :: Ready ( None ) ,
28
35
}
29
36
}
30
37
}
31
38
32
39
impl < T : Future > FusedFuture for PollImmediate < T > {
33
40
fn is_terminated ( & self ) -> bool {
34
- self . 0 . is_none ( )
41
+ self . future . is_none ( )
35
42
}
36
43
}
37
44
@@ -64,25 +71,14 @@ where
64
71
type Item = Poll < T > ;
65
72
66
73
fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
67
- unsafe {
68
- // # Safety
69
- // We never move the inner value until it is done. We only get a reference to it.
70
- let inner = & mut self . get_unchecked_mut ( ) . 0 ;
71
- let fut = match inner. as_mut ( ) {
72
- // inner is gone, so we can signal that the stream is closed.
73
- None => return Poll :: Ready ( None ) ,
74
- Some ( inner) => inner,
75
- } ;
76
- let fut = Pin :: new_unchecked ( fut) ;
77
- Poll :: Ready ( Some ( fut. poll ( cx) . map ( |t| {
78
- // # Safety
79
- // The inner option value is done, so we need to drop it. We do it without moving it
80
- // by using drop in place. We then write over the value without trying to drop it first
81
- // This should uphold all the safety requirements of `Pin`
82
- std:: ptr:: drop_in_place ( inner) ;
83
- std:: ptr:: write ( inner, None ) ;
74
+ let mut this = self . project ( ) ;
75
+ match this. future . as_mut ( ) . as_pin_mut ( ) {
76
+ // inner is gone, so we can signal that the stream is closed.
77
+ None => Poll :: Ready ( None ) ,
78
+ Some ( fut) => Poll :: Ready ( Some ( fut. poll ( cx) . map ( |t| {
79
+ this. future . set ( None ) ;
84
80
t
85
- } ) ) )
81
+ } ) ) ) ,
86
82
}
87
83
}
88
84
}
103
99
/// # });
104
100
/// ```
105
101
pub fn poll_immediate < F : Future > ( f : F ) -> PollImmediate < F > {
106
- assert_future :: < Option < F :: Output > , PollImmediate < F > > ( PollImmediate ( Some ( f) ) )
102
+ assert_future :: < Option < F :: Output > , PollImmediate < F > > ( PollImmediate { future : Some ( f) } )
107
103
}
108
104
109
105
/// Future for the [`poll_immediate_reuse`](poll_immediate_reuse()) function.
@@ -119,7 +115,8 @@ where
119
115
120
116
#[ inline]
121
117
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < T , F > > {
122
- let mut inner = self . get_mut ( ) . 0 . take ( ) . expect ( "PollOnceReuse polled after completion" ) ;
118
+ let mut inner =
119
+ self . get_mut ( ) . 0 . take ( ) . expect ( "PollImmediateReuse polled after completion" ) ;
123
120
match inner. poll_unpin ( cx) {
124
121
Poll :: Ready ( t) => Poll :: Ready ( Ok ( t) ) ,
125
122
Poll :: Pending => Poll :: Ready ( Err ( inner) ) ,
0 commit comments