Closed
Description
The generator
|| {
if { yield; false } {
yield;
loop {}
}
yield
}
produces the following MIR:
fn main::{{closure}}(_1: &mut [generator@src/main.rs:20:15: 26:6 ((), bool)]) -> std::ops::GeneratorState<(), ()> {
let mut _0: std::ops::GeneratorState<(), ()>; // return pointer
let mut _2: ();
let mut _3: bool;
let mut _4: ();
let mut _5: ();
let mut _6: ();
let mut _7: ();
let mut _8: ();
let mut _9: ();
let mut _10: ();
bb0: {
switchInt(((*_1).0: u32)) -> [2u32: bb2, 0u32: bb1, 3u32: bb5, 4u32: bb7, 1u32: bb11, 5u32: bb9, otherwise: bb9]; // scope 0 at src/main.rs:20:15: 26:6
}
bb1: {
StorageLive(_3); // scope 0 at src/main.rs:21:12: 21:28
StorageLive(_5); // scope 0 at src/main.rs:21:14: 21:19
_5 = (); // scope 0 at src/main.rs:21:14: 21:19
((*_1).0: u32) = const 2u32; // scope 0 at src/main.rs:21:14: 21:19
_0 = std::ops::GeneratorState<(), ()>::Yielded(_5,); // scope 0 at src/main.rs:21:14: 21:19
return; // scope 0 at src/main.rs:21:14: 21:19
}
bb2: {
_4 = (); // scope 0 at src/main.rs:21:14: 21:19
StorageDead(_5); // scope 0 at src/main.rs:21:19: 21:19
_3 = const false; // scope 0 at src/main.rs:21:21: 21:26
switchInt(_3) -> [0u8: bb4, otherwise: bb3]; // scope 0 at src/main.rs:21:9: 24:10
}
bb3: {
StorageLive(_7); // scope 0 at src/main.rs:22:13: 22:18
_7 = (); // scope 0 at src/main.rs:22:13: 22:18
((*_1).0: u32) = const 3u32; // scope 0 at src/main.rs:22:13: 22:18
_0 = std::ops::GeneratorState<(), ()>::Yielded(_7,); // scope 0 at src/main.rs:22:13: 22:18
return; // scope 0 at src/main.rs:22:13: 22:18
}
bb4: {
_2 = (); // scope 0 at src/main.rs:21:9: 24:10
StorageDead(_3); // scope 0 at src/main.rs:24:10: 24:10
StorageLive(_9); // scope 0 at src/main.rs:25:9: 25:14
_9 = (); // scope 0 at src/main.rs:25:9: 25:14
((*_1).0: u32) = const 4u32; // scope 0 at src/main.rs:25:9: 25:14
_0 = std::ops::GeneratorState<(), ()>::Yielded(_9,); // scope 0 at src/main.rs:25:9: 25:14
return; // scope 0 at src/main.rs:25:9: 25:14
}
bb5: {
_6 = (); // scope 0 at src/main.rs:22:13: 22:18
StorageDead(_7); // scope 0 at src/main.rs:22:18: 22:18
goto -> bb6; // scope 0 at src/main.rs:23:13: 23:20
}
bb6: {
_8 = (); // scope 0 at src/main.rs:23:18: 23:20
goto -> bb6; // scope 0 at src/main.rs:23:13: 23:20
}
bb7: {
_10 = (); // scope 0 at src/main.rs:25:9: 25:14
StorageDead(_9); // scope 0 at src/main.rs:25:14: 25:14
goto -> bb10; // scope 0 at src/main.rs:26:6: 26:6
}
bb8: {
((*_1).0: u32) = const 5u32; // scope 0 at src/main.rs:26:6: 26:6
_0 = std::ops::GeneratorState<(), ()>::Complete(_10,); // scope 0 at src/main.rs:26:6: 26:6
return; // scope 0 at src/main.rs:26:6: 26:6
}
bb9: {
assert(const false, "generator resumed after completion") -> bb9; // scope 0 at src/main.rs:20:15: 26:6
}
bb10: {
goto -> bb8; // scope 0 at src/main.rs:26:6: 26:6
}
bb11: {
assert(const false, "generator resumed after panicking") -> bb9; // scope 0 at src/main.rs:20:15: 26:6
}
}
Note the assignment to _3
in bb2
, which is not preceded by a StorageLive
in this invocation of the generator.
Full example in the playground: https://play.rust-lang.org/?gist=680d18fb9f9bdc91ab969fdbd8bb72a2&version=nightly
cc @Zoxc