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