rust/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
Tomasz Miąsko ef1831a21f End locals' live range before suspending coroutine
State transforms retains storage statements for locals that are not
stored inside a coroutine. It ensures those locals are live when
resuming by inserting StorageLive as appropriate. It forgot to end the
storage of those locals when suspending, which is fixed here.

While the end of live range is implicit when executing return, it is
nevertheless useful for inliner which would otherwise extend the live
range beyond return.
2023-12-11 23:11:20 +01:00

128 lines
3.5 KiB
Diff

- // MIR for `main` before Inline
+ // MIR for `main` after Inline
fn main() -> () {
let mut _0: ();
let _1: std::ops::CoroutineState<i32, bool>;
let mut _2: std::pin::Pin<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>;
let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8};
let mut _4: {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8};
+ let mut _5: bool;
scope 1 {
debug _r => _1;
}
+ scope 2 (inlined g) {
+ }
+ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new) {
+ debug pointer => _3;
+ scope 4 {
+ scope 5 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
+ debug pointer => _3;
+ }
+ }
+ }
+ scope 6 (inlined g::{closure#0}) {
+ debug a => _5;
+ let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8};
+ let mut _7: u32;
+ let mut _8: i32;
+ }
bb0: {
StorageLive(_1);
StorageLive(_2);
StorageLive(_3);
StorageLive(_4);
- _4 = g() -> [return: bb1, unwind continue];
+ _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)};
+ _3 = &mut _4;
+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: move _3 };
+ StorageDead(_3);
+ StorageLive(_5);
+ _5 = const false;
+ StorageLive(_6);
+ StorageLive(_7);
+ _6 = (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8});
+ _7 = discriminant((*_6));
+ switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
}
bb1: {
- _3 = &mut _4;
- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5];
+ StorageDead(_4);
+ _0 = const ();
+ StorageDead(_1);
+ return;
}
- bb2: {
- StorageDead(_3);
- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
+ bb2 (cleanup): {
+ drop(_4) -> [return: bb3, unwind terminate(cleanup)];
}
- bb3: {
- StorageDead(_2);
- drop(_4) -> [return: bb4, unwind: bb6];
+ bb3 (cleanup): {
+ resume;
}
bb4: {
- StorageDead(_4);
- _0 = const ();
- StorageDead(_1);
- return;
+ StorageDead(_7);
+ StorageDead(_6);
+ StorageDead(_5);
+ StorageDead(_2);
+ drop(_4) -> [return: bb1, unwind: bb3];
}
- bb5 (cleanup): {
- drop(_4) -> [return: bb6, unwind terminate(cleanup)];
+ bb5: {
+ StorageLive(_8);
+ switchInt(_5) -> [0: bb6, otherwise: bb7];
}
- bb6 (cleanup): {
- resume;
+ bb6: {
+ _8 = const 13_i32;
+ goto -> bb8;
+ }
+
+ bb7: {
+ _8 = const 7_i32;
+ goto -> bb8;
+ }
+
+ bb8: {
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
+ StorageDead(_8);
+ discriminant((*_6)) = 3;
+ goto -> bb4;
+ }
+
+ bb9: {
+ assert(const false, "coroutine resumed after completion") -> [success: bb9, unwind: bb2];
+ }
+
+ bb10: {
+ StorageLive(_8);
+ StorageDead(_8);
+ _1 = CoroutineState::<i32, bool>::Complete(_5);
+ discriminant((*_6)) = 1;
+ goto -> bb4;
+ }
+
+ bb11: {
+ unreachable;
}
}