@@ -59,6 +59,7 @@ pub(super) fn lower(
59
59
body : Option < ast:: Expr > ,
60
60
krate : CrateId ,
61
61
is_async_fn : bool ,
62
+ is_gen_fn : bool ,
62
63
) -> ( Body , BodySourceMap ) {
63
64
ExprCollector {
64
65
db,
@@ -85,7 +86,7 @@ pub(super) fn lower(
85
86
label_ribs : Vec :: new ( ) ,
86
87
current_binding_owner : None ,
87
88
}
88
- . collect ( params, body, is_async_fn)
89
+ . collect ( params, body, is_async_fn, is_gen_fn )
89
90
}
90
91
91
92
struct ExprCollector < ' a > {
@@ -191,6 +192,7 @@ impl ExprCollector<'_> {
191
192
param_list : Option < ( ast:: ParamList , impl Iterator < Item = bool > ) > ,
192
193
body : Option < ast:: Expr > ,
193
194
is_async_fn : bool ,
195
+ is_gen_fn : bool ,
194
196
) -> ( Body , BodySourceMap ) {
195
197
if let Some ( ( param_list, mut attr_enabled) ) = param_list {
196
198
if let Some ( self_param) =
@@ -212,23 +214,73 @@ impl ExprCollector<'_> {
212
214
self . body . params . push ( param_pat) ;
213
215
}
214
216
} ;
215
- self . body . body_expr = self . with_label_rib ( RibKind :: Closure , |this| {
216
- if is_async_fn {
217
- match body {
217
+ self . body . body_expr =
218
+ self . with_label_rib ( RibKind :: Closure , |this| match ( is_async_fn, is_gen_fn) {
219
+ ( false , false ) => this. collect_expr_opt ( body) ,
220
+ ( false , true ) => match body {
218
221
Some ( e) => {
219
222
let expr = this. collect_expr ( e) ;
220
- this. alloc_expr_desugared ( Expr :: Async {
221
- id : None ,
222
- statements : Box :: new ( [ ] ) ,
223
- tail : Some ( expr) ,
223
+
224
+ this. alloc_expr_desugared ( Expr :: Closure {
225
+ args : Box :: new ( [ ] ) ,
226
+ arg_types : Box :: new ( [ ] ) ,
227
+ ret_type : None , // FIXME maybe unspecified?
228
+ body : expr,
229
+ closure_kind : ClosureKind :: Coroutine (
230
+ crate :: hir:: CoroutineKind :: Desugared (
231
+ crate :: hir:: CoroutineDesugaring :: Gen ,
232
+ crate :: hir:: CoroutineSource :: Fn ,
233
+ ) ,
234
+ Movability :: Movable ,
235
+ ) ,
236
+ capture_by : CaptureBy :: Ref ,
224
237
} )
225
238
}
226
239
None => this. missing_expr ( ) ,
227
- }
228
- } else {
229
- this. collect_expr_opt ( body)
230
- }
231
- } ) ;
240
+ } ,
241
+ ( true , false ) => match body {
242
+ Some ( e) => {
243
+ let expr = this. collect_expr ( e) ;
244
+
245
+ this. alloc_expr_desugared ( Expr :: Closure {
246
+ args : Box :: new ( [ ] ) ,
247
+ arg_types : Box :: new ( [ ] ) ,
248
+ ret_type : None , // FIXME maybe unspecified?
249
+ body : expr,
250
+ closure_kind : ClosureKind :: Coroutine (
251
+ crate :: hir:: CoroutineKind :: Desugared (
252
+ crate :: hir:: CoroutineDesugaring :: Async ,
253
+ crate :: hir:: CoroutineSource :: Fn ,
254
+ ) ,
255
+ Movability :: Movable ,
256
+ ) ,
257
+ capture_by : CaptureBy :: Ref ,
258
+ } )
259
+ }
260
+ None => this. missing_expr ( ) ,
261
+ } ,
262
+ ( true , true ) => match body {
263
+ Some ( e) => {
264
+ let expr = this. collect_expr ( e) ;
265
+
266
+ this. alloc_expr_desugared ( Expr :: Closure {
267
+ args : Box :: new ( [ ] ) ,
268
+ arg_types : Box :: new ( [ ] ) ,
269
+ ret_type : None , // FIXME maybe unspecified?
270
+ body : expr,
271
+ closure_kind : ClosureKind :: Coroutine (
272
+ crate :: hir:: CoroutineKind :: Desugared (
273
+ crate :: hir:: CoroutineDesugaring :: AsyncGen ,
274
+ crate :: hir:: CoroutineSource :: Fn ,
275
+ ) ,
276
+ Movability :: Movable ,
277
+ ) ,
278
+ capture_by : CaptureBy :: Ref ,
279
+ } )
280
+ }
281
+ None => this. missing_expr ( ) ,
282
+ } ,
283
+ } ) ;
232
284
233
285
( self . body , self . source_map )
234
286
}
@@ -268,6 +320,7 @@ impl ExprCollector<'_> {
268
320
let expr = self . collect_expr_opt ( e. expr ( ) ) ;
269
321
self . alloc_expr ( Expr :: Let { pat, expr } , syntax_ptr)
270
322
}
323
+ // https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast/src/ast.rs#L1430
271
324
ast:: Expr :: BlockExpr ( e) => match e. modifier ( ) {
272
325
Some ( ast:: BlockModifier :: Try ( _) ) => self . desugar_try_block ( e) ,
273
326
Some ( ast:: BlockModifier :: Unsafe ( _) ) => {
@@ -288,13 +341,76 @@ impl ExprCollector<'_> {
288
341
} )
289
342
} )
290
343
}
344
+ // https://github.com/compiler-errors/rust/blob/closure-kind/compiler/rustc_ast/src/ast.rs#L1430
345
+ // https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L186
291
346
Some ( ast:: BlockModifier :: Async ( _) ) => {
292
347
self . with_label_rib ( RibKind :: Closure , |this| {
293
- this. collect_block_ ( e, |id, statements, tail| Expr :: Async {
294
- id,
295
- statements,
296
- tail,
297
- } )
348
+ let ( result_expr_id, _) = this. initialize_binding_owner ( syntax_ptr) ;
349
+
350
+ let body = this. collect_block ( e) ;
351
+
352
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
353
+ args : Box :: new ( [ ] ) ,
354
+ arg_types : Box :: new ( [ ] ) ,
355
+ ret_type : None , // FIXME maybe unspecified?
356
+ body,
357
+ closure_kind : ClosureKind :: Coroutine (
358
+ crate :: hir:: CoroutineKind :: Desugared (
359
+ crate :: hir:: CoroutineDesugaring :: Async ,
360
+ crate :: hir:: CoroutineSource :: Block ,
361
+ ) ,
362
+ Movability :: Movable ,
363
+ ) ,
364
+ capture_by : CaptureBy :: Ref ,
365
+ } ;
366
+
367
+ result_expr_id
368
+ } )
369
+ }
370
+ Some ( ast:: BlockModifier :: Gen ( _) ) => self . with_label_rib ( RibKind :: Closure , |this| {
371
+ let ( result_expr_id, _) = this. initialize_binding_owner ( syntax_ptr) ;
372
+
373
+ let body = this. collect_block ( e) ;
374
+
375
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
376
+ args : Box :: new ( [ ] ) ,
377
+ arg_types : Box :: new ( [ ] ) ,
378
+ ret_type : None , // FIXME maybe unspecified?
379
+ body,
380
+ closure_kind : ClosureKind :: Coroutine (
381
+ crate :: hir:: CoroutineKind :: Desugared (
382
+ crate :: hir:: CoroutineDesugaring :: Gen ,
383
+ crate :: hir:: CoroutineSource :: Block ,
384
+ ) ,
385
+ Movability :: Movable ,
386
+ ) ,
387
+ capture_by : CaptureBy :: Ref ,
388
+ } ;
389
+
390
+ result_expr_id
391
+ } ) ,
392
+ Some ( ast:: BlockModifier :: AsyncGen ( _) ) => {
393
+ self . with_label_rib ( RibKind :: Closure , |this| {
394
+ let ( result_expr_id, _) = this. initialize_binding_owner ( syntax_ptr) ;
395
+
396
+ let body = this. collect_block ( e) ;
397
+
398
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
399
+ args : Box :: new ( [ ] ) ,
400
+ arg_types : Box :: new ( [ ] ) ,
401
+ ret_type : None , // FIXME maybe unspecified?
402
+ body,
403
+ closure_kind : ClosureKind :: Coroutine (
404
+ crate :: hir:: CoroutineKind :: Desugared (
405
+ crate :: hir:: CoroutineDesugaring :: AsyncGen ,
406
+ crate :: hir:: CoroutineSource :: Block ,
407
+ ) ,
408
+ Movability :: Movable ,
409
+ ) ,
410
+ capture_by : CaptureBy :: Ref ,
411
+ } ;
412
+
413
+ result_expr_id
298
414
} )
299
415
}
300
416
Some ( ast:: BlockModifier :: Const ( _) ) => {
@@ -504,6 +620,7 @@ impl ExprCollector<'_> {
504
620
}
505
621
}
506
622
ast:: Expr :: ClosureExpr ( e) => self . with_label_rib ( RibKind :: Closure , |this| {
623
+ // here
507
624
let ( result_expr_id, prev_binding_owner) =
508
625
this. initialize_binding_owner ( syntax_ptr) ;
509
626
let mut args = Vec :: new ( ) ;
@@ -536,9 +653,39 @@ impl ExprCollector<'_> {
536
653
} else {
537
654
Movability :: Movable
538
655
} ;
539
- ClosureKind :: Coroutine ( movability)
656
+ ClosureKind :: Coroutine ( crate :: hir :: CoroutineKind :: Coroutine , movability)
540
657
} else if e. async_token ( ) . is_some ( ) {
541
- ClosureKind :: Async
658
+ // https://github.com/compiler-errors/rust/blob/bd0eec74026d5f967afeadc3611bdb674a7b9de4/compiler/rustc_ast_lowering/src/expr.rs#L1199 ?
659
+
660
+ let capture_by =
661
+ if e. move_token ( ) . is_some ( ) { CaptureBy :: Value } else { CaptureBy :: Ref } ;
662
+
663
+ let inner = Expr :: Closure {
664
+ args : Box :: new ( [ ] ) ,
665
+ arg_types : Box :: new ( [ ] ) ,
666
+ ret_type : ret_type. clone ( ) ,
667
+ body,
668
+ closure_kind : ClosureKind :: Coroutine (
669
+ crate :: hir:: CoroutineKind :: Desugared (
670
+ crate :: hir:: CoroutineDesugaring :: Async ,
671
+ crate :: hir:: CoroutineSource :: Closure ,
672
+ ) ,
673
+ Movability :: Movable ,
674
+ ) ,
675
+ capture_by,
676
+ } ;
677
+ this. is_lowering_coroutine = prev_is_lowering_coroutine;
678
+ this. current_binding_owner = prev_binding_owner;
679
+ this. current_try_block_label = prev_try_block_label;
680
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
681
+ args : args. into ( ) ,
682
+ arg_types : arg_types. into ( ) ,
683
+ ret_type,
684
+ body : this. alloc_expr_desugared ( inner) ,
685
+ closure_kind : ClosureKind :: Closure ,
686
+ capture_by,
687
+ } ;
688
+ return result_expr_id;
542
689
} else {
543
690
ClosureKind :: Closure
544
691
} ;
0 commit comments