@@ -252,15 +252,15 @@ struct TransformVisitor<'tcx> {
252
252
253
253
impl < ' tcx > TransformVisitor < ' tcx > {
254
254
fn insert_none_ret_block ( & self , body : & mut Body < ' tcx > ) -> BasicBlock {
255
- assert ! ( matches!( self . coroutine_kind, CoroutineKind :: Gen ( _) ) ) ;
256
-
257
255
let block = BasicBlock :: new ( body. basic_blocks . len ( ) ) ;
258
256
let source_info = SourceInfo :: outermost ( body. span ) ;
259
- let option_def_id = self . tcx . require_lang_item ( LangItem :: Option , None ) ;
260
257
261
- let statements = vec ! [ Statement {
262
- kind: StatementKind :: Assign ( Box :: new( (
263
- Place :: return_place( ) ,
258
+ let none_value = match self . coroutine_kind {
259
+ CoroutineKind :: Async ( _) => span_bug ! ( body. span, "`Future`s are not fused inherently" ) ,
260
+ CoroutineKind :: Coroutine => span_bug ! ( body. span, "`Coroutine`s cannot be fused" ) ,
261
+ // `gen` continues return `None`
262
+ CoroutineKind :: Gen ( _) => {
263
+ let option_def_id = self . tcx . require_lang_item ( LangItem :: Option , None ) ;
264
264
Rvalue :: Aggregate (
265
265
Box :: new ( AggregateKind :: Adt (
266
266
option_def_id,
@@ -270,8 +270,29 @@ impl<'tcx> TransformVisitor<'tcx> {
270
270
None ,
271
271
) ) ,
272
272
IndexVec :: new ( ) ,
273
- ) ,
274
- ) ) ) ,
273
+ )
274
+ }
275
+ // `async gen` continues to return `Poll::Ready(None)`
276
+ CoroutineKind :: AsyncGen ( _) => {
277
+ let ty:: Adt ( _poll_adt, args) = * self . old_yield_ty . kind ( ) else { bug ! ( ) } ;
278
+ let ty:: Adt ( _option_adt, args) = * args. type_at ( 0 ) . kind ( ) else { bug ! ( ) } ;
279
+ let yield_ty = args. type_at ( 0 ) ;
280
+ Rvalue :: Use ( Operand :: Constant ( Box :: new ( ConstOperand {
281
+ span : source_info. span ,
282
+ const_ : Const :: Unevaluated (
283
+ UnevaluatedConst :: new (
284
+ self . tcx . require_lang_item ( LangItem :: AsyncGenFinished , None ) ,
285
+ self . tcx . mk_args ( & [ yield_ty. into ( ) ] ) ,
286
+ ) ,
287
+ self . old_yield_ty ,
288
+ ) ,
289
+ user_ty : None ,
290
+ } ) ) )
291
+ }
292
+ } ;
293
+
294
+ let statements = vec ! [ Statement {
295
+ kind: StatementKind :: Assign ( Box :: new( ( Place :: return_place( ) , none_value) ) ) ,
275
296
source_info,
276
297
} ] ;
277
298
@@ -1393,11 +1414,12 @@ fn create_coroutine_resume_function<'tcx>(
1393
1414
1394
1415
if can_return {
1395
1416
let block = match coroutine_kind {
1396
- // FIXME(gen_blocks): Should `async gen` yield `None` when resumed once again?
1397
- CoroutineKind :: Async ( _) | CoroutineKind :: AsyncGen ( _) | CoroutineKind :: Coroutine => {
1417
+ CoroutineKind :: Async ( _) | CoroutineKind :: Coroutine => {
1398
1418
insert_panic_block ( tcx, body, ResumedAfterReturn ( coroutine_kind) )
1399
1419
}
1400
- CoroutineKind :: Gen ( _) => transform. insert_none_ret_block ( body) ,
1420
+ CoroutineKind :: AsyncGen ( _) | CoroutineKind :: Gen ( _) => {
1421
+ transform. insert_none_ret_block ( body)
1422
+ }
1401
1423
} ;
1402
1424
cases. insert ( 1 , ( RETURNED , block) ) ;
1403
1425
}
0 commit comments