@@ -252,15 +252,15 @@ struct TransformVisitor<'tcx> {
252252
253253impl < ' tcx > TransformVisitor < ' tcx > {
254254 fn insert_none_ret_block ( & self , body : & mut Body < ' tcx > ) -> BasicBlock {
255- assert ! ( matches!( self . coroutine_kind, CoroutineKind :: Gen ( _) ) ) ;
256-
257255 let block = BasicBlock :: new ( body. basic_blocks . len ( ) ) ;
258256 let source_info = SourceInfo :: outermost ( body. span ) ;
259- let option_def_id = self . tcx . require_lang_item ( LangItem :: Option , None ) ;
260257
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 ) ;
264264 Rvalue :: Aggregate (
265265 Box :: new ( AggregateKind :: Adt (
266266 option_def_id,
@@ -270,8 +270,29 @@ impl<'tcx> TransformVisitor<'tcx> {
270270 None ,
271271 ) ) ,
272272 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) ) ) ,
275296 source_info,
276297 } ] ;
277298
@@ -1393,11 +1414,12 @@ fn create_coroutine_resume_function<'tcx>(
13931414
13941415 if can_return {
13951416 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 => {
13981418 insert_panic_block ( tcx, body, ResumedAfterReturn ( coroutine_kind) )
13991419 }
1400- CoroutineKind :: Gen ( _) => transform. insert_none_ret_block ( body) ,
1420+ CoroutineKind :: AsyncGen ( _) | CoroutineKind :: Gen ( _) => {
1421+ transform. insert_none_ret_block ( body)
1422+ }
14011423 } ;
14021424 cases. insert ( 1 , ( RETURNED , block) ) ;
14031425 }
0 commit comments