Skip to content

Commit 8901ea2

Browse files
committed
Rebase resume argument projections during state transform
When remapping a resume argument with projections rebase them on top of the new base. The case where resume argument has projections is unusual, but might arise with box syntax where the assignment is performed directly into the box without an intermediate temporary.
1 parent 83f147b commit 8901ea2

File tree

3 files changed

+12
-5
lines changed

3 files changed

+12
-5
lines changed

compiler/rustc_mir_transform/src/generator.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -342,15 +342,16 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
342342
let source_info = data.terminator().source_info;
343343
// We must assign the value first in case it gets declared dead below
344344
data.statements.extend(self.make_state(state_idx, v, source_info));
345-
let state = if let Some((resume, resume_arg)) = resume {
345+
let state = if let Some((resume, mut resume_arg)) = resume {
346346
// Yield
347347
let state = 3 + self.suspension_points.len();
348348

349349
// The resume arg target location might itself be remapped if its base local is
350350
// live across a yield.
351351
let resume_arg =
352352
if let Some(&(ty, variant, idx)) = self.remap.get(&resume_arg.local) {
353-
self.make_field(variant, idx, ty)
353+
replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx);
354+
resume_arg
354355
} else {
355356
resume_arg
356357
};

src/test/ui/generator/yield-in-box.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// run-pass
2-
32
// Test that box-statements with yields in them work.
43

5-
#![feature(generators, box_syntax)]
4+
#![feature(generators, box_syntax, generator_trait)]
5+
use std::pin::Pin;
6+
use std::ops::Generator;
7+
use std::ops::GeneratorState;
68

79
fn main() {
810
let x = 0i32;
@@ -15,4 +17,8 @@ fn main() {
1517
_t => {}
1618
}
1719
};
20+
21+
let mut g = |_| box yield;
22+
assert_eq!(Pin::new(&mut g).resume(1), GeneratorState::Yielded(()));
23+
assert_eq!(Pin::new(&mut g).resume(2), GeneratorState::Complete(box 2));
1824
}

src/test/ui/generator/yield-in-box.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: unused generator that must be used
2-
--> $DIR/yield-in-box.rs:9:5
2+
--> $DIR/yield-in-box.rs:11:5
33
|
44
LL | / || {
55
LL | | let y = 2u32;

0 commit comments

Comments
 (0)