@@ -1340,14 +1340,13 @@ fn create_cases<'tcx>(
13401340 }
13411341 }
13421342
1343- if operation == Operation :: Resume {
1343+ if operation == Operation :: Resume && point . resume_arg != CTX_ARG . into ( ) {
13441344 // Move the resume argument to the destination place of the `Yield` terminator
1345- let resume_arg = CTX_ARG ;
13461345 statements. push ( Statement :: new (
13471346 source_info,
13481347 StatementKind :: Assign ( Box :: new ( (
13491348 point. resume_arg ,
1350- Rvalue :: Use ( Operand :: Move ( resume_arg . into ( ) ) ) ,
1349+ Rvalue :: Use ( Operand :: Move ( CTX_ARG . into ( ) ) ) ,
13511350 ) ) ) ,
13521351 ) ) ;
13531352 }
@@ -1439,7 +1438,10 @@ fn check_field_tys_sized<'tcx>(
14391438}
14401439
14411440impl < ' tcx > crate :: MirPass < ' tcx > for StateTransform {
1441+ #[ instrument( level = "debug" , skip( self , tcx, body) , ret) ]
14421442 fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
1443+ debug ! ( def_id = ?body. source. def_id( ) ) ;
1444+
14431445 let Some ( old_yield_ty) = body. yield_ty ( ) else {
14441446 // This only applies to coroutines
14451447 return ;
@@ -1518,31 +1520,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
15181520 cleanup_async_drops ( body) ;
15191521 }
15201522
1521- // We also replace the resume argument and insert an `Assign`.
1522- // This is needed because the resume argument `_2` might be live across a `yield`, in which
1523- // case there is no `Assign` to it that the transform can turn into a store to the coroutine
1524- // state. After the yield the slot in the coroutine state would then be uninitialized.
1525- let resume_local = CTX_ARG ;
1526- let resume_ty = body. local_decls [ resume_local] . ty ;
1527- let old_resume_local = replace_local ( resume_local, resume_ty, body, tcx) ;
1528-
1529- // When first entering the coroutine, move the resume argument into its old local
1530- // (which is now a generator interior).
1531- let source_info = SourceInfo :: outermost ( body. span ) ;
1532- let stmts = & mut body. basic_blocks_mut ( ) [ START_BLOCK ] . statements ;
1533- stmts. insert (
1534- 0 ,
1535- Statement :: new (
1536- source_info,
1537- StatementKind :: Assign ( Box :: new ( (
1538- old_resume_local. into ( ) ,
1539- Rvalue :: Use ( Operand :: Move ( resume_local. into ( ) ) ) ,
1540- ) ) ) ,
1541- ) ,
1542- ) ;
1543-
15441523 let always_live_locals = always_storage_live_locals ( body) ;
1545-
15461524 let movable = coroutine_kind. movability ( ) == hir:: Movability :: Movable ;
15471525 let liveness_info =
15481526 locals_live_across_suspend_points ( tcx, body, & always_live_locals, movable) ;
@@ -1583,6 +1561,21 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
15831561 } ;
15841562 transform. visit_body ( body) ;
15851563
1564+ // MIR parameters are not explicitly assigned-to when entering the MIR body.
1565+ // If we want to save their values inside the coroutine state, we need to do so explicitly.
1566+ let source_info = SourceInfo :: outermost ( body. span ) ;
1567+ let args_iter = body. args_iter ( ) ;
1568+ body. basic_blocks . as_mut ( ) [ START_BLOCK ] . statements . splice (
1569+ 0 ..0 ,
1570+ args_iter. filter_map ( |local| {
1571+ let ( ty, variant_index, idx) = transform. remap [ local] ?;
1572+ let lhs = transform. make_field ( variant_index, idx, ty) ;
1573+ let rhs = Rvalue :: Use ( Operand :: Move ( local. into ( ) ) ) ;
1574+ let assign = StatementKind :: Assign ( Box :: new ( ( lhs, rhs) ) ) ;
1575+ Some ( Statement :: new ( source_info, assign) )
1576+ } ) ,
1577+ ) ;
1578+
15861579 // Update our MIR struct to reflect the changes we've made
15871580 body. arg_count = 2 ; // self, resume arg
15881581 body. spread_arg = None ;
0 commit comments