@@ -249,18 +249,34 @@ struct TransformVisitor<'tcx> {
249249}
250250
251251impl < ' tcx > TransformVisitor < ' tcx > {
252- // Make a `CoroutineState` or `Poll` variant assignment.
253- //
254- // `core::ops::CoroutineState` only has single element tuple variants,
255- // so we can just write to the downcasted first field and then set the
256- // discriminant to the appropriate variant.
257- fn make_state (
252+ fn insert_none_ret_block ( & self , body : & mut Body < ' tcx > ) -> BasicBlock {
253+ let block = BasicBlock :: new ( body. basic_blocks . len ( ) ) ;
254+
255+ let source_info = SourceInfo :: outermost ( body. span ) ;
256+
257+ let ( kind, idx) = self . coroutine_state_adt_and_variant_idx ( true ) ;
258+ assert_eq ! ( self . state_adt_ref. variant( idx) . fields. len( ) , 0 ) ;
259+ let statements = vec ! [ Statement {
260+ kind: StatementKind :: Assign ( Box :: new( (
261+ Place :: return_place( ) ,
262+ Rvalue :: Aggregate ( Box :: new( kind) , IndexVec :: new( ) ) ,
263+ ) ) ) ,
264+ source_info,
265+ } ] ;
266+
267+ body. basic_blocks_mut ( ) . push ( BasicBlockData {
268+ statements,
269+ terminator : Some ( Terminator { source_info, kind : TerminatorKind :: Return } ) ,
270+ is_cleanup : false ,
271+ } ) ;
272+
273+ block
274+ }
275+
276+ fn coroutine_state_adt_and_variant_idx (
258277 & self ,
259- val : Operand < ' tcx > ,
260- source_info : SourceInfo ,
261278 is_return : bool ,
262- statements : & mut Vec < Statement < ' tcx > > ,
263- ) {
279+ ) -> ( AggregateKind < ' tcx > , VariantIdx ) {
264280 let idx = VariantIdx :: new ( match ( is_return, self . coroutine_kind ) {
265281 ( true , hir:: CoroutineKind :: Coroutine ) => 1 , // CoroutineState::Complete
266282 ( false , hir:: CoroutineKind :: Coroutine ) => 0 , // CoroutineState::Yielded
@@ -271,6 +287,22 @@ impl<'tcx> TransformVisitor<'tcx> {
271287 } ) ;
272288
273289 let kind = AggregateKind :: Adt ( self . state_adt_ref . did ( ) , idx, self . state_args , None , None ) ;
290+ ( kind, idx)
291+ }
292+
293+ // Make a `CoroutineState` or `Poll` variant assignment.
294+ //
295+ // `core::ops::CoroutineState` only has single element tuple variants,
296+ // so we can just write to the downcasted first field and then set the
297+ // discriminant to the appropriate variant.
298+ fn make_state (
299+ & self ,
300+ val : Operand < ' tcx > ,
301+ source_info : SourceInfo ,
302+ is_return : bool ,
303+ statements : & mut Vec < Statement < ' tcx > > ,
304+ ) {
305+ let ( kind, idx) = self . coroutine_state_adt_and_variant_idx ( is_return) ;
274306
275307 match self . coroutine_kind {
276308 // `Poll::Pending`
@@ -1285,10 +1317,13 @@ fn create_coroutine_resume_function<'tcx>(
12851317 }
12861318
12871319 if can_return {
1288- cases. insert (
1289- 1 ,
1290- ( RETURNED , insert_panic_block ( tcx, body, ResumedAfterReturn ( coroutine_kind) ) ) ,
1291- ) ;
1320+ let block = match coroutine_kind {
1321+ CoroutineKind :: Async ( _) | CoroutineKind :: Coroutine => {
1322+ insert_panic_block ( tcx, body, ResumedAfterReturn ( coroutine_kind) )
1323+ }
1324+ CoroutineKind :: Gen ( _) => transform. insert_none_ret_block ( body) ,
1325+ } ;
1326+ cases. insert ( 1 , ( RETURNED , block) ) ;
12921327 }
12931328
12941329 insert_switch ( body, cases, & transform, TerminatorKind :: Unreachable ) ;
0 commit comments