@@ -57,6 +57,7 @@ pub(super) fn lower(
57
57
body : Option < ast:: Expr > ,
58
58
krate : CrateId ,
59
59
is_async_fn : bool ,
60
+ is_gen_fn : bool ,
60
61
) -> ( Body , BodySourceMap ) {
61
62
ExprCollector {
62
63
db,
@@ -73,7 +74,7 @@ pub(super) fn lower(
73
74
label_ribs : Vec :: new ( ) ,
74
75
current_binding_owner : None ,
75
76
}
76
- . collect ( params, body, is_async_fn)
77
+ . collect ( params, body, is_async_fn, is_gen_fn )
77
78
}
78
79
79
80
struct ExprCollector < ' a > {
@@ -179,6 +180,7 @@ impl ExprCollector<'_> {
179
180
param_list : Option < ( ast:: ParamList , impl Iterator < Item = bool > ) > ,
180
181
body : Option < ast:: Expr > ,
181
182
is_async_fn : bool ,
183
+ is_gen_fn : bool ,
182
184
) -> ( Body , BodySourceMap ) {
183
185
if let Some ( ( param_list, mut attr_enabled) ) = param_list {
184
186
let mut params = vec ! [ ] ;
@@ -202,23 +204,76 @@ impl ExprCollector<'_> {
202
204
}
203
205
self . body . params = params. into_boxed_slice ( ) ;
204
206
} ;
205
- self . body . body_expr = self . with_label_rib ( RibKind :: Closure , |this| {
206
- if is_async_fn {
207
- match body {
207
+ self . body . body_expr =
208
+ self . with_label_rib ( RibKind :: Closure , |this| match ( is_async_fn, is_gen_fn) {
209
+ ( false , false ) => this. collect_expr_opt ( body) ,
210
+ // gen fn
211
+ ( false , true ) => match body {
208
212
Some ( e) => {
209
- let syntax_ptr = AstPtr :: new ( & e) ;
210
213
let expr = this. collect_expr ( e) ;
211
- this. alloc_expr_desugared_with_ptr (
212
- Expr :: Async { id : None , statements : Box :: new ( [ ] ) , tail : Some ( expr) } ,
213
- syntax_ptr,
214
- )
214
+
215
+ this. alloc_expr_desugared ( Expr :: Closure {
216
+ args : Box :: new ( [ ] ) ,
217
+ arg_types : Box :: new ( [ ] ) ,
218
+ ret_type : None , // FIXME maybe unspecified?
219
+ body : expr,
220
+ closure_kind : ClosureKind :: Coroutine (
221
+ crate :: hir:: CoroutineKind :: Desugared (
222
+ crate :: hir:: CoroutineDesugaring :: Gen ,
223
+ crate :: hir:: CoroutineSource :: Fn ,
224
+ ) ,
225
+ Movability :: Movable ,
226
+ ) ,
227
+ capture_by : CaptureBy :: Ref ,
228
+ } )
215
229
}
216
230
None => this. missing_expr ( ) ,
217
- }
218
- } else {
219
- this. collect_expr_opt ( body)
220
- }
221
- } ) ;
231
+ } ,
232
+ // async fn
233
+ ( true , false ) => match body {
234
+ Some ( e) => {
235
+ let expr = this. collect_expr ( e) ;
236
+
237
+ this. alloc_expr_desugared ( Expr :: Closure {
238
+ args : Box :: new ( [ ] ) ,
239
+ arg_types : Box :: new ( [ ] ) ,
240
+ ret_type : None , // FIXME maybe unspecified?
241
+ body : expr,
242
+ closure_kind : ClosureKind :: Coroutine (
243
+ crate :: hir:: CoroutineKind :: Desugared (
244
+ crate :: hir:: CoroutineDesugaring :: Async ,
245
+ crate :: hir:: CoroutineSource :: Fn ,
246
+ ) ,
247
+ Movability :: Movable ,
248
+ ) ,
249
+ capture_by : CaptureBy :: Ref ,
250
+ } )
251
+ }
252
+ None => this. missing_expr ( ) ,
253
+ } ,
254
+ // async gen fn
255
+ ( true , true ) => match body {
256
+ Some ( e) => {
257
+ let expr = this. collect_expr ( e) ;
258
+
259
+ this. alloc_expr_desugared ( Expr :: Closure {
260
+ args : Box :: new ( [ ] ) ,
261
+ arg_types : Box :: new ( [ ] ) ,
262
+ ret_type : None , // FIXME maybe unspecified?
263
+ body : expr,
264
+ closure_kind : ClosureKind :: Coroutine (
265
+ crate :: hir:: CoroutineKind :: Desugared (
266
+ crate :: hir:: CoroutineDesugaring :: AsyncGen ,
267
+ crate :: hir:: CoroutineSource :: Fn ,
268
+ ) ,
269
+ Movability :: Movable ,
270
+ ) ,
271
+ capture_by : CaptureBy :: Ref ,
272
+ } )
273
+ }
274
+ None => this. missing_expr ( ) ,
275
+ } ,
276
+ } ) ;
222
277
223
278
( self . body , self . source_map )
224
279
}
@@ -258,6 +313,7 @@ impl ExprCollector<'_> {
258
313
let expr = self . collect_expr_opt ( e. expr ( ) ) ;
259
314
self . alloc_expr ( Expr :: Let { pat, expr } , syntax_ptr)
260
315
}
316
+ // https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast/src/ast.rs#L1430
261
317
ast:: Expr :: BlockExpr ( e) => match e. modifier ( ) {
262
318
Some ( ast:: BlockModifier :: Try ( _) ) => self . desugar_try_block ( e) ,
263
319
Some ( ast:: BlockModifier :: Unsafe ( _) ) => {
@@ -278,13 +334,76 @@ impl ExprCollector<'_> {
278
334
} )
279
335
} )
280
336
}
337
+ // https://github.com/compiler-errors/rust/blob/closure-kind/compiler/rustc_ast/src/ast.rs#L1430
338
+ // https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L186
281
339
Some ( ast:: BlockModifier :: Async ( _) ) => {
282
340
self . with_label_rib ( RibKind :: Closure , |this| {
283
- this. collect_block_ ( e, |id, statements, tail| Expr :: Async {
284
- id,
285
- statements,
286
- tail,
287
- } )
341
+ let ( result_expr_id, _) = this. initialize_binding_owner ( syntax_ptr) ;
342
+
343
+ let body = this. collect_block ( e) ;
344
+
345
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
346
+ args : Box :: new ( [ ] ) ,
347
+ arg_types : Box :: new ( [ ] ) ,
348
+ ret_type : None , // FIXME maybe unspecified?
349
+ body,
350
+ closure_kind : ClosureKind :: Coroutine (
351
+ crate :: hir:: CoroutineKind :: Desugared (
352
+ crate :: hir:: CoroutineDesugaring :: Async ,
353
+ crate :: hir:: CoroutineSource :: Block ,
354
+ ) ,
355
+ Movability :: Movable ,
356
+ ) ,
357
+ capture_by : CaptureBy :: Ref ,
358
+ } ;
359
+
360
+ result_expr_id
361
+ } )
362
+ }
363
+ Some ( ast:: BlockModifier :: Gen ( _) ) => self . with_label_rib ( RibKind :: Closure , |this| {
364
+ let ( result_expr_id, _) = this. initialize_binding_owner ( syntax_ptr) ;
365
+
366
+ let body = this. collect_block ( e) ;
367
+
368
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
369
+ args : Box :: new ( [ ] ) ,
370
+ arg_types : Box :: new ( [ ] ) ,
371
+ ret_type : None , // FIXME maybe unspecified?
372
+ body,
373
+ closure_kind : ClosureKind :: Coroutine (
374
+ crate :: hir:: CoroutineKind :: Desugared (
375
+ crate :: hir:: CoroutineDesugaring :: Gen ,
376
+ crate :: hir:: CoroutineSource :: Block ,
377
+ ) ,
378
+ Movability :: Movable ,
379
+ ) ,
380
+ capture_by : CaptureBy :: Ref ,
381
+ } ;
382
+
383
+ result_expr_id
384
+ } ) ,
385
+ Some ( ast:: BlockModifier :: AsyncGen ( _) ) => {
386
+ self . with_label_rib ( RibKind :: Closure , |this| {
387
+ let ( result_expr_id, _) = this. initialize_binding_owner ( syntax_ptr) ;
388
+
389
+ let body = this. collect_block ( e) ;
390
+
391
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
392
+ args : Box :: new ( [ ] ) ,
393
+ arg_types : Box :: new ( [ ] ) ,
394
+ ret_type : None , // FIXME maybe unspecified?
395
+ body,
396
+ closure_kind : ClosureKind :: Coroutine (
397
+ crate :: hir:: CoroutineKind :: Desugared (
398
+ crate :: hir:: CoroutineDesugaring :: AsyncGen ,
399
+ crate :: hir:: CoroutineSource :: Block ,
400
+ ) ,
401
+ Movability :: Movable ,
402
+ ) ,
403
+ capture_by : CaptureBy :: Ref ,
404
+ } ;
405
+
406
+ result_expr_id
288
407
} )
289
408
}
290
409
Some ( ast:: BlockModifier :: Const ( _) ) => {
@@ -301,10 +420,7 @@ impl ExprCollector<'_> {
301
420
result_expr_id
302
421
} )
303
422
}
304
- // FIXME
305
- Some ( ast:: BlockModifier :: AsyncGen ( _) ) | Some ( ast:: BlockModifier :: Gen ( _) ) | None => {
306
- self . collect_block ( e)
307
- }
423
+ None => self . collect_block ( e) ,
308
424
} ,
309
425
ast:: Expr :: LoopExpr ( e) => {
310
426
let label = e. label ( ) . map ( |label| self . collect_label ( label) ) ;
@@ -503,6 +619,7 @@ impl ExprCollector<'_> {
503
619
}
504
620
}
505
621
ast:: Expr :: ClosureExpr ( e) => self . with_label_rib ( RibKind :: Closure , |this| {
622
+ // here
506
623
let ( result_expr_id, prev_binding_owner) =
507
624
this. initialize_binding_owner ( syntax_ptr) ;
508
625
let mut args = Vec :: new ( ) ;
@@ -535,9 +652,39 @@ impl ExprCollector<'_> {
535
652
} else {
536
653
Movability :: Movable
537
654
} ;
538
- ClosureKind :: Coroutine ( movability)
655
+ ClosureKind :: Coroutine ( crate :: hir :: CoroutineKind :: Coroutine , movability)
539
656
} else if e. async_token ( ) . is_some ( ) {
540
- ClosureKind :: Async
657
+ // https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L1199 ?
658
+
659
+ let capture_by =
660
+ if e. move_token ( ) . is_some ( ) { CaptureBy :: Value } else { CaptureBy :: Ref } ;
661
+
662
+ let inner = Expr :: Closure {
663
+ args : Box :: new ( [ ] ) ,
664
+ arg_types : Box :: new ( [ ] ) ,
665
+ ret_type : ret_type. clone ( ) ,
666
+ body,
667
+ closure_kind : ClosureKind :: Coroutine (
668
+ crate :: hir:: CoroutineKind :: Desugared (
669
+ crate :: hir:: CoroutineDesugaring :: Async ,
670
+ crate :: hir:: CoroutineSource :: Closure ,
671
+ ) ,
672
+ Movability :: Movable ,
673
+ ) ,
674
+ capture_by,
675
+ } ;
676
+ this. is_lowering_coroutine = prev_is_lowering_coroutine;
677
+ this. current_binding_owner = prev_binding_owner;
678
+ this. current_try_block_label = prev_try_block_label;
679
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
680
+ args : args. into ( ) ,
681
+ arg_types : arg_types. into ( ) ,
682
+ ret_type,
683
+ body : this. alloc_expr_desugared ( inner) ,
684
+ closure_kind : ClosureKind :: Closure ,
685
+ capture_by,
686
+ } ;
687
+ return result_expr_id;
541
688
} else {
542
689
ClosureKind :: Closure
543
690
} ;
0 commit comments