Skip to content

Commit 3c22e51

Browse files
Make generator transform move resume arg around
The resume arg is passed as argument `_2` and needs to be moved to the `Yield`s target `Place`
1 parent 3c069a0 commit 3c22e51

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

src/librustc_mir/transform/generator.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,10 @@ const RETURNED: usize = GeneratorSubsts::RETURNED;
192192
/// Generator has been poisoned
193193
const POISONED: usize = GeneratorSubsts::POISONED;
194194

195-
struct SuspensionPoint {
195+
struct SuspensionPoint<'tcx> {
196196
state: usize,
197197
resume: BasicBlock,
198+
resume_arg: Place<'tcx>,
198199
drop: Option<BasicBlock>,
199200
storage_liveness: liveness::LiveVarSet,
200201
}
@@ -216,7 +217,7 @@ struct TransformVisitor<'tcx> {
216217
storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet>,
217218

218219
// A list of suspension points, generated during the transform
219-
suspension_points: Vec<SuspensionPoint>,
220+
suspension_points: Vec<SuspensionPoint<'tcx>>,
220221

221222
// The original RETURN_PLACE local
222223
new_ret_local: Local,
@@ -303,8 +304,8 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
303304
Operand::Move(Place::from(self.new_ret_local)),
304305
None,
305306
)),
306-
TerminatorKind::Yield { ref value, resume, drop } => {
307-
Some((VariantIdx::new(0), Some(resume), value.clone(), drop))
307+
TerminatorKind::Yield { ref value, resume, resume_arg, drop } => {
308+
Some((VariantIdx::new(0), Some((resume, resume_arg)), value.clone(), drop))
308309
}
309310
_ => None,
310311
};
@@ -319,13 +320,14 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
319320
self.make_state(state_idx, v),
320321
)),
321322
});
322-
let state = if let Some(resume) = resume {
323+
let state = if let Some((resume, resume_arg)) = resume {
323324
// Yield
324325
let state = 3 + self.suspension_points.len();
325326

326327
self.suspension_points.push(SuspensionPoint {
327328
state,
328329
resume,
330+
resume_arg,
329331
drop,
330332
storage_liveness: self.storage_liveness.get(&block).unwrap().clone(),
331333
});
@@ -1063,7 +1065,7 @@ fn create_cases<'tcx, F>(
10631065
target: F,
10641066
) -> Vec<(usize, BasicBlock)>
10651067
where
1066-
F: Fn(&SuspensionPoint) -> Option<BasicBlock>,
1068+
F: Fn(&SuspensionPoint<'tcx>) -> Option<BasicBlock>,
10671069
{
10681070
let source_info = source_info(body);
10691071

@@ -1085,6 +1087,16 @@ where
10851087
}
10861088
}
10871089

1090+
// Move the resume argument to the destination place of the `Yield` terminator
1091+
let resume_arg = Local::new(2); // 0 = return, 1 = self
1092+
statements.push(Statement {
1093+
source_info,
1094+
kind: StatementKind::Assign(box (
1095+
point.resume_arg,
1096+
Rvalue::Use(Operand::Move(resume_arg.into())),
1097+
)),
1098+
});
1099+
10881100
// Then jump to the real target
10891101
body.basic_blocks_mut().push(BasicBlockData {
10901102
statements,
@@ -1163,7 +1175,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
11631175
};
11641176
transform.visit_body(body);
11651177

1166-
// Update our MIR struct to reflect the changed we've made
1178+
// Update our MIR struct to reflect the changes we've made
11671179
body.yield_ty = None;
11681180
body.arg_count = 2; // self, resume arg
11691181
body.spread_arg = None;

0 commit comments

Comments
 (0)