@@ -249,18 +249,34 @@ struct TransformVisitor<'tcx> {
249
249
}
250
250
251
251
impl < ' 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 (
258
277
& self ,
259
- val : Operand < ' tcx > ,
260
- source_info : SourceInfo ,
261
278
is_return : bool ,
262
- statements : & mut Vec < Statement < ' tcx > > ,
263
- ) {
279
+ ) -> ( AggregateKind < ' tcx > , VariantIdx ) {
264
280
let idx = VariantIdx :: new ( match ( is_return, self . coroutine_kind ) {
265
281
( true , hir:: CoroutineKind :: Coroutine ) => 1 , // CoroutineState::Complete
266
282
( false , hir:: CoroutineKind :: Coroutine ) => 0 , // CoroutineState::Yielded
@@ -271,6 +287,22 @@ impl<'tcx> TransformVisitor<'tcx> {
271
287
} ) ;
272
288
273
289
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) ;
274
306
275
307
match self . coroutine_kind {
276
308
// `Poll::Pending`
@@ -1285,10 +1317,13 @@ fn create_coroutine_resume_function<'tcx>(
1285
1317
}
1286
1318
1287
1319
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) ) ;
1292
1327
}
1293
1328
1294
1329
insert_switch ( body, cases, & transform, TerminatorKind :: Unreachable ) ;
0 commit comments