Skip to content

Commit bb14428

Browse files
committed
Fix generator transform bug rust-lang#69039
1 parent 61d9231 commit bb14428

File tree

4 files changed

+28
-17
lines changed

4 files changed

+28
-17
lines changed

src/librustc/mir/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,21 +1468,21 @@ impl<'tcx> TerminatorKind<'tcx> {
14681468
/// successors, which may be rendered differently between the text and the graphviz format.
14691469
pub fn fmt_head<W: Write>(&self, fmt: &mut W) -> fmt::Result {
14701470
use self::TerminatorKind::*;
1471-
match *self {
1471+
match self {
14721472
Goto { .. } => write!(fmt, "goto"),
1473-
SwitchInt { discr: ref place, .. } => write!(fmt, "switchInt({:?})", place),
1473+
SwitchInt { discr, .. } => write!(fmt, "switchInt({:?})", discr),
14741474
Return => write!(fmt, "return"),
14751475
GeneratorDrop => write!(fmt, "generator_drop"),
14761476
Resume => write!(fmt, "resume"),
14771477
Abort => write!(fmt, "abort"),
1478-
Yield { ref value, .. } => write!(fmt, "_1 = suspend({:?})", value),
1478+
Yield { value, resume_arg, .. } => write!(fmt, "{:?} = yield({:?})", resume_arg, value),
14791479
Unreachable => write!(fmt, "unreachable"),
1480-
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
1481-
DropAndReplace { ref location, ref value, .. } => {
1480+
Drop { location, .. } => write!(fmt, "drop({:?})", location),
1481+
DropAndReplace { location, value, .. } => {
14821482
write!(fmt, "replace({:?} <- {:?})", location, value)
14831483
}
1484-
Call { ref func, ref args, ref destination, .. } => {
1485-
if let Some((ref destination, _)) = *destination {
1484+
Call { func, args, destination, .. } => {
1485+
if let Some((destination, _)) = destination {
14861486
write!(fmt, "{:?} = ", destination)?;
14871487
}
14881488
write!(fmt, "{:?}(", func)?;
@@ -1494,7 +1494,7 @@ impl<'tcx> TerminatorKind<'tcx> {
14941494
}
14951495
write!(fmt, ")")
14961496
}
1497-
Assert { ref cond, expected, ref msg, .. } => {
1497+
Assert { cond, expected, msg, .. } => {
14981498
write!(fmt, "assert(")?;
14991499
if !expected {
15001500
write!(fmt, "!")?;

src/librustc_mir/dataflow/impls/storage_liveness.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,12 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
139139

140140
fn before_terminator_effect(&self, sets: &mut GenKillSet<Local>, loc: Location) {
141141
self.check_for_borrow(sets, loc);
142-
143-
if let TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. } =
144-
self.body[loc.block].terminator().kind
145-
{
146-
sets.gen(local);
142+
match &self.body[loc.block].terminator().kind {
143+
TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. }
144+
| TerminatorKind::Yield { resume_arg: Place { local, .. }, .. } => {
145+
sets.gen(*local);
146+
}
147+
_ => {}
147148
}
148149
}
149150

src/librustc_mir/transform/generator.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,9 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
283283
_location: Location,
284284
) {
285285
// Replace an Local in the remap with a generator struct access
286+
debug!("generator visit_place {:?}", place);
286287
if let Some(&(ty, variant_index, idx)) = self.remap.get(&place.local) {
288+
debug!("generator visit_place replacing with ({:?}, {:?})", variant_index, idx);
287289
replace_base(place, self.make_field(variant_index, idx, ty), self.tcx);
288290
}
289291
}
@@ -798,6 +800,8 @@ fn compute_layout<'tcx>(
798800

799801
let layout = GeneratorLayout { field_tys: tys, variant_fields, storage_conflicts };
800802

803+
debug!("generator remap = {:?}", remap);
804+
801805
(remap, layout, storage_liveness)
802806
}
803807

@@ -1007,7 +1011,7 @@ fn insert_panic_block<'tcx>(
10071011

10081012
fn create_generator_resume_function<'tcx>(
10091013
tcx: TyCtxt<'tcx>,
1010-
transform: TransformVisitor<'tcx>,
1014+
transform: &TransformVisitor<'tcx>,
10111015
def_id: DefId,
10121016
source: MirSource<'tcx>,
10131017
body: &mut BodyAndCache<'tcx>,
@@ -1121,10 +1125,16 @@ fn create_cases<'tcx>(
11211125
if operation == Operation::Resume {
11221126
// Move the resume argument to the destination place of the `Yield` terminator
11231127
let resume_arg = Local::new(2); // 0 = return, 1 = self
1128+
let dst_place = match transform.remap.get(&point.resume_arg.local) {
1129+
Some(&(ty, variant_index, idx)) => {
1130+
transform.make_field(variant_index, idx, ty)
1131+
}
1132+
None => point.resume_arg,
1133+
};
11241134
statements.push(Statement {
11251135
source_info,
11261136
kind: StatementKind::Assign(box (
1127-
point.resume_arg,
1137+
dst_place,
11281138
Rvalue::Use(Operand::Move(resume_arg.into())),
11291139
)),
11301140
});
@@ -1257,6 +1267,6 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
12571267
body.generator_drop = Some(box drop_shim);
12581268

12591269
// Create the Generator::resume function
1260-
create_generator_resume_function(tcx, transform, def_id, source, body);
1270+
create_generator_resume_function(tcx, &transform, def_id, source, body);
12611271
}
12621272
}

src/test/mir-opt/generator-storage-dead-unwind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn main() {
4949
// StorageLive(_4);
5050
// _4 = Bar(const 6i32,);
5151
// ...
52-
// _1 = suspend(move _6) -> [resume: bb2, drop: bb4];
52+
// _5 = yield(move _6) -> [resume: bb2, drop: bb4];
5353
// }
5454
// bb1 (cleanup): {
5555
// resume;

0 commit comments

Comments
 (0)