@@ -6,6 +6,8 @@ use std::task::{Context, Poll};
6
6
use futures:: ready;
7
7
use futures:: stream:: Stream ;
8
8
9
+ use pin_utils:: unsafe_unpinned;
10
+
9
11
/// Creates a new stream where each iteration calls the provided closure.
10
12
///
11
13
/// This allows creating a custom iterator with any behavior
@@ -52,7 +54,11 @@ pub fn from_fn<T, F>(f: F) -> FromFn<F, T>
52
54
/// [`stream::from_fn`]: fn.from_fn.html
53
55
pub struct FromFn < F , T > {
54
56
closure : F ,
55
- fut : Option < Box < dyn Future < Output = Option < T > > > > ,
57
+ fut : Option < Pin < Box < dyn Future < Output = Option < T > > > > > ,
58
+ }
59
+
60
+ impl < F , T > FromFn < F , T > {
61
+ unsafe_unpinned ! ( closure: F ) ;
56
62
}
57
63
58
64
impl < T , F : Unpin > Stream for FromFn < F , T >
@@ -63,10 +69,11 @@ impl<T, F: Unpin> Stream for FromFn<F, T>
63
69
#[ inline]
64
70
fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
65
71
if let None = self . fut {
66
- self . fut = Some ( ( self . closure ) ( ) ) ;
72
+ let fut = ( self . as_mut ( ) . closure ( ) ) ( ) ;
73
+ self . fut = unsafe { Some ( Pin :: new_unchecked ( fut) ) } ;
67
74
}
68
75
69
- let pinned = unsafe { Pin :: new_unchecked ( & mut self . fut . as_mut ( ) . unwrap ( ) ) } ;
76
+ let pinned = Pin :: new ( self . fut . as_mut ( ) . unwrap ( ) ) ;
70
77
let out = ready ! ( pinned. poll( cx) ) ;
71
78
72
79
self . fut = None ;
0 commit comments