@@ -53,7 +53,7 @@ pub mod macro_impl;
53
53
use core:: {
54
54
future:: Future ,
55
55
ops:: { ControlFlow , Coroutine , CoroutineState } ,
56
- pin:: Pin ,
56
+ pin:: pin ,
57
57
} ;
58
58
use frunk:: {
59
59
coproduct:: { CNil , CoprodInjector , CoprodUninjector , CoproductEmbedder , CoproductSubsetter } ,
@@ -76,7 +76,7 @@ pub fn run<F, R>(mut f: F) -> R
76
76
where
77
77
F : Coroutine < Coproduct < Begin , CNil > , Yield = CNil , Return = R > ,
78
78
{
79
- let pinned = core :: pin :: pin!( f) ;
79
+ let pinned = pin ! ( f) ;
80
80
match pinned. resume ( Coproduct :: Inl ( Begin ) ) {
81
81
CoroutineState :: Yielded ( never) => match never { } ,
82
82
CoroutineState :: Complete ( ret) => ret,
@@ -108,14 +108,13 @@ impl<E: Effect> EffectGroup for E {
108
108
/// Create a new effectful computation by applying a "pure" function to the return value of an
109
109
/// existing computation.
110
110
pub fn map < E , I , T , U > (
111
- mut g : impl Coroutine < I , Yield = E , Return = T > ,
111
+ g : impl Coroutine < I , Yield = E , Return = T > ,
112
112
f : impl FnOnce ( T ) -> U ,
113
113
) -> impl Coroutine < I , Yield = E , Return = U > {
114
- move |mut injs : I | {
114
+ static move |mut injs : I | {
115
+ let mut pinned = pin ! ( g) ;
115
116
loop {
116
- // safety: see handle_group()
117
- let pinned = unsafe { Pin :: new_unchecked ( & mut g) } ;
118
- match pinned. resume ( injs) {
117
+ match pinned. as_mut ( ) . resume ( injs) {
119
118
CoroutineState :: Yielded ( effs) => injs = yield effs,
120
119
CoroutineState :: Complete ( ret) => return f ( ret) ,
121
120
}
@@ -196,7 +195,7 @@ pub fn handle_group<
196
195
BeginIndex ,
197
196
EmbedIndices ,
198
197
> (
199
- mut g : G ,
198
+ g : G ,
200
199
mut handler : impl FnMut ( Es ) -> ControlFlow < R , Is > ,
201
200
) -> impl Coroutine < PostIs , Yield = PostEs , Return = R >
202
201
where
@@ -208,14 +207,11 @@ where
208
207
PostIs : CoproductEmbedder < PreIs , EmbedIndices > ,
209
208
G : Coroutine < PreIs , Yield = PreEs , Return = R > ,
210
209
{
211
- move |_begin : PostIs | {
210
+ static move |_begin : PostIs | {
212
211
let mut injection = PreIs :: inject ( Begin ) ;
212
+ let mut pinned = pin ! ( g) ;
213
213
loop {
214
- // safety: im 90% sure that since we are inside Coroutine::resume which takes
215
- // Pin<&mut self>, all locals in this function are effectively pinned and this call is
216
- // simply projecting that
217
- let pinned = unsafe { Pin :: new_unchecked ( & mut g) } ;
218
- match pinned. resume ( injection) {
214
+ match pinned. as_mut ( ) . resume ( injection) {
219
215
CoroutineState :: Yielded ( effs) => match effs. subset ( ) {
220
216
Ok ( effs) => match handler ( effs) {
221
217
ControlFlow :: Continue ( injs) => injection = injs. embed ( ) ,
@@ -238,18 +234,16 @@ where
238
234
/// because it is impossible to construct a computation that is both asynchronous and effectful.
239
235
///
240
236
/// For more flexible interactions with Futures, see [`effects::future`].
241
- pub async fn handle_async < Eff , G , Fut > ( mut g : G , mut handler : impl FnMut ( Eff ) -> Fut ) -> G :: Return
237
+ pub async fn handle_async < Eff , G , Fut > ( g : G , mut handler : impl FnMut ( Eff ) -> Fut ) -> G :: Return
242
238
where
243
239
Eff : Effect ,
244
240
G : Coroutine < Coprod ! ( Tagged <Eff :: Injection , Eff >, Begin ) , Yield = Coprod ! ( Eff ) > ,
245
241
Fut : Future < Output = ControlFlow < G :: Return , Eff :: Injection > > ,
246
242
{
247
243
let mut injs = Coproduct :: inject ( Begin ) ;
244
+ let mut pinned = pin ! ( g) ;
248
245
loop {
249
- // safety: see handle_group() - remember that futures are pinned in the same way as
250
- // coroutines
251
- let pinned = unsafe { Pin :: new_unchecked ( & mut g) } ;
252
- match pinned. resume ( injs) {
246
+ match pinned. as_mut ( ) . resume ( injs) {
253
247
CoroutineState :: Yielded ( effs) => {
254
248
let eff = match effs {
255
249
Coproduct :: Inl ( v) => v,
@@ -285,11 +279,9 @@ where
285
279
Fut : Future < Output = ControlFlow < G :: Return , Is > > ,
286
280
{
287
281
let mut injs = Is :: inject ( Begin ) ;
282
+ let mut pinned = pin ! ( g) ;
288
283
loop {
289
- // safety: see handle_group() - remember that futures are pinned in the same way as
290
- // coroutines
291
- let pinned = unsafe { Pin :: new_unchecked ( & mut g) } ;
292
- match pinned. resume ( injs) {
284
+ match pinned. as_mut ( ) . resume ( injs) {
293
285
CoroutineState :: Yielded ( effs) => match handler ( effs) . await {
294
286
ControlFlow :: Continue ( new_injs) => injs = new_injs,
295
287
ControlFlow :: Break ( ret) => return ret,
@@ -329,7 +321,7 @@ pub fn transform<
329
321
EmbedIndices2 ,
330
322
EmbedIndices3 ,
331
323
> (
332
- mut g : G1 ,
324
+ g : G1 ,
333
325
mut handler : impl FnMut ( E ) -> H ,
334
326
) -> impl Coroutine < PostIs , Yield = PostEs , Return = R >
335
327
where
@@ -350,21 +342,18 @@ where
350
342
> + CoproductSubsetter < HandlerIs , SubsetIndices2 > ,
351
343
G1 : Coroutine < PreIs , Yield = PreEs , Return = R > ,
352
344
{
353
- move |_begin : PostIs | {
345
+ static move |_begin : PostIs | {
354
346
let mut injection = PreIs :: inject ( Begin ) ;
347
+ let mut pinned = pin ! ( g) ;
355
348
loop {
356
- // safety: see handle_group()
357
- let pinned = unsafe { Pin :: new_unchecked ( & mut g) } ;
358
- match pinned. resume ( injection) {
349
+ match pinned. as_mut ( ) . resume ( injection) {
359
350
CoroutineState :: Yielded ( effs) => match effs. uninject ( ) {
360
351
// the effect we are handling
361
352
Ok ( eff) => {
362
- let mut handling = handler ( eff) ;
353
+ let mut handling = pin ! ( handler( eff) ) ;
363
354
let mut handler_inj = HandlerIs :: inject ( Begin ) ;
364
355
' run_handler: loop {
365
- // safety: same again
366
- let pinned = unsafe { Pin :: new_unchecked ( & mut handling) } ;
367
- match pinned. resume ( handler_inj) {
356
+ match handling. as_mut ( ) . resume ( handler_inj) {
368
357
CoroutineState :: Yielded ( effs) => {
369
358
handler_inj = PostIs :: subset ( yield effs. embed ( ) ) . ok ( ) . unwrap ( ) ;
370
359
} ,
0 commit comments