Skip to content

Commit fb00c01

Browse files
committed
Do not renumber resume local.
1 parent 697692a commit fb00c01

12 files changed

+201
-228
lines changed

compiler/rustc_mir_transform/src/coroutine.rs

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,12 +1342,11 @@ fn create_cases<'tcx>(
13421342

13431343
if operation == Operation::Resume {
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

14411440
impl<'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;

tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// MIR for `a::{closure#0}` 0 coroutine_drop_async
22

33
fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>) -> Poll<()> {
4-
debug _task_context => _19;
4+
debug _task_context => _2;
55
debug x => ((*(_1.0: &mut {async fn body of a<T>()})).0: T);
66
let mut _0: std::task::Poll<()>;
77
let _3: T;
@@ -20,15 +20,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
2020
let mut _16: &mut impl std::future::Future<Output = ()>;
2121
let mut _17: std::pin::Pin<&mut impl std::future::Future<Output = ()>>;
2222
let mut _18: isize;
23-
let mut _19: &mut std::task::Context<'_>;
24-
let mut _20: u32;
23+
let mut _19: u32;
2524
scope 1 {
2625
debug x => (((*(_1.0: &mut {async fn body of a<T>()})) as variant#4).0: T);
2726
}
2827

2928
bb0: {
30-
_20 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
31-
switchInt(move _20) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14];
29+
_19 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
30+
switchInt(move _19) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14];
3231
}
3332

3433
bb1: {

tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// MIR for `a::{closure#0}` 0 coroutine_drop_async
22

33
fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>) -> Poll<()> {
4-
debug _task_context => _19;
4+
debug _task_context => _2;
55
debug x => ((*(_1.0: &mut {async fn body of a<T>()})).0: T);
66
let mut _0: std::task::Poll<()>;
77
let _3: T;
@@ -20,15 +20,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
2020
let mut _16: &mut impl std::future::Future<Output = ()>;
2121
let mut _17: std::pin::Pin<&mut impl std::future::Future<Output = ()>>;
2222
let mut _18: isize;
23-
let mut _19: &mut std::task::Context<'_>;
24-
let mut _20: u32;
23+
let mut _19: u32;
2524
scope 1 {
2625
debug x => (((*(_1.0: &mut {async fn body of a<T>()})) as variant#4).0: T);
2726
}
2827

2928
bb0: {
30-
_20 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
31-
switchInt(move _20) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19];
29+
_19 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
30+
switchInt(move _19) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19];
3231
}
3332

3433
bb1: {

tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,17 @@
1010
} */
1111

1212
fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> {
13-
debug _task_context => _4;
13+
debug _task_context => _2;
1414
let mut _0: std::task::Poll<()>;
1515
let mut _3: ();
16-
let mut _4: &mut std::task::Context<'_>;
17-
let mut _5: u32;
16+
let mut _4: u32;
1817

1918
bb0: {
20-
_5 = discriminant((*(_1.0: &mut {async fn body of a()})));
21-
switchInt(move _5) -> [0: bb1, 1: bb4, otherwise: bb5];
19+
_4 = discriminant((*(_1.0: &mut {async fn body of a()})));
20+
switchInt(move _4) -> [0: bb1, 1: bb4, otherwise: bb5];
2221
}
2322

2423
bb1: {
25-
_4 = move _2;
2624
_3 = const ();
2725
goto -> bb3;
2826
}

tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
} */
5151

5252
fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> {
53-
debug _task_context => _38;
53+
debug _task_context => _2;
5454
let mut _0: std::task::Poll<()>;
5555
let _3: ();
5656
let mut _4: {async fn body of a()};
@@ -85,8 +85,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
8585
let mut _35: &mut std::task::Context<'_>;
8686
let mut _36: ();
8787
let mut _37: ();
88-
let mut _38: &mut std::task::Context<'_>;
89-
let mut _39: u32;
88+
let mut _38: u32;
9089
scope 1 {
9190
debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()});
9291
let _17: ();
@@ -103,12 +102,11 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
103102
}
104103

105104
bb0: {
106-
_39 = discriminant((*(_1.0: &mut {async fn body of b()})));
107-
switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8];
105+
_38 = discriminant((*(_1.0: &mut {async fn body of b()})));
106+
switchInt(move _38) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8];
108107
}
109108

110109
bb1: {
111-
_38 = move _2;
112110
StorageLive(_3);
113111
StorageLive(_4);
114112
StorageLive(_5);
@@ -143,7 +141,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
143141
StorageLive(_13);
144142
StorageLive(_14);
145143
StorageLive(_15);
146-
_15 = copy _38;
144+
_15 = copy _2;
147145
_14 = move _15;
148146
goto -> bb6;
149147
}
@@ -198,7 +196,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
198196

199197
bb11: {
200198
StorageDead(_20);
201-
_38 = move _19;
199+
_2 = move _19;
202200
StorageDead(_19);
203201
_7 = const ();
204202
goto -> bb4;
@@ -245,7 +243,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
245243
StorageLive(_29);
246244
StorageLive(_30);
247245
StorageLive(_31);
248-
_31 = copy _38;
246+
_31 = copy _2;
249247
_30 = move _31;
250248
goto -> bb18;
251249
}
@@ -295,7 +293,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
295293

296294
bb22: {
297295
StorageDead(_36);
298-
_38 = move _35;
296+
_2 = move _35;
299297
StorageDead(_35);
300298
_7 = const ();
301299
goto -> bb16;

tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,31 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:17:31: 17:44}>, _
3939
let mut _14: &std::panic::Location<'_>;
4040
let _15: &std::panic::Location<'_>;
4141
let mut _16: ();
42-
let _17: std::string::String;
43-
let mut _18: u32;
42+
let mut _17: u32;
43+
let mut _18: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
4444
let mut _19: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
4545
let mut _20: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
4646
let mut _21: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
4747
let mut _22: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
4848
let mut _23: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
4949
let mut _24: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
5050
let mut _25: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
51-
let mut _26: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44};
5251

5352
bb0: {
54-
_19 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
55-
_18 = discriminant((*_19));
56-
switchInt(move _18) -> [0: bb1, 1: bb19, 3: bb17, 4: bb18, otherwise: bb20];
53+
_18 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
54+
_17 = discriminant((*_18));
55+
switchInt(move _17) -> [0: bb1, 1: bb19, 3: bb17, 4: bb18, otherwise: bb20];
5756
}
5857

5958
bb1: {
60-
_20 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
61-
(((*_20) as variant#4).0: std::string::String) = move _2;
59+
_19 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
60+
(((*_19) as variant#4).0: std::string::String) = move _2;
6261
StorageLive(_3);
6362
StorageLive(_4);
6463
StorageLive(_5);
6564
StorageLive(_6);
66-
_21 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
67-
_6 = &(((*_21) as variant#4).0: std::string::String);
65+
_20 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
66+
_6 = &(((*_20) as variant#4).0: std::string::String);
6867
_5 = <String as Clone>::clone(move _6) -> [return: bb2, unwind unreachable];
6968
}
7069

@@ -85,8 +84,8 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:17:31: 17:44}>, _
8584
_0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4);
8685
StorageDead(_3);
8786
StorageDead(_4);
88-
_22 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
89-
discriminant((*_22)) = 3;
87+
_21 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
88+
discriminant((*_21)) = 3;
9089
return;
9190
}
9291

@@ -109,8 +108,8 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:17:31: 17:44}>, _
109108
_10 = &(*_11);
110109
StorageLive(_12);
111110
StorageLive(_13);
112-
_23 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
113-
_13 = &(((*_23) as variant#4).0: std::string::String);
111+
_22 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
112+
_13 = &(((*_22) as variant#4).0: std::string::String);
114113
_12 = <String as Clone>::clone(move _13) -> [return: bb8, unwind unreachable];
115114
}
116115

@@ -136,8 +135,8 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:17:31: 17:44}>, _
136135
StorageDead(_9);
137136
StorageDead(_11);
138137
StorageDead(_15);
139-
_24 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
140-
discriminant((*_24)) = 4;
138+
_23 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
139+
discriminant((*_23)) = 4;
141140
return;
142141
}
143142

@@ -155,8 +154,8 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:17:31: 17:44}>, _
155154
StorageDead(_11);
156155
StorageDead(_8);
157156
_16 = const ();
158-
_25 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
159-
drop((((*_25) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable];
157+
_24 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
158+
drop((((*_24) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable];
160159
}
161160

162161
bb14: {
@@ -165,8 +164,8 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:17:31: 17:44}>, _
165164

166165
bb15: {
167166
_0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16);
168-
_26 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
169-
discriminant((*_26)) = 1;
167+
_25 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:17:31: 17:44});
168+
discriminant((*_25)) = 1;
170169
return;
171170
}
172171

0 commit comments

Comments
 (0)