From 4cafc347936f79b7f8b2e5550fbcfe24bc07a5be Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 15:04:00 +0000 Subject: [PATCH 01/12] Add tests. --- ...closure#0}-{closure#0}.StateTransform.diff | 80 ++ ...losure#0}-{closure#0}.coroutine_drop.0.mir | 36 + ...losure#0}.coroutine_drop_proxy_async.0.mir | 14 + ...ync_fn.add-{closure#0}.StateTransform.diff | 371 ++++++++++ ...nc_fn.add-{closure#0}.coroutine_drop.0.mir | 129 ++++ ...losure#0}.coroutine_drop_proxy_async.0.mir | 24 + ..._aggregate-{closure#0}.StateTransform.diff | 695 ++++++++++++++++++ ...aggregate-{closure#0}.coroutine_drop.0.mir | 217 ++++++ ...losure#0}.coroutine_drop_proxy_async.0.mir | 32 + ...closure#0}-{closure#0}.StateTransform.diff | 80 ++ ...losure#0}-{closure#0}.coroutine_drop.0.mir | 36 + ...losure#0}.coroutine_drop_proxy_async.0.mir | 14 + ...ync_fn.foo-{closure#0}.StateTransform.diff | 432 +++++++++++ ...nc_fn.foo-{closure#0}.coroutine_drop.0.mir | 153 ++++ ...losure#0}.coroutine_drop_proxy_async.0.mir | 34 + ...ello_world-{closure#0}.StateTransform.diff | 453 ++++++++++++ ...llo_world-{closure#0}.coroutine_drop.0.mir | 141 ++++ ...losure#0}.coroutine_drop_proxy_async.0.mir | 24 + ...closure#0}-{closure#0}.StateTransform.diff | 78 ++ ...losure#0}-{closure#0}.coroutine_drop.0.mir | 35 + ...losure#0}.coroutine_drop_proxy_async.0.mir | 14 + ...closure#0}-{closure#1}.StateTransform.diff | 78 ++ ...losure#0}-{closure#1}.coroutine_drop.0.mir | 35 + ...losure#1}.coroutine_drop_proxy_async.0.mir | 14 + ...udes_never-{closure#0}.StateTransform.diff | 412 +++++++++++ ...des_never-{closure#0}.coroutine_drop.0.mir | 155 ++++ ...losure#0}.coroutine_drop_proxy_async.0.mir | 32 + ...closure#0}-{closure#0}.StateTransform.diff | 78 ++ ...losure#0}-{closure#0}.coroutine_drop.0.mir | 35 + ...losure#0}.coroutine_drop_proxy_async.0.mir | 14 + ...rtial_init-{closure#0}.StateTransform.diff | 387 ++++++++++ ...tial_init-{closure#0}.coroutine_drop.0.mir | 131 ++++ ...losure#0}.coroutine_drop_proxy_async.0.mir | 24 + tests/mir-opt/coroutine/async_fn.rs | 139 ++++ ...ed_variant-{closure#0}.StateTransform.diff | 683 +++++++++++++++++ ...d_variant-{closure#0}.coroutine_drop.0.mir | 216 ++++++ ...losure#0}.coroutine_drop_proxy_async.0.mir | 26 + 37 files changed, 5551 insertions(+) create mode 100644 tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.add-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.foo-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.rs create mode 100644 tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop.0.mir create mode 100644 tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..3619637baa1f4 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.StateTransform.diff @@ -0,0 +1,80 @@ +- // MIR for `add::{closure#0}::{closure#0}` before StateTransform ++ // MIR for `add::{closure#0}::{closure#0}` after StateTransform + +- fn add::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:34:13: 34:18}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn add::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ } ++ storage_conflicts = BitMatrix(0x0) {} ++ } + debug _task_context => _2; +- debug x => (*(_1.0: &u32)); +- debug y => (*(_1.1: &u32)); +- let mut _0: u32; ++ debug x => (*((*_9).0: &u32)); ++ debug y => (*((*_9).1: &u32)); ++ let mut _0: std::task::Poll; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; ++ let mut _7: u32; ++ let mut _8: u32; ++ let mut _9: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + + bb0: { +- StorageLive(_3); +- _5 = no_retag copy (_1.0: &u32); +- _3 = copy (*_5); +- StorageLive(_4); +- _6 = no_retag copy (_1.1: &u32); +- _4 = copy (*_6); +- _0 = Add(move _3, move _4); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb1, unwind: bb2]; ++ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}); ++ _8 = discriminant((*_9)); ++ switchInt(move _8) -> [0: bb5, 1: bb3, otherwise: bb4]; + } + + bb1: { ++ _0 = Poll::::Ready(move _7); ++ discriminant((*_9)) = 1; + return; + } + +- bb2 (cleanup): { +- resume; ++ bb2: { ++ goto -> bb1; ++ } ++ ++ bb3: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb3, unwind continue]; ++ } ++ ++ bb4: { ++ unreachable; ++ } ++ ++ bb5: { ++ StorageLive(_3); ++ _5 = no_retag copy ((*_9).0: &u32); ++ _3 = copy (*_5); ++ StorageLive(_4); ++ _6 = no_retag copy ((*_9).1: &u32); ++ _4 = copy (*_6); ++ _7 = Add(move _3, move _4); ++ StorageDead(_4); ++ StorageDead(_3); ++ goto -> bb2; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..0439d4c682755 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,36 @@ +// MIR for `add::{closure#0}::{closure#0}` 0 coroutine_drop + +fn add::{closure#0}::{closure#0}(_1: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}) -> () { + debug _task_context => _2; + debug x => (*((*_1).0: &u32)); + debug y => (*((*_1).1: &u32)); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; + let mut _7: u32; + let mut _8: u32; + + bb0: { + _8 = discriminant((*_1)); + switchInt(move _8) -> [0: bb2, otherwise: bb4]; + } + + bb1: { + return; + } + + bb2: { + goto -> bb3; + } + + bb3: { + goto -> bb1; + } + + bb4: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..0c8f25df081aa --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,14 @@ +// MIR for `add::{closure#0}::{closure#0}` 0 coroutine_drop_proxy_async + +fn add::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:34:13: 34:18}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..472d469984170 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.StateTransform.diff @@ -0,0 +1,371 @@ +- // MIR for `add::{closure#0}` before StateTransform ++ // MIR for `add::{closure#0}` after StateTransform + +- fn add::{closure#0}(_1: {async fn body of add()}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn add::{closure#0}(_1: Pin<&mut {async fn body of add()}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ field _s0: u32; ++ field _s1: u32; ++ field _s2: {async block@$DIR/async_fn.rs:34:13: 34:18}; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s2], ++ } ++ storage_conflicts = BitMatrix(3x3) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s2, _s0), (_s2, _s1), (_s2, _s2)} ++ } + debug _task_context => _2; +- debug x => (_1.0: u32); +- debug y => (_1.1: u32); +- let mut _0: u32; ++ debug x => ((*_27).0: u32); ++ debug y => ((*_27).1: u32); ++ coroutine debug x => _s0; ++ let mut _0: std::task::Poll; + let _3: u32; + let mut _6: &u32; + let mut _7: &u32; + let mut _8: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _9: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _11: (); + let _12: (); + let mut _13: std::task::Poll; + let mut _14: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>; + let mut _15: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _16: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut std::task::Context<'_>; +- let mut _19: std::future::ResumeTy; ++ let mut _19: &mut std::task::Context<'_>; + let mut _20: isize; + let mut _22: !; +- let mut _23: std::future::ResumeTy; ++ let mut _23: &mut std::task::Context<'_>; + let mut _24: (); ++ let mut _25: u32; ++ let mut _26: u32; ++ let mut _27: &mut {async fn body of add()}; + scope 1 { +- debug x => _3; ++ debug x => (((*_27) as variant#3).0: u32); ++ coroutine debug y => _s1; + let _4: u32; + scope 2 { +- debug y => _4; ++ debug y => (((*_27) as variant#3).1: u32); + let _5: {async block@$DIR/async_fn.rs:34:13: 34:18}; + scope 3 { + debug a => _5; ++ coroutine debug __awaitee => _s2; + let mut _10: {async block@$DIR/async_fn.rs:34:13: 34:18}; + scope 4 { +- debug __awaitee => _10; ++ debug __awaitee => (((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18}); + let _21: u32; + scope 5 { + debug result => _21; + } + } + } + } + } + + bb0: { +- StorageLive(_3); +- _3 = copy (_1.0: u32); +- StorageLive(_4); +- _4 = copy (_1.1: u32); +- StorageLive(_5); +- StorageLive(_6); +- _6 = &_3; +- StorageLive(_7); +- _7 = &_4; +- _5 = {coroutine@$DIR/async_fn.rs:34:13: 34:18 (#0)} { x: move _6, y: move _7 }; +- StorageDead(_7); +- StorageDead(_6); +- StorageLive(_8); +- StorageLive(_9); +- _9 = move _5; +- _8 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as IntoFuture>::into_future(move _9) -> [return: bb1, unwind: bb24]; ++ _27 = copy (_1.0: &mut {async fn body of add()}); ++ _26 = discriminant((*_27)); ++ switchInt(move _26) -> [0: bb28, 1: bb27, 2: bb26, 3: bb25, otherwise: bb6]; + } + + bb1: { + StorageDead(_9); + PlaceMention(_8); +- StorageLive(_10); +- _10 = move _8; ++ nop; ++ (((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18}) = move _8; + goto -> bb2; + } + + bb2: { + StorageLive(_12); + StorageLive(_13); + StorageLive(_14); + StorageLive(_15); + StorageLive(_16); +- _16 = &mut _10; ++ _16 = &mut (((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18}); + _15 = &mut (*_16); +- _14 = Pin::<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>::new_unchecked(move _15) -> [return: bb3, unwind: bb21]; ++ _14 = Pin::<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>::new_unchecked(move _15) -> [return: bb3, unwind: bb15]; + } + + bb3: { + StorageDead(_15); + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); + _19 = copy _2; +- _18 = std::future::get_context::<'_, '_>(move _19) -> [return: bb4, unwind: bb19]; ++ _18 = move _19; ++ goto -> bb4; + } + + bb4: { + _17 = &mut (*_18); + StorageDead(_19); +- _13 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as Future>::poll(move _14, move _17) -> [return: bb5, unwind: bb20]; ++ _13 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as Future>::poll(move _14, move _17) -> [return: bb5, unwind: bb14]; + } + + bb5: { + StorageDead(_18); + StorageDead(_17); + StorageDead(_16); + StorageDead(_14); + PlaceMention(_13); + _20 = discriminant(_13); + switchInt(move _20) -> [0: bb8, 1: bb7, otherwise: bb6]; + } + + bb6: { + unreachable; + } + + bb7: { + _12 = const (); + StorageDead(_13); + StorageDead(_12); + StorageLive(_23); + StorageLive(_24); + _24 = (); +- _23 = yield(move _24) -> [resume: bb9, drop: bb14]; ++ _0 = Poll::::Pending; ++ StorageDead(_5); ++ StorageDead(_8); ++ StorageDead(_23); ++ StorageDead(_24); ++ discriminant((*_27)) = 3; ++ return; + } + + bb8: { + StorageLive(_21); + _21 = copy ((_13 as Ready).0: u32); +- _0 = copy _21; ++ _25 = copy _21; + StorageDead(_21); + StorageDead(_13); + StorageDead(_12); +- drop(_10) -> [return: bb10, unwind: bb23]; ++ drop((((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb10, unwind: bb17]; + } + + bb9: { + StorageDead(_24); + _2 = move _23; + StorageDead(_23); + _11 = const (); + goto -> bb2; + } + + bb10: { +- StorageDead(_10); ++ nop; + goto -> bb11; + } + + bb11: { + StorageDead(_8); + goto -> bb12; + } + + bb12: { + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb13, unwind: bb28]; ++ nop; ++ nop; ++ goto -> bb23; + } + + bb13: { ++ _0 = Poll::::Ready(move _25); ++ discriminant((*_27)) = 1; + return; + } + +- bb14: { +- StorageDead(_24); +- StorageDead(_23); +- drop(_10) -> [return: bb15, unwind: bb29]; ++ bb14 (cleanup): { ++ StorageDead(_18); ++ StorageDead(_17); ++ goto -> bb16; + } + +- bb15: { +- StorageDead(_10); ++ bb15 (cleanup): { ++ StorageDead(_15); + goto -> bb16; + } + +- bb16: { +- StorageDead(_8); +- goto -> bb17; ++ bb16 (cleanup): { ++ StorageDead(_16); ++ StorageDead(_14); ++ StorageDead(_13); ++ StorageDead(_12); ++ drop((((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb17, unwind terminate(cleanup)]; + } + +- bb17: { +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb18, unwind: bb28]; ++ bb17 (cleanup): { ++ nop; ++ goto -> bb20; + } + +- bb18: { +- coroutine_drop; ++ bb18 (cleanup): { ++ goto -> bb19; + } + + bb19 (cleanup): { +- StorageDead(_19); ++ StorageDead(_9); + goto -> bb20; + } + + bb20 (cleanup): { +- StorageDead(_18); +- StorageDead(_17); +- goto -> bb22; ++ StorageDead(_8); ++ goto -> bb21; + } + + bb21 (cleanup): { +- StorageDead(_15); ++ StorageDead(_5); ++ nop; ++ nop; + goto -> bb22; + } + + bb22 (cleanup): { +- StorageDead(_16); +- StorageDead(_14); +- StorageDead(_13); +- StorageDead(_12); +- drop(_10) -> [return: bb23, unwind terminate(cleanup)]; ++ goto -> bb24; + } + +- bb23 (cleanup): { +- StorageDead(_10); +- goto -> bb26; ++ bb23: { ++ goto -> bb13; + } + + bb24 (cleanup): { +- goto -> bb25; ++ discriminant((*_27)) = 2; ++ resume; + } + +- bb25 (cleanup): { +- StorageDead(_9); +- goto -> bb26; ++ bb25: { ++ StorageLive(_5); ++ StorageLive(_8); ++ StorageLive(_23); ++ StorageLive(_24); ++ _23 = move _2; ++ goto -> bb9; + } + +- bb26 (cleanup): { +- StorageDead(_8); +- goto -> bb27; ++ bb26: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb26, unwind continue]; + } + +- bb27 (cleanup): { +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb28, unwind terminate(cleanup)]; ++ bb27: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb27, unwind continue]; + } + +- bb28 (cleanup): { +- resume; +- } +- +- bb29 (cleanup): { +- StorageDead(_10); +- goto -> bb30; +- } +- +- bb30 (cleanup): { +- StorageDead(_8); +- goto -> bb31; +- } +- +- bb31 (cleanup): { +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb28, unwind terminate(cleanup)]; ++ bb28: { ++ nop; ++ (((*_27) as variant#3).0: u32) = copy ((*_27).0: u32); ++ nop; ++ (((*_27) as variant#3).1: u32) = copy ((*_27).1: u32); ++ StorageLive(_5); ++ StorageLive(_6); ++ _6 = &(((*_27) as variant#3).0: u32); ++ StorageLive(_7); ++ _7 = &(((*_27) as variant#3).1: u32); ++ _5 = {coroutine@$DIR/async_fn.rs:34:13: 34:18 (#0)} { x: move _6, y: move _7 }; ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageLive(_8); ++ StorageLive(_9); ++ _9 = move _5; ++ _8 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as IntoFuture>::into_future(move _9) -> [return: bb1, unwind: bb18]; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..ecff837e4436f --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,129 @@ +// MIR for `add::{closure#0}` 0 coroutine_drop + +fn add::{closure#0}(_1: &mut {async fn body of add()}) -> () { + debug _task_context => _2; + debug x => ((*_1).0: u32); + debug y => ((*_1).1: u32); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let _3: u32; + let mut _6: &u32; + let mut _7: &u32; + let mut _8: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _9: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _11: (); + let _12: (); + let mut _13: std::task::Poll; + let mut _14: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>; + let mut _15: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _16: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut std::task::Context<'_>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: isize; + let mut _22: !; + let mut _23: &mut std::task::Context<'_>; + let mut _24: (); + let mut _25: u32; + let mut _26: u32; + scope 1 { + debug x => (((*_1) as variant#3).0: u32); + let _4: u32; + scope 2 { + debug y => (((*_1) as variant#3).1: u32); + let _5: {async block@$DIR/async_fn.rs:34:13: 34:18}; + scope 3 { + debug a => _5; + let mut _10: {async block@$DIR/async_fn.rs:34:13: 34:18}; + scope 4 { + debug __awaitee => (((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18}); + let _21: u32; + scope 5 { + debug result => _21; + } + } + } + } + } + + bb0: { + _26 = discriminant((*_1)); + switchInt(move _26) -> [0: bb11, 3: bb14, otherwise: bb15]; + } + + bb1: { + StorageDead(_24); + StorageDead(_23); + drop((((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb2, unwind: bb7]; + } + + bb2: { + nop; + goto -> bb3; + } + + bb3: { + StorageDead(_8); + goto -> bb4; + } + + bb4: { + StorageDead(_5); + nop; + nop; + goto -> bb12; + } + + bb5: { + return; + } + + bb6 (cleanup): { + resume; + } + + bb7 (cleanup): { + nop; + goto -> bb8; + } + + bb8 (cleanup): { + StorageDead(_8); + goto -> bb9; + } + + bb9 (cleanup): { + StorageDead(_5); + nop; + nop; + goto -> bb6; + } + + bb10: { + return; + } + + bb11: { + goto -> bb13; + } + + bb12: { + goto -> bb5; + } + + bb13: { + goto -> bb10; + } + + bb14: { + StorageLive(_5); + StorageLive(_8); + StorageLive(_23); + StorageLive(_24); + goto -> bb1; + } + + bb15: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..c86391c4f729e --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,24 @@ +// MIR for `add::{closure#0}` 0 coroutine_drop_proxy_async + +fn add::{closure#0}(_1: {async fn body of add()}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + scope 1 { + scope 2 { + scope 3 { + scope 4 { + scope 5 { + } + } + } + } + } + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..9a644309798be --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.StateTransform.diff @@ -0,0 +1,695 @@ +- // MIR for `build_aggregate::{closure#0}` before StateTransform ++ // MIR for `build_aggregate::{closure#0}` after StateTransform + +- fn build_aggregate::{closure#0}(_1: {async fn body of build_aggregate()}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn build_aggregate::{closure#0}(_1: Pin<&mut {async fn body of build_aggregate()}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ field _s0: u32; ++ field _s1: u32; ++ field _s2: u32; ++ field _s3: {async fn body of add()}; ++ field _s4: {async fn body of add()}; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s3], ++ Suspend1 (4): [_s2, _s4], ++ } ++ storage_conflicts = BitMatrix(5x5) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s0, _s4), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s1, _s4), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s2, _s4), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3), (_s4, _s0), (_s4, _s1), (_s4, _s2), (_s4, _s4)} ++ } + debug _task_context => _2; +- debug a => (_1.0: u32); +- debug b => (_1.1: u32); +- debug c => (_1.2: u32); +- debug d => (_1.3: u32); +- let mut _0: u32; ++ debug a => ((*_51).0: u32); ++ debug b => ((*_51).1: u32); ++ debug c => ((*_51).2: u32); ++ debug d => ((*_51).3: u32); ++ let mut _0: std::task::Poll; + let _3: u32; + let mut _8: u32; + let mut _9: {async fn body of add()}; + let mut _10: {async fn body of add()}; + let mut _11: u32; + let mut _12: u32; + let mut _14: (); + let _15: (); + let mut _16: std::task::Poll; + let mut _17: std::pin::Pin<&mut {async fn body of add()}>; + let mut _18: &mut {async fn body of add()}; + let mut _19: &mut {async fn body of add()}; + let mut _20: &mut std::task::Context<'_>; + let mut _21: &mut std::task::Context<'_>; +- let mut _22: std::future::ResumeTy; ++ let mut _22: &mut std::task::Context<'_>; + let mut _23: isize; + let mut _25: !; +- let mut _26: std::future::ResumeTy; ++ let mut _26: &mut std::task::Context<'_>; + let mut _27: (); + let mut _28: u32; + let mut _29: {async fn body of add()}; + let mut _30: {async fn body of add()}; + let mut _31: u32; + let mut _32: u32; + let _34: (); + let mut _35: std::task::Poll; + let mut _36: std::pin::Pin<&mut {async fn body of add()}>; + let mut _37: &mut {async fn body of add()}; + let mut _38: &mut {async fn body of add()}; + let mut _39: &mut std::task::Context<'_>; + let mut _40: &mut std::task::Context<'_>; +- let mut _41: std::future::ResumeTy; ++ let mut _41: &mut std::task::Context<'_>; + let mut _42: isize; + let mut _44: !; +- let mut _45: std::future::ResumeTy; ++ let mut _45: &mut std::task::Context<'_>; + let mut _46: (); + let mut _47: u32; + let mut _48: u32; ++ let mut _49: u32; ++ let mut _50: u32; ++ let mut _51: &mut {async fn body of build_aggregate()}; + scope 1 { + debug a => _3; + let _4: u32; + scope 2 { + debug b => _4; ++ coroutine debug c => _s0; + let _5: u32; + scope 3 { +- debug c => _5; ++ debug c => (((*_51) as variant#3).0: u32); ++ coroutine debug d => _s1; + let _6: u32; + scope 4 { +- debug d => _6; ++ debug d => (((*_51) as variant#3).1: u32); ++ coroutine debug __awaitee => _s3; ++ coroutine debug __awaitee => _s4; + let _7: (u32, u32); + let mut _13: {async fn body of add()}; + let mut _33: {async fn body of add()}; + scope 5 { + debug x => _7; + } + scope 6 { +- debug __awaitee => _13; ++ debug __awaitee => (((*_51) as variant#3).2: {async fn body of add()}); + let _24: u32; + scope 7 { + debug result => _24; + } + } + scope 8 { +- debug __awaitee => _33; ++ debug __awaitee => (((*_51) as variant#4).1: {async fn body of add()}); + let _43: u32; + scope 9 { + debug result => _43; + } + } + } + } + } + } + + bb0: { +- StorageLive(_3); +- _3 = copy (_1.0: u32); +- StorageLive(_4); +- _4 = copy (_1.1: u32); +- StorageLive(_5); +- _5 = copy (_1.2: u32); +- StorageLive(_6); +- _6 = copy (_1.3: u32); +- StorageLive(_7); +- StorageLive(_8); +- StorageLive(_9); +- StorageLive(_10); +- StorageLive(_11); +- _11 = copy _3; +- StorageLive(_12); +- _12 = copy _4; +- _10 = add(move _11, move _12) -> [return: bb1, unwind: bb49]; ++ _51 = copy (_1.0: &mut {async fn body of build_aggregate()}); ++ _50 = discriminant((*_51)); ++ switchInt(move _50) -> [0: bb49, 1: bb48, 2: bb47, 3: bb45, 4: bb46, otherwise: bb7]; + } + + bb1: { + StorageDead(_12); + StorageDead(_11); +- _9 = <{async fn body of add()} as IntoFuture>::into_future(move _10) -> [return: bb2, unwind: bb48]; ++ _9 = <{async fn body of add()} as IntoFuture>::into_future(move _10) -> [return: bb2, unwind: bb38]; + } + + bb2: { + StorageDead(_10); + PlaceMention(_9); +- StorageLive(_13); +- _13 = move _9; ++ nop; ++ (((*_51) as variant#3).2: {async fn body of add()}) = move _9; + goto -> bb3; + } + + bb3: { + StorageLive(_15); + StorageLive(_16); + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); +- _19 = &mut _13; ++ _19 = &mut (((*_51) as variant#3).2: {async fn body of add()}); + _18 = &mut (*_19); +- _17 = Pin::<&mut {async fn body of add()}>::new_unchecked(move _18) -> [return: bb4, unwind: bb44]; ++ _17 = Pin::<&mut {async fn body of add()}>::new_unchecked(move _18) -> [return: bb4, unwind: bb34]; + } + + bb4: { + StorageDead(_18); + StorageLive(_20); + StorageLive(_21); + StorageLive(_22); + _22 = copy _2; +- _21 = std::future::get_context::<'_, '_>(move _22) -> [return: bb5, unwind: bb42]; ++ _21 = move _22; ++ goto -> bb5; + } + + bb5: { + _20 = &mut (*_21); + StorageDead(_22); +- _16 = <{async fn body of add()} as Future>::poll(move _17, move _20) -> [return: bb6, unwind: bb43]; ++ _16 = <{async fn body of add()} as Future>::poll(move _17, move _20) -> [return: bb6, unwind: bb33]; + } + + bb6: { + StorageDead(_21); + StorageDead(_20); + StorageDead(_19); + StorageDead(_17); + PlaceMention(_16); + _23 = discriminant(_16); + switchInt(move _23) -> [0: bb9, 1: bb8, otherwise: bb7]; + } + + bb7: { + unreachable; + } + + bb8: { + _15 = const (); + StorageDead(_16); + StorageDead(_15); + StorageLive(_26); + StorageLive(_27); + _27 = (); +- _26 = yield(move _27) -> [resume: bb10, drop: bb28]; ++ _0 = Poll::::Pending; ++ StorageDead(_3); ++ StorageDead(_4); ++ StorageDead(_7); ++ StorageDead(_9); ++ StorageDead(_26); ++ StorageDead(_27); ++ discriminant((*_51)) = 3; ++ return; + } + + bb9: { + StorageLive(_24); + _24 = copy ((_16 as Ready).0: u32); +- _8 = copy _24; ++ (((*_51) as variant#4).0: u32) = copy _24; + StorageDead(_24); + StorageDead(_16); + StorageDead(_15); +- drop(_13) -> [return: bb11, unwind: bb46]; ++ drop((((*_51) as variant#3).2: {async fn body of add()})) -> [return: bb11, unwind: bb36]; + } + + bb10: { + StorageDead(_27); + _2 = move _26; + StorageDead(_26); + _14 = const (); + goto -> bb3; + } + + bb11: { +- StorageDead(_13); ++ nop; + StorageLive(_28); + StorageLive(_29); + StorageLive(_30); + StorageLive(_31); +- _31 = copy _5; ++ _31 = copy (((*_51) as variant#3).0: u32); + StorageLive(_32); +- _32 = copy _6; +- _30 = add(move _31, move _32) -> [return: bb12, unwind: bb39]; ++ _32 = copy (((*_51) as variant#3).1: u32); ++ _30 = add(move _31, move _32) -> [return: bb12, unwind: bb30]; + } + + bb12: { + StorageDead(_32); + StorageDead(_31); +- _29 = <{async fn body of add()} as IntoFuture>::into_future(move _30) -> [return: bb13, unwind: bb38]; ++ _29 = <{async fn body of add()} as IntoFuture>::into_future(move _30) -> [return: bb13, unwind: bb29]; + } + + bb13: { + StorageDead(_30); + PlaceMention(_29); +- StorageLive(_33); +- _33 = move _29; ++ nop; ++ (((*_51) as variant#4).1: {async fn body of add()}) = move _29; + goto -> bb14; + } + + bb14: { + StorageLive(_34); + StorageLive(_35); + StorageLive(_36); + StorageLive(_37); + StorageLive(_38); +- _38 = &mut _33; ++ _38 = &mut (((*_51) as variant#4).1: {async fn body of add()}); + _37 = &mut (*_38); +- _36 = Pin::<&mut {async fn body of add()}>::new_unchecked(move _37) -> [return: bb15, unwind: bb35]; ++ _36 = Pin::<&mut {async fn body of add()}>::new_unchecked(move _37) -> [return: bb15, unwind: bb26]; + } + + bb15: { + StorageDead(_37); + StorageLive(_39); + StorageLive(_40); + StorageLive(_41); + _41 = copy _2; +- _40 = std::future::get_context::<'_, '_>(move _41) -> [return: bb16, unwind: bb33]; ++ _40 = move _41; ++ goto -> bb16; + } + + bb16: { + _39 = &mut (*_40); + StorageDead(_41); +- _35 = <{async fn body of add()} as Future>::poll(move _36, move _39) -> [return: bb17, unwind: bb34]; ++ _35 = <{async fn body of add()} as Future>::poll(move _36, move _39) -> [return: bb17, unwind: bb25]; + } + + bb17: { + StorageDead(_40); + StorageDead(_39); + StorageDead(_38); + StorageDead(_36); + PlaceMention(_35); + _42 = discriminant(_35); + switchInt(move _42) -> [0: bb19, 1: bb18, otherwise: bb7]; + } + + bb18: { + _34 = const (); + StorageDead(_35); + StorageDead(_34); + StorageLive(_45); + StorageLive(_46); + _46 = (); +- _45 = yield(move _46) -> [resume: bb20, drop: bb25]; ++ _0 = Poll::::Pending; ++ StorageDead(_3); ++ StorageDead(_4); ++ StorageDead(_7); ++ StorageDead(_9); ++ StorageDead(_28); ++ StorageDead(_29); ++ StorageDead(_45); ++ StorageDead(_46); ++ discriminant((*_51)) = 4; ++ return; + } + + bb19: { + StorageLive(_43); + _43 = copy ((_35 as Ready).0: u32); + _28 = copy _43; + StorageDead(_43); + StorageDead(_35); + StorageDead(_34); +- drop(_33) -> [return: bb21, unwind: bb37]; ++ drop((((*_51) as variant#4).1: {async fn body of add()})) -> [return: bb21, unwind: bb28]; + } + + bb20: { + StorageDead(_46); + _2 = move _45; + StorageDead(_45); + _14 = const (); + goto -> bb14; + } + + bb21: { +- StorageDead(_33); +- _7 = (move _8, move _28); ++ nop; ++ _7 = (move (((*_51) as variant#4).0: u32), move _28); + StorageDead(_28); +- StorageDead(_8); ++ nop; + goto -> bb22; + } + + bb22: { + StorageDead(_29); + goto -> bb23; + } + + bb23: { + StorageDead(_9); + StorageLive(_47); + _47 = copy (_7.0: u32); + StorageLive(_48); + _48 = copy (_7.1: u32); +- _0 = Add(move _47, move _48); ++ _49 = Add(move _47, move _48); + StorageDead(_48); + StorageDead(_47); + StorageDead(_7); +- StorageDead(_6); +- StorageDead(_5); ++ nop; ++ nop; + StorageDead(_4); + StorageDead(_3); +- drop(_1) -> [return: bb24, unwind: bb52]; ++ goto -> bb43; + } + + bb24: { ++ _0 = Poll::::Ready(move _49); ++ discriminant((*_51)) = 1; + return; + } + +- bb25: { +- StorageDead(_46); +- StorageDead(_45); +- drop(_33) -> [return: bb26, unwind: bb53]; +- } +- +- bb26: { +- StorageDead(_33); +- StorageDead(_28); +- StorageDead(_8); +- goto -> bb27; +- } +- +- bb27: { +- StorageDead(_29); +- goto -> bb30; +- } +- +- bb28: { +- StorageDead(_27); +- StorageDead(_26); +- drop(_13) -> [return: bb29, unwind: bb55]; +- } +- +- bb29: { +- StorageDead(_13); +- StorageDead(_8); +- goto -> bb30; +- } +- +- bb30: { +- goto -> bb31; +- } +- +- bb31: { +- StorageDead(_9); +- StorageDead(_7); +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb32, unwind: bb52]; +- } +- +- bb32: { +- coroutine_drop; +- } +- +- bb33 (cleanup): { +- StorageDead(_41); +- goto -> bb34; +- } +- +- bb34 (cleanup): { ++ bb25 (cleanup): { + StorageDead(_40); + StorageDead(_39); +- goto -> bb36; ++ goto -> bb27; + } + +- bb35 (cleanup): { ++ bb26 (cleanup): { + StorageDead(_37); +- goto -> bb36; ++ goto -> bb27; + } + +- bb36 (cleanup): { ++ bb27 (cleanup): { + StorageDead(_38); + StorageDead(_36); + StorageDead(_35); + StorageDead(_34); +- drop(_33) -> [return: bb37, unwind terminate(cleanup)]; ++ drop((((*_51) as variant#4).1: {async fn body of add()})) -> [return: bb28, unwind terminate(cleanup)]; + } + +- bb37 (cleanup): { +- StorageDead(_33); ++ bb28 (cleanup): { ++ nop; + StorageDead(_28); +- StorageDead(_8); +- goto -> bb41; ++ nop; ++ goto -> bb32; + } + +- bb38 (cleanup): { +- goto -> bb40; ++ bb29 (cleanup): { ++ goto -> bb31; + } + +- bb39 (cleanup): { ++ bb30 (cleanup): { + StorageDead(_32); + StorageDead(_31); +- goto -> bb40; ++ goto -> bb31; + } + +- bb40 (cleanup): { ++ bb31 (cleanup): { + StorageDead(_30); + StorageDead(_28); +- StorageDead(_8); +- goto -> bb41; ++ nop; ++ goto -> bb32; + } + +- bb41 (cleanup): { ++ bb32 (cleanup): { + StorageDead(_29); +- goto -> bb47; ++ goto -> bb37; + } + +- bb42 (cleanup): { +- StorageDead(_22); +- goto -> bb43; +- } +- +- bb43 (cleanup): { ++ bb33 (cleanup): { + StorageDead(_21); + StorageDead(_20); +- goto -> bb45; ++ goto -> bb35; + } + +- bb44 (cleanup): { ++ bb34 (cleanup): { + StorageDead(_18); +- goto -> bb45; ++ goto -> bb35; + } + +- bb45 (cleanup): { ++ bb35 (cleanup): { + StorageDead(_19); + StorageDead(_17); + StorageDead(_16); + StorageDead(_15); +- drop(_13) -> [return: bb46, unwind terminate(cleanup)]; ++ drop((((*_51) as variant#3).2: {async fn body of add()})) -> [return: bb36, unwind terminate(cleanup)]; + } + +- bb46 (cleanup): { +- StorageDead(_13); +- StorageDead(_8); +- goto -> bb47; ++ bb36 (cleanup): { ++ nop; ++ nop; ++ goto -> bb37; + } + +- bb47 (cleanup): { +- goto -> bb51; ++ bb37 (cleanup): { ++ goto -> bb41; + } + +- bb48 (cleanup): { +- goto -> bb50; ++ bb38 (cleanup): { ++ goto -> bb40; + } + +- bb49 (cleanup): { ++ bb39 (cleanup): { + StorageDead(_12); + StorageDead(_11); +- goto -> bb50; ++ goto -> bb40; + } + +- bb50 (cleanup): { ++ bb40 (cleanup): { + StorageDead(_10); +- StorageDead(_8); +- goto -> bb51; ++ nop; ++ goto -> bb41; + } + +- bb51 (cleanup): { ++ bb41 (cleanup): { + StorageDead(_9); + StorageDead(_7); +- StorageDead(_6); +- StorageDead(_5); ++ nop; ++ nop; + StorageDead(_4); + StorageDead(_3); +- drop(_1) -> [return: bb52, unwind terminate(cleanup)]; ++ goto -> bb42; + } + +- bb52 (cleanup): { ++ bb42 (cleanup): { ++ goto -> bb44; ++ } ++ ++ bb43: { ++ goto -> bb24; ++ } ++ ++ bb44 (cleanup): { ++ discriminant((*_51)) = 2; + resume; + } + +- bb53 (cleanup): { +- StorageDead(_33); +- StorageDead(_28); +- StorageDead(_8); +- goto -> bb54; ++ bb45: { ++ StorageLive(_3); ++ StorageLive(_4); ++ StorageLive(_7); ++ StorageLive(_9); ++ StorageLive(_26); ++ StorageLive(_27); ++ _26 = move _2; ++ goto -> bb10; + } + +- bb54 (cleanup): { +- StorageDead(_29); +- goto -> bb56; ++ bb46: { ++ StorageLive(_3); ++ StorageLive(_4); ++ StorageLive(_7); ++ StorageLive(_9); ++ StorageLive(_28); ++ StorageLive(_29); ++ StorageLive(_45); ++ StorageLive(_46); ++ _45 = move _2; ++ goto -> bb20; + } + +- bb55 (cleanup): { +- StorageDead(_13); +- StorageDead(_8); +- goto -> bb56; ++ bb47: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb47, unwind continue]; + } + +- bb56 (cleanup): { +- goto -> bb57; ++ bb48: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb48, unwind continue]; + } + +- bb57 (cleanup): { +- StorageDead(_9); +- StorageDead(_7); +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb52, unwind terminate(cleanup)]; ++ bb49: { ++ StorageLive(_3); ++ _3 = copy ((*_51).0: u32); ++ StorageLive(_4); ++ _4 = copy ((*_51).1: u32); ++ nop; ++ (((*_51) as variant#3).0: u32) = copy ((*_51).2: u32); ++ nop; ++ (((*_51) as variant#3).1: u32) = copy ((*_51).3: u32); ++ StorageLive(_7); ++ nop; ++ StorageLive(_9); ++ StorageLive(_10); ++ StorageLive(_11); ++ _11 = copy _3; ++ StorageLive(_12); ++ _12 = copy _4; ++ _10 = add(move _11, move _12) -> [return: bb1, unwind: bb39]; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..bd5fea383b50d --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,217 @@ +// MIR for `build_aggregate::{closure#0}` 0 coroutine_drop + +fn build_aggregate::{closure#0}(_1: &mut {async fn body of build_aggregate()}) -> () { + debug _task_context => _2; + debug a => ((*_1).0: u32); + debug b => ((*_1).1: u32); + debug c => ((*_1).2: u32); + debug d => ((*_1).3: u32); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let _3: u32; + let mut _8: u32; + let mut _9: {async fn body of add()}; + let mut _10: {async fn body of add()}; + let mut _11: u32; + let mut _12: u32; + let mut _14: (); + let _15: (); + let mut _16: std::task::Poll; + let mut _17: std::pin::Pin<&mut {async fn body of add()}>; + let mut _18: &mut {async fn body of add()}; + let mut _19: &mut {async fn body of add()}; + let mut _20: &mut std::task::Context<'_>; + let mut _21: &mut std::task::Context<'_>; + let mut _22: &mut std::task::Context<'_>; + let mut _23: isize; + let mut _25: !; + let mut _26: &mut std::task::Context<'_>; + let mut _27: (); + let mut _28: u32; + let mut _29: {async fn body of add()}; + let mut _30: {async fn body of add()}; + let mut _31: u32; + let mut _32: u32; + let _34: (); + let mut _35: std::task::Poll; + let mut _36: std::pin::Pin<&mut {async fn body of add()}>; + let mut _37: &mut {async fn body of add()}; + let mut _38: &mut {async fn body of add()}; + let mut _39: &mut std::task::Context<'_>; + let mut _40: &mut std::task::Context<'_>; + let mut _41: &mut std::task::Context<'_>; + let mut _42: isize; + let mut _44: !; + let mut _45: &mut std::task::Context<'_>; + let mut _46: (); + let mut _47: u32; + let mut _48: u32; + let mut _49: u32; + let mut _50: u32; + scope 1 { + debug a => _3; + let _4: u32; + scope 2 { + debug b => _4; + let _5: u32; + scope 3 { + debug c => (((*_1) as variant#3).0: u32); + let _6: u32; + scope 4 { + debug d => (((*_1) as variant#3).1: u32); + let _7: (u32, u32); + let mut _13: {async fn body of add()}; + let mut _33: {async fn body of add()}; + scope 5 { + debug x => _7; + } + scope 6 { + debug __awaitee => (((*_1) as variant#3).2: {async fn body of add()}); + let _24: u32; + scope 7 { + debug result => _24; + } + } + scope 8 { + debug __awaitee => (((*_1) as variant#4).1: {async fn body of add()}); + let _43: u32; + scope 9 { + debug result => _43; + } + } + } + } + } + } + + bb0: { + _50 = discriminant((*_1)); + switchInt(move _50) -> [0: bb16, 3: bb19, 4: bb20, otherwise: bb21]; + } + + bb1: { + StorageDead(_46); + StorageDead(_45); + drop((((*_1) as variant#4).1: {async fn body of add()})) -> [return: bb2, unwind: bb10]; + } + + bb2: { + nop; + StorageDead(_28); + nop; + goto -> bb3; + } + + bb3: { + StorageDead(_29); + goto -> bb6; + } + + bb4: { + StorageDead(_27); + StorageDead(_26); + drop((((*_1) as variant#3).2: {async fn body of add()})) -> [return: bb5, unwind: bb12]; + } + + bb5: { + nop; + nop; + goto -> bb6; + } + + bb6: { + goto -> bb7; + } + + bb7: { + StorageDead(_9); + StorageDead(_7); + nop; + nop; + StorageDead(_4); + StorageDead(_3); + goto -> bb17; + } + + bb8: { + return; + } + + bb9 (cleanup): { + resume; + } + + bb10 (cleanup): { + nop; + StorageDead(_28); + nop; + goto -> bb11; + } + + bb11 (cleanup): { + StorageDead(_29); + goto -> bb13; + } + + bb12 (cleanup): { + nop; + nop; + goto -> bb13; + } + + bb13 (cleanup): { + goto -> bb14; + } + + bb14 (cleanup): { + StorageDead(_9); + StorageDead(_7); + nop; + nop; + StorageDead(_4); + StorageDead(_3); + goto -> bb9; + } + + bb15: { + return; + } + + bb16: { + goto -> bb18; + } + + bb17: { + goto -> bb8; + } + + bb18: { + goto -> bb15; + } + + bb19: { + StorageLive(_3); + StorageLive(_4); + StorageLive(_7); + StorageLive(_9); + StorageLive(_26); + StorageLive(_27); + goto -> bb4; + } + + bb20: { + StorageLive(_3); + StorageLive(_4); + StorageLive(_7); + StorageLive(_9); + StorageLive(_28); + StorageLive(_29); + StorageLive(_45); + StorageLive(_46); + goto -> bb1; + } + + bb21: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..9f06ae9272bad --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,32 @@ +// MIR for `build_aggregate::{closure#0}` 0 coroutine_drop_proxy_async + +fn build_aggregate::{closure#0}(_1: {async fn body of build_aggregate()}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + scope 1 { + scope 2 { + scope 3 { + scope 4 { + scope 5 { + } + scope 6 { + scope 7 { + } + } + scope 8 { + scope 9 { + } + } + } + } + } + } + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..b902c7c048048 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.StateTransform.diff @@ -0,0 +1,80 @@ +- // MIR for `foo::{closure#0}::{closure#0}` before StateTransform ++ // MIR for `foo::{closure#0}::{closure#0}` after StateTransform + +- fn foo::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:21:13: 21:18}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:21:13: 21:18}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ } ++ storage_conflicts = BitMatrix(0x0) {} ++ } + debug _task_context => _2; +- debug y => (*(_1.0: &u32)); +- debug z => (*(_1.1: &u32)); +- let mut _0: u32; ++ debug y => (*((*_9).0: &u32)); ++ debug z => (*((*_9).1: &u32)); ++ let mut _0: std::task::Poll; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; ++ let mut _7: u32; ++ let mut _8: u32; ++ let mut _9: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}; + + bb0: { +- StorageLive(_3); +- _5 = no_retag copy (_1.0: &u32); +- _3 = copy (*_5); +- StorageLive(_4); +- _6 = no_retag copy (_1.1: &u32); +- _4 = copy (*_6); +- _0 = Add(move _3, move _4); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb1, unwind: bb2]; ++ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}); ++ _8 = discriminant((*_9)); ++ switchInt(move _8) -> [0: bb5, 1: bb3, otherwise: bb4]; + } + + bb1: { ++ _0 = Poll::::Ready(move _7); ++ discriminant((*_9)) = 1; + return; + } + +- bb2 (cleanup): { +- resume; ++ bb2: { ++ goto -> bb1; ++ } ++ ++ bb3: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb3, unwind continue]; ++ } ++ ++ bb4: { ++ unreachable; ++ } ++ ++ bb5: { ++ StorageLive(_3); ++ _5 = no_retag copy ((*_9).0: &u32); ++ _3 = copy (*_5); ++ StorageLive(_4); ++ _6 = no_retag copy ((*_9).1: &u32); ++ _4 = copy (*_6); ++ _7 = Add(move _3, move _4); ++ StorageDead(_4); ++ StorageDead(_3); ++ goto -> bb2; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..c22d1ca1ca132 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,36 @@ +// MIR for `foo::{closure#0}::{closure#0}` 0 coroutine_drop + +fn foo::{closure#0}::{closure#0}(_1: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}) -> () { + debug _task_context => _2; + debug y => (*((*_1).0: &u32)); + debug z => (*((*_1).1: &u32)); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; + let mut _7: u32; + let mut _8: u32; + + bb0: { + _8 = discriminant((*_1)); + switchInt(move _8) -> [0: bb2, otherwise: bb4]; + } + + bb1: { + return; + } + + bb2: { + goto -> bb3; + } + + bb3: { + goto -> bb1; + } + + bb4: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..19fe75de78cb5 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,14 @@ +// MIR for `foo::{closure#0}::{closure#0}` 0 coroutine_drop_proxy_async + +fn foo::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:21:13: 21:18}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..86cac4aad150d --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.StateTransform.diff @@ -0,0 +1,432 @@ +- // MIR for `foo::{closure#0}` before StateTransform ++ // MIR for `foo::{closure#0}` after StateTransform + +- fn foo::{closure#0}(_1: {async fn body of foo()}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn foo::{closure#0}(_1: Pin<&mut {async fn body of foo()}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ field _s0: &u32; ++ field _s1: u32; ++ field _s2: u32; ++ field _s3: {async block@$DIR/async_fn.rs:21:13: 21:18}; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s2, _s3], ++ } ++ storage_conflicts = BitMatrix(4x4) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3)} ++ } + debug _task_context => _2; +- debug x => (_1.0: &u32); +- debug y => (_1.1: u32); +- let mut _0: u32; ++ debug x => ((*_36).0: &u32); ++ debug y => ((*_36).1: u32); ++ coroutine debug x => _s0; ++ let mut _0: std::task::Poll; + let _3: &u32; + let mut _9: {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _10: {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _11: &u32; + let mut _12: &u32; + let mut _14: (); + let _15: (); + let mut _16: std::task::Poll; + let mut _17: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:21:13: 21:18}>; + let mut _18: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _19: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _20: &mut std::task::Context<'_>; + let mut _21: &mut std::task::Context<'_>; +- let mut _22: std::future::ResumeTy; ++ let mut _22: &mut std::task::Context<'_>; + let mut _23: isize; + let mut _25: !; +- let mut _26: std::future::ResumeTy; ++ let mut _26: &mut std::task::Context<'_>; + let mut _27: (); + let mut _30: u32; + let mut _31: u32; + let mut _32: u32; + let mut _33: u32; ++ let mut _34: u32; ++ let mut _35: u32; ++ let mut _36: &mut {async fn body of foo()}; ++ let mut _37: &u32; + scope 1 { +- debug x => _3; ++ debug x => (((*_36) as variant#3).0: &u32); ++ coroutine debug y => _s1; + let _4: u32; + scope 2 { +- debug y => _4; ++ debug y => (((*_36) as variant#3).1: u32); + let _5: &u32; + scope 3 { + debug y => _5; ++ coroutine debug z => _s2; + let _6: u32; + scope 4 { +- debug z => _6; ++ debug z => (((*_36) as variant#3).2: u32); + let _7: &u32; + scope 5 { + debug z => _7; ++ coroutine debug __awaitee => _s3; + let _8: u32; + let mut _13: {async block@$DIR/async_fn.rs:21:13: 21:18}; + scope 6 { + debug y => _8; + let _28: u32; + scope 9 { + debug a => _28; + let _29: &u32; + scope 10 { + debug a => _29; + } + } + } + scope 7 { +- debug __awaitee => _13; ++ debug __awaitee => (((*_36) as variant#3).3: {async block@$DIR/async_fn.rs:21:13: 21:18}); + let _24: u32; + scope 8 { + debug result => _24; + } + } + } + } + } + } + } + + bb0: { +- StorageLive(_3); +- _3 = copy (_1.0: &u32); +- StorageLive(_4); +- _4 = copy (_1.1: u32); +- StorageLive(_5); +- _5 = &_4; +- StorageLive(_6); +- _6 = const 9_u32; +- StorageLive(_7); +- _7 = &_6; +- StorageLive(_8); +- StorageLive(_9); +- StorageLive(_10); +- StorageLive(_11); +- _11 = &(*_5); +- StorageLive(_12); +- _12 = &(*_7); +- _10 = {coroutine@$DIR/async_fn.rs:21:13: 21:18 (#0)} { y: move _11, z: move _12 }; +- StorageDead(_12); +- StorageDead(_11); +- _9 = <{async block@$DIR/async_fn.rs:21:13: 21:18} as IntoFuture>::into_future(move _10) -> [return: bb1, unwind: bb22]; ++ _36 = copy (_1.0: &mut {async fn body of foo()}); ++ _35 = discriminant((*_36)); ++ switchInt(move _35) -> [0: bb26, 1: bb25, 2: bb24, 3: bb23, otherwise: bb6]; + } + + bb1: { + StorageDead(_10); + PlaceMention(_9); +- StorageLive(_13); +- _13 = move _9; ++ nop; ++ (((*_36) as variant#3).3: {async block@$DIR/async_fn.rs:21:13: 21:18}) = move _9; + goto -> bb2; + } + + bb2: { + StorageLive(_15); + StorageLive(_16); + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); +- _19 = &mut _13; ++ _19 = &mut (((*_36) as variant#3).3: {async block@$DIR/async_fn.rs:21:13: 21:18}); + _18 = &mut (*_19); +- _17 = Pin::<&mut {async block@$DIR/async_fn.rs:21:13: 21:18}>::new_unchecked(move _18) -> [return: bb3, unwind: bb19]; ++ _17 = Pin::<&mut {async block@$DIR/async_fn.rs:21:13: 21:18}>::new_unchecked(move _18) -> [return: bb3, unwind: bb14]; + } + + bb3: { + StorageDead(_18); + StorageLive(_20); + StorageLive(_21); + StorageLive(_22); + _22 = copy _2; +- _21 = std::future::get_context::<'_, '_>(move _22) -> [return: bb4, unwind: bb17]; ++ _21 = move _22; ++ goto -> bb4; + } + + bb4: { + _20 = &mut (*_21); + StorageDead(_22); +- _16 = <{async block@$DIR/async_fn.rs:21:13: 21:18} as Future>::poll(move _17, move _20) -> [return: bb5, unwind: bb18]; ++ _16 = <{async block@$DIR/async_fn.rs:21:13: 21:18} as Future>::poll(move _17, move _20) -> [return: bb5, unwind: bb13]; + } + + bb5: { + StorageDead(_21); + StorageDead(_20); + StorageDead(_19); + StorageDead(_17); + PlaceMention(_16); + _23 = discriminant(_16); + switchInt(move _23) -> [0: bb8, 1: bb7, otherwise: bb6]; + } + + bb6: { + unreachable; + } + + bb7: { + _15 = const (); + StorageDead(_16); + StorageDead(_15); + StorageLive(_26); + StorageLive(_27); + _27 = (); +- _26 = yield(move _27) -> [resume: bb9, drop: bb13]; ++ _0 = Poll::::Pending; ++ StorageDead(_5); ++ StorageDead(_7); ++ StorageDead(_8); ++ StorageDead(_9); ++ StorageDead(_26); ++ StorageDead(_27); ++ discriminant((*_36)) = 3; ++ return; + } + + bb8: { + StorageLive(_24); + _24 = copy ((_16 as Ready).0: u32); + _8 = copy _24; + StorageDead(_24); + StorageDead(_16); + StorageDead(_15); +- drop(_13) -> [return: bb10, unwind: bb21]; ++ drop((((*_36) as variant#3).3: {async block@$DIR/async_fn.rs:21:13: 21:18})) -> [return: bb10, unwind: bb16]; + } + + bb9: { + StorageDead(_27); + _2 = move _26; + StorageDead(_26); + _14 = const (); + goto -> bb2; + } + + bb10: { +- StorageDead(_13); ++ nop; + goto -> bb11; + } + + bb11: { + StorageDead(_9); + StorageLive(_28); + _28 = const 10_u32; + StorageLive(_29); + _29 = &_28; + StorageLive(_30); + StorageLive(_31); +- _31 = copy (*_3); ++ _37 = no_retag copy (((*_36) as variant#3).0: &u32); ++ _31 = copy (*_37); + StorageLive(_32); + _32 = copy _8; + _30 = Add(move _31, move _32); + StorageDead(_32); + StorageDead(_31); + StorageLive(_33); + _33 = copy (*_29); +- _0 = Add(move _30, move _33); ++ _34 = Add(move _30, move _33); + StorageDead(_33); + StorageDead(_30); + StorageDead(_29); + StorageDead(_28); + StorageDead(_8); + StorageDead(_7); +- StorageDead(_6); ++ nop; + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb12, unwind: bb25]; ++ nop; ++ nop; ++ goto -> bb21; + } + + bb12: { ++ _0 = Poll::::Ready(move _34); ++ discriminant((*_36)) = 1; + return; + } + +- bb13: { +- StorageDead(_27); +- StorageDead(_26); +- drop(_13) -> [return: bb14, unwind: bb26]; ++ bb13 (cleanup): { ++ StorageDead(_21); ++ StorageDead(_20); ++ goto -> bb15; + } + +- bb14: { +- StorageDead(_13); ++ bb14 (cleanup): { ++ StorageDead(_18); + goto -> bb15; + } + +- bb15: { +- StorageDead(_9); +- StorageDead(_8); +- StorageDead(_7); +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb16, unwind: bb25]; ++ bb15 (cleanup): { ++ StorageDead(_19); ++ StorageDead(_17); ++ StorageDead(_16); ++ StorageDead(_15); ++ drop((((*_36) as variant#3).3: {async block@$DIR/async_fn.rs:21:13: 21:18})) -> [return: bb16, unwind terminate(cleanup)]; + } + +- bb16: { +- coroutine_drop; ++ bb16 (cleanup): { ++ nop; ++ goto -> bb19; + } + + bb17 (cleanup): { +- StorageDead(_22); + goto -> bb18; + } + + bb18 (cleanup): { +- StorageDead(_21); +- StorageDead(_20); +- goto -> bb20; ++ StorageDead(_10); ++ goto -> bb19; + } + + bb19 (cleanup): { +- StorageDead(_18); ++ StorageDead(_9); ++ StorageDead(_8); ++ StorageDead(_7); ++ nop; ++ StorageDead(_5); ++ nop; ++ nop; + goto -> bb20; + } + + bb20 (cleanup): { +- StorageDead(_19); +- StorageDead(_17); +- StorageDead(_16); +- StorageDead(_15); +- drop(_13) -> [return: bb21, unwind terminate(cleanup)]; ++ goto -> bb22; + } + +- bb21 (cleanup): { +- StorageDead(_13); +- goto -> bb24; ++ bb21: { ++ goto -> bb12; + } + + bb22 (cleanup): { +- goto -> bb23; ++ discriminant((*_36)) = 2; ++ resume; + } + +- bb23 (cleanup): { +- StorageDead(_10); +- goto -> bb24; ++ bb23: { ++ StorageLive(_5); ++ StorageLive(_7); ++ StorageLive(_8); ++ StorageLive(_9); ++ StorageLive(_26); ++ StorageLive(_27); ++ _26 = move _2; ++ goto -> bb9; + } + +- bb24 (cleanup): { +- StorageDead(_9); +- StorageDead(_8); +- StorageDead(_7); +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb25, unwind terminate(cleanup)]; ++ bb24: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb24, unwind continue]; + } + +- bb25 (cleanup): { +- resume; ++ bb25: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb25, unwind continue]; + } + +- bb26 (cleanup): { +- StorageDead(_13); +- goto -> bb27; +- } +- +- bb27 (cleanup): { +- StorageDead(_9); +- StorageDead(_8); +- StorageDead(_7); +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb25, unwind terminate(cleanup)]; ++ bb26: { ++ nop; ++ (((*_36) as variant#3).0: &u32) = copy ((*_36).0: &u32); ++ nop; ++ (((*_36) as variant#3).1: u32) = copy ((*_36).1: u32); ++ StorageLive(_5); ++ _5 = &(((*_36) as variant#3).1: u32); ++ nop; ++ (((*_36) as variant#3).2: u32) = const 9_u32; ++ StorageLive(_7); ++ _7 = &(((*_36) as variant#3).2: u32); ++ StorageLive(_8); ++ StorageLive(_9); ++ StorageLive(_10); ++ StorageLive(_11); ++ _11 = &(*_5); ++ StorageLive(_12); ++ _12 = &(*_7); ++ _10 = {coroutine@$DIR/async_fn.rs:21:13: 21:18 (#0)} { y: move _11, z: move _12 }; ++ StorageDead(_12); ++ StorageDead(_11); ++ _9 = <{async block@$DIR/async_fn.rs:21:13: 21:18} as IntoFuture>::into_future(move _10) -> [return: bb1, unwind: bb17]; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..1ce52d353af34 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,153 @@ +// MIR for `foo::{closure#0}` 0 coroutine_drop + +fn foo::{closure#0}(_1: &mut {async fn body of foo()}) -> () { + debug _task_context => _2; + debug x => ((*_1).0: &u32); + debug y => ((*_1).1: u32); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let _3: &u32; + let mut _9: {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _10: {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _11: &u32; + let mut _12: &u32; + let mut _14: (); + let _15: (); + let mut _16: std::task::Poll; + let mut _17: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:21:13: 21:18}>; + let mut _18: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _19: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _20: &mut std::task::Context<'_>; + let mut _21: &mut std::task::Context<'_>; + let mut _22: &mut std::task::Context<'_>; + let mut _23: isize; + let mut _25: !; + let mut _26: &mut std::task::Context<'_>; + let mut _27: (); + let mut _30: u32; + let mut _31: u32; + let mut _32: u32; + let mut _33: u32; + let mut _34: u32; + let mut _35: u32; + scope 1 { + debug x => (((*_1) as variant#3).0: &u32); + let _4: u32; + scope 2 { + debug y => (((*_1) as variant#3).1: u32); + let _5: &u32; + scope 3 { + debug y => _5; + let _6: u32; + scope 4 { + debug z => (((*_1) as variant#3).2: u32); + let _7: &u32; + scope 5 { + debug z => _7; + let _8: u32; + let mut _13: {async block@$DIR/async_fn.rs:21:13: 21:18}; + scope 6 { + debug y => _8; + let _28: u32; + scope 9 { + debug a => _28; + let _29: &u32; + scope 10 { + debug a => _29; + } + } + } + scope 7 { + debug __awaitee => (((*_1) as variant#3).3: {async block@$DIR/async_fn.rs:21:13: 21:18}); + let _24: u32; + scope 8 { + debug result => _24; + } + } + } + } + } + } + } + + bb0: { + _35 = discriminant((*_1)); + switchInt(move _35) -> [0: bb9, 3: bb12, otherwise: bb13]; + } + + bb1: { + StorageDead(_27); + StorageDead(_26); + drop((((*_1) as variant#3).3: {async block@$DIR/async_fn.rs:21:13: 21:18})) -> [return: bb2, unwind: bb6]; + } + + bb2: { + nop; + goto -> bb3; + } + + bb3: { + StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + nop; + StorageDead(_5); + nop; + nop; + goto -> bb10; + } + + bb4: { + return; + } + + bb5 (cleanup): { + resume; + } + + bb6 (cleanup): { + nop; + goto -> bb7; + } + + bb7 (cleanup): { + StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + nop; + StorageDead(_5); + nop; + nop; + goto -> bb5; + } + + bb8: { + return; + } + + bb9: { + goto -> bb11; + } + + bb10: { + goto -> bb4; + } + + bb11: { + goto -> bb8; + } + + bb12: { + StorageLive(_5); + StorageLive(_7); + StorageLive(_8); + StorageLive(_9); + StorageLive(_26); + StorageLive(_27); + goto -> bb1; + } + + bb13: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..f7038fc83baad --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,34 @@ +// MIR for `foo::{closure#0}` 0 coroutine_drop_proxy_async + +fn foo::{closure#0}(_1: {async fn body of foo()}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + scope 1 { + scope 2 { + scope 3 { + scope 4 { + scope 5 { + scope 6 { + scope 9 { + scope 10 { + } + } + } + scope 7 { + scope 8 { + } + } + } + } + } + } + } + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..fbbec5a970b73 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.StateTransform.diff @@ -0,0 +1,453 @@ +- // MIR for `hello_world::{closure#0}` before StateTransform ++ // MIR for `hello_world::{closure#0}` after StateTransform + +- fn hello_world::{closure#0}(_1: {async fn body of hello_world()}, _2: std::future::ResumeTy) -> () +- yields () +- { ++ fn hello_world::{closure#0}(_1: Pin<&mut {async fn body of hello_world()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: [u8; 1]; ++ field _s1: &[u8]; ++ field _s2: [u8; 1]; ++ field _s3: {async fn body of read_exact()}; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s2, _s3], ++ } ++ storage_conflicts = BitMatrix(4x4) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3)} ++ } + debug _task_context => _2; +- let mut _0: (); ++ coroutine debug data => _s0; ++ let mut _0: std::task::Poll<()>; + let _3: [u8; 1]; + let _5: &[u8]; + let mut _6: &[u8; 1]; + let mut _7: std::ops::RangeFull; + let _9: (); + let mut _10: std::option::Option<()>; + let mut _11: {async fn body of read_exact()}; + let mut _12: {async fn body of read_exact()}; + let mut _13: &mut &[u8]; + let mut _14: &mut &[u8]; + let mut _15: &mut [u8]; + let mut _16: &mut [u8; 1]; + let mut _17: &mut [u8; 1]; + let mut _19: (); + let _20: (); + let mut _21: std::task::Poll>; + let mut _22: std::pin::Pin<&mut {async fn body of read_exact()}>; + let mut _23: &mut {async fn body of read_exact()}; + let mut _24: &mut {async fn body of read_exact()}; + let mut _25: &mut std::task::Context<'_>; + let mut _26: &mut std::task::Context<'_>; +- let mut _27: std::future::ResumeTy; ++ let mut _27: &mut std::task::Context<'_>; + let mut _28: isize; + let mut _30: !; +- let mut _31: std::future::ResumeTy; ++ let mut _31: &mut std::task::Context<'_>; + let mut _32: (); ++ let mut _33: (); ++ let mut _34: u32; ++ let mut _35: &mut {async fn body of hello_world()}; + scope 1 { +- debug data => _3; ++ debug data => (((*_35) as variant#3).0: [u8; 1]); ++ coroutine debug reader => _s1; + let mut _4: &[u8]; + scope 2 { +- debug reader => _4; ++ debug reader => (((*_35) as variant#3).1: &[u8]); ++ coroutine debug marker => _s2; + let mut _8: [u8; 1]; + scope 3 { +- debug marker => _8; ++ debug marker => (((*_35) as variant#3).2: [u8; 1]); ++ coroutine debug __awaitee => _s3; + let mut _18: {async fn body of read_exact()}; + scope 4 { +- debug __awaitee => _18; ++ debug __awaitee => (((*_35) as variant#3).3: {async fn body of read_exact()}); + let _29: std::option::Option<()>; + scope 5 { + debug result => _29; + } + } + } + } + } + + bb0: { +- StorageLive(_3); +- _3 = [const 0_u8; 1]; +- StorageLive(_4); +- StorageLive(_5); +- StorageLive(_6); +- _6 = &_3; +- StorageLive(_7); +- _7 = RangeFull; +- _5 = <[u8; 1] as Index>::index(move _6, move _7) -> [return: bb1, unwind: bb30]; ++ _35 = copy (_1.0: &mut {async fn body of hello_world()}); ++ _34 = discriminant((*_35)); ++ switchInt(move _34) -> [0: bb33, 1: bb32, 2: bb31, 3: bb30, otherwise: bb8]; + } + + bb1: { + StorageDead(_7); + StorageDead(_6); +- _4 = &(*_5); +- StorageLive(_8); +- _8 = [const 0_u8; 1]; ++ (((*_35) as variant#3).1: &[u8]) = &(*_5); ++ nop; ++ (((*_35) as variant#3).2: [u8; 1]) = [const 0_u8; 1]; + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + StorageLive(_13); + StorageLive(_14); +- _14 = &mut _4; ++ _14 = &mut (((*_35) as variant#3).1: &[u8]); + _13 = &mut (*_14); + StorageLive(_15); + StorageLive(_16); + StorageLive(_17); +- _17 = &mut _8; ++ _17 = &mut (((*_35) as variant#3).2: [u8; 1]); + _16 = &mut (*_17); + _15 = move _16 as &mut [u8] (PointerCoercion(Unsize, Implicit)); + StorageDead(_16); +- _12 = read_exact(move _13, move _15) -> [return: bb2, unwind: bb27]; ++ _12 = read_exact(move _13, move _15) -> [return: bb2, unwind: bb22]; + } + + bb2: { + StorageDead(_15); + StorageDead(_13); +- _11 = <{async fn body of read_exact()} as IntoFuture>::into_future(move _12) -> [return: bb3, unwind: bb26]; ++ _11 = <{async fn body of read_exact()} as IntoFuture>::into_future(move _12) -> [return: bb3, unwind: bb21]; + } + + bb3: { + StorageDead(_12); + PlaceMention(_11); +- StorageLive(_18); +- _18 = move _11; ++ nop; ++ (((*_35) as variant#3).3: {async fn body of read_exact()}) = move _11; + goto -> bb4; + } + + bb4: { + StorageLive(_20); + StorageLive(_21); + StorageLive(_22); + StorageLive(_23); + StorageLive(_24); +- _24 = &mut _18; ++ _24 = &mut (((*_35) as variant#3).3: {async fn body of read_exact()}); + _23 = &mut (*_24); +- _22 = Pin::<&mut {async fn body of read_exact()}>::new_unchecked(move _23) -> [return: bb5, unwind: bb22]; ++ _22 = Pin::<&mut {async fn body of read_exact()}>::new_unchecked(move _23) -> [return: bb5, unwind: bb17]; + } + + bb5: { + StorageDead(_23); + StorageLive(_25); + StorageLive(_26); + StorageLive(_27); + _27 = copy _2; +- _26 = std::future::get_context::<'_, '_>(move _27) -> [return: bb6, unwind: bb20]; ++ _26 = move _27; ++ goto -> bb6; + } + + bb6: { + _25 = &mut (*_26); + StorageDead(_27); +- _21 = <{async fn body of read_exact()} as Future>::poll(move _22, move _25) -> [return: bb7, unwind: bb21]; ++ _21 = <{async fn body of read_exact()} as Future>::poll(move _22, move _25) -> [return: bb7, unwind: bb16]; + } + + bb7: { + StorageDead(_26); + StorageDead(_25); + StorageDead(_24); + StorageDead(_22); + PlaceMention(_21); + _28 = discriminant(_21); + switchInt(move _28) -> [0: bb10, 1: bb9, otherwise: bb8]; + } + + bb8: { + unreachable; + } + + bb9: { + _20 = const (); + StorageDead(_21); + StorageDead(_20); + StorageLive(_31); + StorageLive(_32); + _32 = (); +- _31 = yield(move _32) -> [resume: bb11, drop: bb16]; ++ _0 = Poll::<()>::Pending; ++ StorageDead(_5); ++ StorageDead(_9); ++ StorageDead(_10); ++ StorageDead(_11); ++ StorageDead(_14); ++ StorageDead(_17); ++ StorageDead(_31); ++ StorageDead(_32); ++ discriminant((*_35)) = 3; ++ return; + } + + bb10: { + StorageLive(_29); + _29 = copy ((_21 as Ready).0: std::option::Option<()>); + _10 = copy _29; + StorageDead(_29); + StorageDead(_21); + StorageDead(_20); +- drop(_18) -> [return: bb12, unwind: bb24]; ++ drop((((*_35) as variant#3).3: {async fn body of read_exact()})) -> [return: bb12, unwind: bb19]; + } + + bb11: { + StorageDead(_32); + _2 = move _31; + StorageDead(_31); + _19 = const (); + goto -> bb4; + } + + bb12: { +- StorageDead(_18); +- _9 = Option::<()>::unwrap(move _10) -> [return: bb13, unwind: bb25]; ++ nop; ++ _9 = Option::<()>::unwrap(move _10) -> [return: bb13, unwind: bb20]; + } + + bb13: { + StorageDead(_10); + goto -> bb14; + } + + bb14: { + StorageDead(_17); + StorageDead(_14); + StorageDead(_11); + StorageDead(_9); +- _0 = const (); +- StorageDead(_8); ++ _33 = const (); ++ nop; + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb15, unwind: bb32]; ++ nop; ++ nop; ++ goto -> bb28; + } + + bb15: { ++ _0 = Poll::<()>::Ready(move _33); ++ discriminant((*_35)) = 1; + return; + } + +- bb16: { +- StorageDead(_32); +- StorageDead(_31); +- drop(_18) -> [return: bb17, unwind: bb33]; +- } +- +- bb17: { +- StorageDead(_18); +- StorageDead(_10); +- goto -> bb18; +- } +- +- bb18: { +- StorageDead(_17); +- StorageDead(_14); +- StorageDead(_11); +- StorageDead(_9); +- StorageDead(_8); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb19, unwind: bb32]; +- } +- +- bb19: { +- coroutine_drop; +- } +- +- bb20 (cleanup): { +- StorageDead(_27); +- goto -> bb21; +- } +- +- bb21 (cleanup): { ++ bb16 (cleanup): { + StorageDead(_26); + StorageDead(_25); +- goto -> bb23; ++ goto -> bb18; + } + +- bb22 (cleanup): { ++ bb17 (cleanup): { + StorageDead(_23); +- goto -> bb23; ++ goto -> bb18; + } + +- bb23 (cleanup): { ++ bb18 (cleanup): { + StorageDead(_24); + StorageDead(_22); + StorageDead(_21); + StorageDead(_20); +- drop(_18) -> [return: bb24, unwind terminate(cleanup)]; ++ drop((((*_35) as variant#3).3: {async fn body of read_exact()})) -> [return: bb19, unwind terminate(cleanup)]; + } + +- bb24 (cleanup): { +- StorageDead(_18); +- goto -> bb25; ++ bb19 (cleanup): { ++ nop; ++ goto -> bb20; + } + +- bb25 (cleanup): { ++ bb20 (cleanup): { + StorageDead(_10); +- goto -> bb29; ++ goto -> bb24; + } + +- bb26 (cleanup): { +- goto -> bb28; ++ bb21 (cleanup): { ++ goto -> bb23; + } + +- bb27 (cleanup): { ++ bb22 (cleanup): { + StorageDead(_15); + StorageDead(_13); +- goto -> bb28; ++ goto -> bb23; + } + +- bb28 (cleanup): { ++ bb23 (cleanup): { + StorageDead(_12); + StorageDead(_10); +- goto -> bb29; ++ goto -> bb24; + } + +- bb29 (cleanup): { ++ bb24 (cleanup): { + StorageDead(_17); + StorageDead(_14); + StorageDead(_11); + StorageDead(_9); +- StorageDead(_8); +- goto -> bb31; ++ nop; ++ goto -> bb26; + } + +- bb30 (cleanup): { ++ bb25 (cleanup): { + StorageDead(_7); + StorageDead(_6); +- goto -> bb31; ++ goto -> bb26; + } + +- bb31 (cleanup): { ++ bb26 (cleanup): { + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb32, unwind terminate(cleanup)]; ++ nop; ++ nop; ++ goto -> bb27; + } + +- bb32 (cleanup): { ++ bb27 (cleanup): { ++ goto -> bb29; ++ } ++ ++ bb28: { ++ goto -> bb15; ++ } ++ ++ bb29 (cleanup): { ++ discriminant((*_35)) = 2; + resume; + } + +- bb33 (cleanup): { +- StorageDead(_18); +- StorageDead(_10); +- goto -> bb34; ++ bb30: { ++ StorageLive(_5); ++ StorageLive(_9); ++ StorageLive(_10); ++ StorageLive(_11); ++ StorageLive(_14); ++ StorageLive(_17); ++ StorageLive(_31); ++ StorageLive(_32); ++ _31 = move _2; ++ goto -> bb11; + } + +- bb34 (cleanup): { +- StorageDead(_17); +- StorageDead(_14); +- StorageDead(_11); +- StorageDead(_9); +- StorageDead(_8); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb32, unwind terminate(cleanup)]; ++ bb31: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb31, unwind continue]; ++ } ++ ++ bb32: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb32, unwind continue]; ++ } ++ ++ bb33: { ++ nop; ++ (((*_35) as variant#3).0: [u8; 1]) = [const 0_u8; 1]; ++ nop; ++ StorageLive(_5); ++ StorageLive(_6); ++ _6 = &(((*_35) as variant#3).0: [u8; 1]); ++ StorageLive(_7); ++ _7 = RangeFull; ++ _5 = <[u8; 1] as Index>::index(move _6, move _7) -> [return: bb1, unwind: bb25]; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..2fd801f42122c --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,141 @@ +// MIR for `hello_world::{closure#0}` 0 coroutine_drop + +fn hello_world::{closure#0}(_1: &mut {async fn body of hello_world()}) -> () { + debug _task_context => _2; + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let _3: [u8; 1]; + let _5: &[u8]; + let mut _6: &[u8; 1]; + let mut _7: std::ops::RangeFull; + let _9: (); + let mut _10: std::option::Option<()>; + let mut _11: {async fn body of read_exact()}; + let mut _12: {async fn body of read_exact()}; + let mut _13: &mut &[u8]; + let mut _14: &mut &[u8]; + let mut _15: &mut [u8]; + let mut _16: &mut [u8; 1]; + let mut _17: &mut [u8; 1]; + let mut _19: (); + let _20: (); + let mut _21: std::task::Poll>; + let mut _22: std::pin::Pin<&mut {async fn body of read_exact()}>; + let mut _23: &mut {async fn body of read_exact()}; + let mut _24: &mut {async fn body of read_exact()}; + let mut _25: &mut std::task::Context<'_>; + let mut _26: &mut std::task::Context<'_>; + let mut _27: &mut std::task::Context<'_>; + let mut _28: isize; + let mut _30: !; + let mut _31: &mut std::task::Context<'_>; + let mut _32: (); + let mut _33: (); + let mut _34: u32; + scope 1 { + debug data => (((*_1) as variant#3).0: [u8; 1]); + let mut _4: &[u8]; + scope 2 { + debug reader => (((*_1) as variant#3).1: &[u8]); + let mut _8: [u8; 1]; + scope 3 { + debug marker => (((*_1) as variant#3).2: [u8; 1]); + let mut _18: {async fn body of read_exact()}; + scope 4 { + debug __awaitee => (((*_1) as variant#3).3: {async fn body of read_exact()}); + let _29: std::option::Option<()>; + scope 5 { + debug result => _29; + } + } + } + } + } + + bb0: { + _34 = discriminant((*_1)); + switchInt(move _34) -> [0: bb9, 3: bb12, otherwise: bb13]; + } + + bb1: { + StorageDead(_32); + StorageDead(_31); + drop((((*_1) as variant#3).3: {async fn body of read_exact()})) -> [return: bb2, unwind: bb6]; + } + + bb2: { + nop; + StorageDead(_10); + goto -> bb3; + } + + bb3: { + StorageDead(_17); + StorageDead(_14); + StorageDead(_11); + StorageDead(_9); + nop; + StorageDead(_5); + nop; + nop; + goto -> bb10; + } + + bb4: { + return; + } + + bb5 (cleanup): { + resume; + } + + bb6 (cleanup): { + nop; + StorageDead(_10); + goto -> bb7; + } + + bb7 (cleanup): { + StorageDead(_17); + StorageDead(_14); + StorageDead(_11); + StorageDead(_9); + nop; + StorageDead(_5); + nop; + nop; + goto -> bb5; + } + + bb8: { + return; + } + + bb9: { + goto -> bb11; + } + + bb10: { + goto -> bb4; + } + + bb11: { + goto -> bb8; + } + + bb12: { + StorageLive(_5); + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + StorageLive(_14); + StorageLive(_17); + StorageLive(_31); + StorageLive(_32); + goto -> bb1; + } + + bb13: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..f611658c30174 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,24 @@ +// MIR for `hello_world::{closure#0}` 0 coroutine_drop_proxy_async + +fn hello_world::{closure#0}(_1: {async fn body of hello_world()}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + scope 1 { + scope 2 { + scope 3 { + scope 4 { + scope 5 { + } + } + } + } + } + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..00bddd77b6ced --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff @@ -0,0 +1,78 @@ +- // MIR for `includes_never::{closure#0}::{closure#0}` before StateTransform ++ // MIR for `includes_never::{closure#0}::{closure#0}` after StateTransform + +- fn includes_never::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:61:18: 61:23}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn includes_never::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ } ++ storage_conflicts = BitMatrix(0x0) {} ++ } + debug _task_context => _2; +- debug x => (*(_1.0: &u32)); +- let mut _0: u32; ++ debug x => (*((*_9).0: &u32)); ++ let mut _0: std::task::Poll; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; ++ let mut _7: u32; ++ let mut _8: u32; ++ let mut _9: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; + + bb0: { +- StorageLive(_3); +- _5 = no_retag copy (_1.0: &u32); +- _3 = copy (*_5); +- StorageLive(_4); +- _6 = no_retag copy (_1.0: &u32); +- _4 = copy (*_6); +- _0 = Mul(move _3, move _4); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb1, unwind: bb2]; ++ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}); ++ _8 = discriminant((*_9)); ++ switchInt(move _8) -> [0: bb5, 1: bb3, otherwise: bb4]; + } + + bb1: { ++ _0 = Poll::::Ready(move _7); ++ discriminant((*_9)) = 1; + return; + } + +- bb2 (cleanup): { +- resume; ++ bb2: { ++ goto -> bb1; ++ } ++ ++ bb3: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb3, unwind continue]; ++ } ++ ++ bb4: { ++ unreachable; ++ } ++ ++ bb5: { ++ StorageLive(_3); ++ _5 = no_retag copy ((*_9).0: &u32); ++ _3 = copy (*_5); ++ StorageLive(_4); ++ _6 = no_retag copy ((*_9).0: &u32); ++ _4 = copy (*_6); ++ _7 = Mul(move _3, move _4); ++ StorageDead(_4); ++ StorageDead(_3); ++ goto -> bb2; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..a17dbe3199dee --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,35 @@ +// MIR for `includes_never::{closure#0}::{closure#0}` 0 coroutine_drop + +fn includes_never::{closure#0}::{closure#0}(_1: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}) -> () { + debug _task_context => _2; + debug x => (*((*_1).0: &u32)); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; + let mut _7: u32; + let mut _8: u32; + + bb0: { + _8 = discriminant((*_1)); + switchInt(move _8) -> [0: bb2, otherwise: bb4]; + } + + bb1: { + return; + } + + bb2: { + goto -> bb3; + } + + bb3: { + goto -> bb1; + } + + bb4: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..11fefd8e962c4 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,14 @@ +// MIR for `includes_never::{closure#0}::{closure#0}` 0 coroutine_drop_proxy_async + +fn includes_never::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:61:18: 61:23}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff new file mode 100644 index 0000000000000..b51642673c26c --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff @@ -0,0 +1,78 @@ +- // MIR for `includes_never::{closure#0}::{closure#1}` before StateTransform ++ // MIR for `includes_never::{closure#0}::{closure#1}` after StateTransform + +- fn includes_never::{closure#0}::{closure#1}(_1: {async block@$DIR/async_fn.rs:67:15: 67:20}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn includes_never::{closure#0}::{closure#1}(_1: Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ } ++ storage_conflicts = BitMatrix(0x0) {} ++ } + debug _task_context => _2; +- debug x => (*(_1.0: &u32)); +- let mut _0: u32; ++ debug x => (*((*_9).0: &u32)); ++ let mut _0: std::task::Poll; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; ++ let mut _7: u32; ++ let mut _8: u32; ++ let mut _9: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + + bb0: { +- StorageLive(_3); +- _5 = no_retag copy (_1.0: &u32); +- _3 = copy (*_5); +- StorageLive(_4); +- _6 = no_retag copy (_1.0: &u32); +- _4 = copy (*_6); +- _0 = Add(move _3, move _4); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb1, unwind: bb2]; ++ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}); ++ _8 = discriminant((*_9)); ++ switchInt(move _8) -> [0: bb5, 1: bb3, otherwise: bb4]; + } + + bb1: { ++ _0 = Poll::::Ready(move _7); ++ discriminant((*_9)) = 1; + return; + } + +- bb2 (cleanup): { +- resume; ++ bb2: { ++ goto -> bb1; ++ } ++ ++ bb3: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb3, unwind continue]; ++ } ++ ++ bb4: { ++ unreachable; ++ } ++ ++ bb5: { ++ StorageLive(_3); ++ _5 = no_retag copy ((*_9).0: &u32); ++ _3 = copy (*_5); ++ StorageLive(_4); ++ _6 = no_retag copy ((*_9).0: &u32); ++ _4 = copy (*_6); ++ _7 = Add(move _3, move _4); ++ StorageDead(_4); ++ StorageDead(_3); ++ goto -> bb2; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..bf47e4c62f433 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir @@ -0,0 +1,35 @@ +// MIR for `includes_never::{closure#0}::{closure#1}` 0 coroutine_drop + +fn includes_never::{closure#0}::{closure#1}(_1: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}) -> () { + debug _task_context => _2; + debug x => (*((*_1).0: &u32)); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; + let mut _7: u32; + let mut _8: u32; + + bb0: { + _8 = discriminant((*_1)); + switchInt(move _8) -> [0: bb2, otherwise: bb4]; + } + + bb1: { + return; + } + + bb2: { + goto -> bb3; + } + + bb3: { + goto -> bb1; + } + + bb4: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..8daa763583e8c --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,14 @@ +// MIR for `includes_never::{closure#0}::{closure#1}` 0 coroutine_drop_proxy_async + +fn includes_never::{closure#0}::{closure#1}(_1: {async block@$DIR/async_fn.rs:67:15: 67:20}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..b3d14b5540c88 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.StateTransform.diff @@ -0,0 +1,412 @@ +- // MIR for `includes_never::{closure#0}` before StateTransform ++ // MIR for `includes_never::{closure#0}` after StateTransform + +- fn includes_never::{closure#0}(_1: {async fn body of includes_never()}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn includes_never::{closure#0}(_1: Pin<&mut {async fn body of includes_never()}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ field _s0: bool; ++ field _s1: u32; ++ field _s2: {async block@$DIR/async_fn.rs:61:18: 61:23}; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s2], ++ } ++ storage_conflicts = BitMatrix(3x3) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s2, _s0), (_s2, _s1), (_s2, _s2)} ++ } + debug _task_context => _2; +- debug crash => (_1.0: bool); +- debug x => (_1.1: u32); +- let mut _0: u32; ++ debug crash => ((*_50).0: bool); ++ debug x => ((*_50).1: u32); ++ coroutine debug crash => _s0; ++ let mut _0: std::task::Poll; + let _3: bool; + let mut _6: {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _7: {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _8: &u32; + let mut _10: (); + let _11: (); + let mut _12: std::task::Poll; + let mut _13: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>; + let mut _14: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _15: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut std::task::Context<'_>; +- let mut _18: std::future::ResumeTy; ++ let mut _18: &mut std::task::Context<'_>; + let mut _19: isize; + let mut _21: !; +- let mut _22: std::future::ResumeTy; ++ let mut _22: &mut std::task::Context<'_>; + let mut _23: (); + let _24: (); + let mut _25: bool; + let mut _26: !; + let mut _28: u32; + let mut _29: {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _30: {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _31: &u32; + let _33: (); + let mut _34: std::task::Poll; + let mut _35: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>; + let mut _36: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _37: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _38: &mut std::task::Context<'_>; + let mut _39: &mut std::task::Context<'_>; + let mut _40: std::future::ResumeTy; + let mut _41: isize; + let mut _43: !; + let mut _44: std::future::ResumeTy; + let mut _45: (); + let _46: (); + let mut _47: Never; ++ let mut _48: u32; ++ let mut _49: u32; ++ let mut _50: &mut {async fn body of includes_never()}; + scope 1 { +- debug crash => _3; ++ debug crash => (((*_50) as variant#3).0: bool); ++ coroutine debug x => _s1; + let _4: u32; + scope 2 { +- debug x => _4; ++ debug x => (((*_50) as variant#3).1: u32); ++ coroutine debug __awaitee => _s2; + let _5: u32; + let mut _9: {async block@$DIR/async_fn.rs:61:18: 61:23}; + scope 3 { + debug result => _5; + scope 6 { + debug bad => _27; + let mut _32: {async block@$DIR/async_fn.rs:67:15: 67:20}; + scope 8 { + debug __awaitee => _32; + let _42: u32; + scope 9 { + debug result => _42; + } + } + } + scope 7 { + let _27: Never; + } + } + scope 4 { +- debug __awaitee => _9; ++ debug __awaitee => (((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23}); + let _20: u32; + scope 5 { + debug result => _20; + } + } + } + } + + bb0: { +- StorageLive(_3); +- _3 = copy (_1.0: bool); +- StorageLive(_4); +- _4 = copy (_1.1: u32); +- StorageLive(_5); +- StorageLive(_6); +- StorageLive(_7); +- StorageLive(_8); +- _8 = &_4; +- _7 = {coroutine@$DIR/async_fn.rs:61:18: 61:23 (#0)} { x: move _8 }; +- StorageDead(_8); +- _6 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as IntoFuture>::into_future(move _7) -> [return: bb1, unwind: bb25]; ++ _50 = copy (_1.0: &mut {async fn body of includes_never()}); ++ _49 = discriminant((*_50)); ++ switchInt(move _49) -> [0: bb30, 1: bb29, 2: bb28, 3: bb27, otherwise: bb6]; + } + + bb1: { + StorageDead(_7); + PlaceMention(_6); +- StorageLive(_9); +- _9 = move _6; ++ nop; ++ (((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23}) = move _6; + goto -> bb2; + } + + bb2: { + StorageLive(_11); + StorageLive(_12); + StorageLive(_13); + StorageLive(_14); + StorageLive(_15); +- _15 = &mut _9; ++ _15 = &mut (((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23}); + _14 = &mut (*_15); +- _13 = Pin::<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>::new_unchecked(move _14) -> [return: bb3, unwind: bb22]; ++ _13 = Pin::<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>::new_unchecked(move _14) -> [return: bb3, unwind: bb17]; + } + + bb3: { + StorageDead(_14); + StorageLive(_16); + StorageLive(_17); + StorageLive(_18); + _18 = copy _2; +- _17 = std::future::get_context::<'_, '_>(move _18) -> [return: bb4, unwind: bb20]; ++ _17 = move _18; ++ goto -> bb4; + } + + bb4: { + _16 = &mut (*_17); + StorageDead(_18); +- _12 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as Future>::poll(move _13, move _16) -> [return: bb5, unwind: bb21]; ++ _12 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as Future>::poll(move _13, move _16) -> [return: bb5, unwind: bb16]; + } + + bb5: { + StorageDead(_17); + StorageDead(_16); + StorageDead(_15); + StorageDead(_13); + PlaceMention(_12); + _19 = discriminant(_12); + switchInt(move _19) -> [0: bb8, 1: bb7, otherwise: bb6]; + } + + bb6: { + unreachable; + } + + bb7: { + _11 = const (); + StorageDead(_12); + StorageDead(_11); + StorageLive(_22); + StorageLive(_23); + _23 = (); +- _22 = yield(move _23) -> [resume: bb9, drop: bb15]; ++ _0 = Poll::::Pending; ++ StorageDead(_5); ++ StorageDead(_6); ++ StorageDead(_22); ++ StorageDead(_23); ++ discriminant((*_50)) = 3; ++ return; + } + + bb8: { + StorageLive(_20); + _20 = copy ((_12 as Ready).0: u32); + _5 = copy _20; + StorageDead(_20); + StorageDead(_12); + StorageDead(_11); +- drop(_9) -> [return: bb10, unwind: bb24]; ++ drop((((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb10, unwind: bb19]; + } + + bb9: { + StorageDead(_23); + _2 = move _22; + StorageDead(_22); + _10 = const (); + goto -> bb2; + } + + bb10: { +- StorageDead(_9); ++ nop; + goto -> bb11; + } + + bb11: { + StorageDead(_6); + StorageLive(_24); + StorageLive(_25); +- _25 = copy _3; ++ _25 = copy (((*_50) as variant#3).0: bool); + switchInt(move _25) -> [0: bb12, otherwise: bb13]; + } + + bb12: { +- _0 = copy _5; ++ _48 = copy _5; + StorageDead(_25); + StorageDead(_24); + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb14, unwind: bb29]; ++ nop; ++ nop; ++ goto -> bb25; + } + + bb13: { + _24 = const (); + StorageDead(_25); + StorageDead(_24); + StorageLive(_27); +- _27 = never() -> bb19; ++ _27 = never() -> bb15; + } + + bb14: { ++ _0 = Poll::::Ready(move _48); ++ discriminant((*_50)) = 1; + return; + } + +- bb15: { +- StorageDead(_23); +- StorageDead(_22); +- drop(_9) -> [return: bb16, unwind: bb30]; ++ bb15 (cleanup): { ++ StorageDead(_27); ++ goto -> bb23; + } + +- bb16: { +- StorageDead(_9); +- goto -> bb17; ++ bb16 (cleanup): { ++ StorageDead(_17); ++ StorageDead(_16); ++ goto -> bb18; + } + +- bb17: { +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb18, unwind: bb29]; ++ bb17 (cleanup): { ++ StorageDead(_14); ++ goto -> bb18; + } + +- bb18: { +- coroutine_drop; ++ bb18 (cleanup): { ++ StorageDead(_15); ++ StorageDead(_13); ++ StorageDead(_12); ++ StorageDead(_11); ++ drop((((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb19, unwind terminate(cleanup)]; + } + + bb19 (cleanup): { +- StorageDead(_27); +- goto -> bb28; ++ nop; ++ goto -> bb22; + } + + bb20 (cleanup): { +- StorageDead(_18); + goto -> bb21; + } + + bb21 (cleanup): { +- StorageDead(_17); +- StorageDead(_16); +- goto -> bb23; ++ StorageDead(_7); ++ goto -> bb22; + } + + bb22 (cleanup): { +- StorageDead(_14); ++ StorageDead(_6); + goto -> bb23; + } + + bb23 (cleanup): { +- StorageDead(_15); +- StorageDead(_13); +- StorageDead(_12); +- StorageDead(_11); +- drop(_9) -> [return: bb24, unwind terminate(cleanup)]; ++ StorageDead(_5); ++ nop; ++ nop; ++ goto -> bb24; + } + + bb24 (cleanup): { +- StorageDead(_9); +- goto -> bb27; ++ goto -> bb26; + } + +- bb25 (cleanup): { +- goto -> bb26; ++ bb25: { ++ goto -> bb14; + } + + bb26 (cleanup): { +- StorageDead(_7); +- goto -> bb27; ++ discriminant((*_50)) = 2; ++ resume; + } + +- bb27 (cleanup): { +- StorageDead(_6); +- goto -> bb28; ++ bb27: { ++ StorageLive(_5); ++ StorageLive(_6); ++ StorageLive(_22); ++ StorageLive(_23); ++ _22 = move _2; ++ goto -> bb9; + } + +- bb28 (cleanup): { +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb29, unwind terminate(cleanup)]; ++ bb28: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb28, unwind continue]; + } + +- bb29 (cleanup): { +- resume; ++ bb29: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb29, unwind continue]; + } + +- bb30 (cleanup): { +- StorageDead(_9); +- goto -> bb31; +- } +- +- bb31 (cleanup): { +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb29, unwind terminate(cleanup)]; ++ bb30: { ++ nop; ++ (((*_50) as variant#3).0: bool) = copy ((*_50).0: bool); ++ nop; ++ (((*_50) as variant#3).1: u32) = copy ((*_50).1: u32); ++ StorageLive(_5); ++ StorageLive(_6); ++ StorageLive(_7); ++ StorageLive(_8); ++ _8 = &(((*_50) as variant#3).1: u32); ++ _7 = {coroutine@$DIR/async_fn.rs:61:18: 61:23 (#0)} { x: move _8 }; ++ StorageDead(_8); ++ _6 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as IntoFuture>::into_future(move _7) -> [return: bb1, unwind: bb20]; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..a701710ebfc58 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,155 @@ +// MIR for `includes_never::{closure#0}` 0 coroutine_drop + +fn includes_never::{closure#0}(_1: &mut {async fn body of includes_never()}) -> () { + debug _task_context => _2; + debug crash => ((*_1).0: bool); + debug x => ((*_1).1: u32); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let _3: bool; + let mut _6: {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _7: {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _8: &u32; + let mut _10: (); + let _11: (); + let mut _12: std::task::Poll; + let mut _13: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>; + let mut _14: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _15: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut std::task::Context<'_>; + let mut _19: isize; + let mut _21: !; + let mut _22: &mut std::task::Context<'_>; + let mut _23: (); + let _24: (); + let mut _25: bool; + let mut _26: !; + let mut _28: u32; + let mut _29: {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _30: {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _31: &u32; + let _33: (); + let mut _34: std::task::Poll; + let mut _35: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>; + let mut _36: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _37: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _38: &mut std::task::Context<'_>; + let mut _39: &mut std::task::Context<'_>; + let mut _40: std::future::ResumeTy; + let mut _41: isize; + let mut _43: !; + let mut _44: std::future::ResumeTy; + let mut _45: (); + let _46: (); + let mut _47: Never; + let mut _48: u32; + let mut _49: u32; + scope 1 { + debug crash => (((*_1) as variant#3).0: bool); + let _4: u32; + scope 2 { + debug x => (((*_1) as variant#3).1: u32); + let _5: u32; + let mut _9: {async block@$DIR/async_fn.rs:61:18: 61:23}; + scope 3 { + debug result => _5; + scope 6 { + debug bad => _27; + let mut _32: {async block@$DIR/async_fn.rs:67:15: 67:20}; + scope 8 { + debug __awaitee => _32; + let _42: u32; + scope 9 { + debug result => _42; + } + } + } + scope 7 { + let _27: Never; + } + } + scope 4 { + debug __awaitee => (((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23}); + let _20: u32; + scope 5 { + debug result => _20; + } + } + } + } + + bb0: { + _49 = discriminant((*_1)); + switchInt(move _49) -> [0: bb9, 3: bb12, otherwise: bb13]; + } + + bb1: { + StorageDead(_23); + StorageDead(_22); + drop((((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb2, unwind: bb6]; + } + + bb2: { + nop; + goto -> bb3; + } + + bb3: { + StorageDead(_6); + StorageDead(_5); + nop; + nop; + goto -> bb10; + } + + bb4: { + return; + } + + bb5 (cleanup): { + resume; + } + + bb6 (cleanup): { + nop; + goto -> bb7; + } + + bb7 (cleanup): { + StorageDead(_6); + StorageDead(_5); + nop; + nop; + goto -> bb5; + } + + bb8: { + return; + } + + bb9: { + goto -> bb11; + } + + bb10: { + goto -> bb4; + } + + bb11: { + goto -> bb8; + } + + bb12: { + StorageLive(_5); + StorageLive(_6); + StorageLive(_22); + StorageLive(_23); + goto -> bb1; + } + + bb13: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..4a6ceb7f1d4e9 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,32 @@ +// MIR for `includes_never::{closure#0}` 0 coroutine_drop_proxy_async + +fn includes_never::{closure#0}(_1: {async fn body of includes_never()}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + scope 1 { + scope 2 { + scope 3 { + scope 6 { + scope 8 { + scope 9 { + } + } + } + scope 7 { + } + } + scope 4 { + scope 5 { + } + } + } + } + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..8f66ed130b333 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff @@ -0,0 +1,78 @@ +- // MIR for `partial_init::{closure#0}::{closure#0}` before StateTransform ++ // MIR for `partial_init::{closure#0}::{closure#0}` after StateTransform + +- fn partial_init::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:80:50: 80:55}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn partial_init::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ } ++ storage_conflicts = BitMatrix(0x0) {} ++ } + debug _task_context => _2; +- debug x => (*(_1.0: &u32)); +- let mut _0: u32; ++ debug x => (*((*_9).0: &u32)); ++ let mut _0: std::task::Poll; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; ++ let mut _7: u32; ++ let mut _8: u32; ++ let mut _9: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; + + bb0: { +- StorageLive(_3); +- _5 = no_retag copy (_1.0: &u32); +- _3 = copy (*_5); +- StorageLive(_4); +- _6 = no_retag copy (_1.0: &u32); +- _4 = copy (*_6); +- _0 = Add(move _3, move _4); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb1, unwind: bb2]; ++ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}); ++ _8 = discriminant((*_9)); ++ switchInt(move _8) -> [0: bb5, 1: bb3, otherwise: bb4]; + } + + bb1: { ++ _0 = Poll::::Ready(move _7); ++ discriminant((*_9)) = 1; + return; + } + +- bb2 (cleanup): { +- resume; ++ bb2: { ++ goto -> bb1; ++ } ++ ++ bb3: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb3, unwind continue]; ++ } ++ ++ bb4: { ++ unreachable; ++ } ++ ++ bb5: { ++ StorageLive(_3); ++ _5 = no_retag copy ((*_9).0: &u32); ++ _3 = copy (*_5); ++ StorageLive(_4); ++ _6 = no_retag copy ((*_9).0: &u32); ++ _4 = copy (*_6); ++ _7 = Add(move _3, move _4); ++ StorageDead(_4); ++ StorageDead(_3); ++ goto -> bb2; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..0261bfd7236f2 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,35 @@ +// MIR for `partial_init::{closure#0}::{closure#0}` 0 coroutine_drop + +fn partial_init::{closure#0}::{closure#0}(_1: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}) -> () { + debug _task_context => _2; + debug x => (*((*_1).0: &u32)); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let mut _3: u32; + let mut _4: u32; + let mut _5: &u32; + let mut _6: &u32; + let mut _7: u32; + let mut _8: u32; + + bb0: { + _8 = discriminant((*_1)); + switchInt(move _8) -> [0: bb2, otherwise: bb4]; + } + + bb1: { + return; + } + + bb2: { + goto -> bb3; + } + + bb3: { + goto -> bb1; + } + + bb4: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..3ddd757ef84e6 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,14 @@ +// MIR for `partial_init::{closure#0}::{closure#0}` 0 coroutine_drop_proxy_async + +fn partial_init::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:80:50: 80:55}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..7acd06e5e900c --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.StateTransform.diff @@ -0,0 +1,387 @@ +- // MIR for `partial_init::{closure#0}` before StateTransform ++ // MIR for `partial_init::{closure#0}` after StateTransform + +- fn partial_init::{closure#0}(_1: {async fn body of partial_init()}, _2: std::future::ResumeTy) -> u32 +- yields () +- { ++ fn partial_init::{closure#0}(_1: Pin<&mut {async fn body of partial_init()}>, _2: &mut Context<'_>) -> Poll { ++ coroutine layout { ++ field _s0: u32; ++ field _s1: String; ++ field _s2: {async block@$DIR/async_fn.rs:80:50: 80:55}; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s2], ++ } ++ storage_conflicts = BitMatrix(3x3) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s2, _s0), (_s2, _s1), (_s2, _s2)} ++ } + debug _task_context => _2; +- debug x => (_1.0: u32); +- let mut _0: u32; ++ debug x => ((*_28).0: u32); ++ coroutine debug x => _s0; ++ let mut _0: std::task::Poll; + let _3: u32; + let mut _4: !; + let mut _6: std::string::String; + let mut _7: !; + let mut _8: {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _9: {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _10: &u32; + let mut _12: (); + let _13: (); + let mut _14: std::task::Poll; + let mut _15: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>; + let mut _16: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _17: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _18: &mut std::task::Context<'_>; + let mut _19: &mut std::task::Context<'_>; +- let mut _20: std::future::ResumeTy; ++ let mut _20: &mut std::task::Context<'_>; + let mut _21: isize; + let mut _23: !; +- let mut _24: std::future::ResumeTy; ++ let mut _24: &mut std::task::Context<'_>; + let mut _25: (); ++ let mut _26: u32; ++ let mut _27: u32; ++ let mut _28: &mut {async fn body of partial_init()}; + scope 1 { +- debug x => _3; ++ debug x => (((*_28) as variant#3).0: u32); + scope 2 { + debug _x => _5; + } + scope 3 { ++ coroutine debug __awaitee => _s2; + let _5: (std::string::String, !); + let mut _11: {async block@$DIR/async_fn.rs:80:50: 80:55}; + scope 4 { +- debug __awaitee => _11; ++ debug __awaitee => (((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55}); + let _22: u32; + scope 5 { + debug result => _22; + } + } + } + } + + bb0: { +- StorageLive(_3); +- _3 = copy (_1.0: u32); +- StorageLive(_4); +- StorageLive(_5); +- StorageLive(_6); +- _6 = String::new() -> [return: bb1, unwind: bb30]; ++ _28 = copy (_1.0: &mut {async fn body of partial_init()}); ++ _27 = discriminant((*_28)); ++ switchInt(move _27) -> [0: bb32, 1: bb31, 2: bb30, 3: bb29, otherwise: bb7]; + } + + bb1: { + StorageLive(_8); + StorageLive(_9); + StorageLive(_10); +- _10 = &_3; ++ _10 = &(((*_28) as variant#3).0: u32); + _9 = {coroutine@$DIR/async_fn.rs:80:50: 80:55 (#0)} { x: move _10 }; + StorageDead(_10); +- _8 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as IntoFuture>::into_future(move _9) -> [return: bb2, unwind: bb26]; ++ _8 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as IntoFuture>::into_future(move _9) -> [return: bb2, unwind: bb20]; + } + + bb2: { + StorageDead(_9); + PlaceMention(_8); +- StorageLive(_11); +- _11 = move _8; ++ nop; ++ (((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55}) = move _8; + goto -> bb3; + } + + bb3: { + StorageLive(_13); + StorageLive(_14); + StorageLive(_15); + StorageLive(_16); + StorageLive(_17); +- _17 = &mut _11; ++ _17 = &mut (((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55}); + _16 = &mut (*_17); +- _15 = Pin::<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>::new_unchecked(move _16) -> [return: bb4, unwind: bb22]; ++ _15 = Pin::<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>::new_unchecked(move _16) -> [return: bb4, unwind: bb16]; + } + + bb4: { + StorageDead(_16); + StorageLive(_18); + StorageLive(_19); + StorageLive(_20); + _20 = copy _2; +- _19 = std::future::get_context::<'_, '_>(move _20) -> [return: bb5, unwind: bb20]; ++ _19 = move _20; ++ goto -> bb5; + } + + bb5: { + _18 = &mut (*_19); + StorageDead(_20); +- _14 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as Future>::poll(move _15, move _18) -> [return: bb6, unwind: bb21]; ++ _14 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as Future>::poll(move _15, move _18) -> [return: bb6, unwind: bb15]; + } + + bb6: { + StorageDead(_19); + StorageDead(_18); + StorageDead(_17); + StorageDead(_15); + PlaceMention(_14); + _21 = discriminant(_14); + switchInt(move _21) -> [0: bb9, 1: bb8, otherwise: bb7]; + } + + bb7: { + unreachable; + } + + bb8: { + _13 = const (); + StorageDead(_14); + StorageDead(_13); + StorageLive(_24); + StorageLive(_25); + _25 = (); +- _24 = yield(move _25) -> [resume: bb10, drop: bb15]; ++ _0 = Poll::::Pending; ++ StorageDead(_4); ++ StorageDead(_5); ++ StorageDead(_8); ++ StorageDead(_24); ++ StorageDead(_25); ++ discriminant((*_28)) = 3; ++ return; + } + + bb9: { + StorageLive(_22); + _22 = copy ((_14 as Ready).0: u32); +- _0 = copy _22; ++ _26 = copy _22; + StorageDead(_22); + StorageDead(_14); + StorageDead(_13); +- drop(_11) -> [return: bb11, unwind: bb24]; ++ drop((((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb11, unwind: bb18]; + } + + bb10: { + StorageDead(_25); + _2 = move _24; + StorageDead(_24); + _12 = const (); + goto -> bb3; + } + + bb11: { +- StorageDead(_11); +- drop(_6) -> [return: bb12, unwind: bb25]; ++ nop; ++ drop((((*_28) as variant#3).1: std::string::String)) -> [return: bb12, unwind: bb19]; + } + + bb12: { +- StorageDead(_6); ++ nop; + goto -> bb13; + } + + bb13: { + StorageDead(_8); + StorageDead(_5); + StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb14, unwind: bb32]; ++ nop; ++ goto -> bb27; + } + + bb14: { ++ _0 = Poll::::Ready(move _26); ++ discriminant((*_28)) = 1; + return; + } + +- bb15: { +- StorageDead(_25); +- StorageDead(_24); +- drop(_11) -> [return: bb16, unwind: bb33]; ++ bb15 (cleanup): { ++ StorageDead(_19); ++ StorageDead(_18); ++ goto -> bb17; + } + +- bb16: { +- StorageDead(_11); +- drop(_6) -> [return: bb17, unwind: bb34]; ++ bb16 (cleanup): { ++ StorageDead(_16); ++ goto -> bb17; + } + +- bb17: { +- StorageDead(_6); +- goto -> bb18; ++ bb17 (cleanup): { ++ StorageDead(_17); ++ StorageDead(_15); ++ StorageDead(_14); ++ StorageDead(_13); ++ drop((((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb18, unwind terminate(cleanup)]; + } + +- bb18: { +- StorageDead(_8); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb19, unwind: bb32]; ++ bb18 (cleanup): { ++ nop; ++ drop((((*_28) as variant#3).1: std::string::String)) -> [return: bb19, unwind terminate(cleanup)]; + } + +- bb19: { +- coroutine_drop; ++ bb19 (cleanup): { ++ nop; ++ goto -> bb23; + } + + bb20 (cleanup): { +- StorageDead(_20); + goto -> bb21; + } + + bb21 (cleanup): { +- StorageDead(_19); +- StorageDead(_18); +- goto -> bb23; ++ StorageDead(_9); ++ drop((((*_28) as variant#3).1: std::string::String)) -> [return: bb22, unwind terminate(cleanup)]; + } + + bb22 (cleanup): { +- StorageDead(_16); ++ nop; + goto -> bb23; + } + + bb23 (cleanup): { +- StorageDead(_17); +- StorageDead(_15); +- StorageDead(_14); +- StorageDead(_13); +- drop(_11) -> [return: bb24, unwind terminate(cleanup)]; ++ StorageDead(_8); ++ goto -> bb25; + } + + bb24 (cleanup): { +- StorageDead(_11); +- drop(_6) -> [return: bb25, unwind terminate(cleanup)]; ++ nop; ++ goto -> bb25; + } + + bb25 (cleanup): { +- StorageDead(_6); +- goto -> bb29; ++ StorageDead(_5); ++ StorageDead(_4); ++ nop; ++ goto -> bb26; + } + + bb26 (cleanup): { +- goto -> bb27; ++ goto -> bb28; + } + +- bb27 (cleanup): { +- StorageDead(_9); +- drop(_6) -> [return: bb28, unwind terminate(cleanup)]; ++ bb27: { ++ goto -> bb14; + } + + bb28 (cleanup): { +- StorageDead(_6); +- goto -> bb29; ++ discriminant((*_28)) = 2; ++ resume; + } + +- bb29 (cleanup): { +- StorageDead(_8); +- goto -> bb31; ++ bb29: { ++ StorageLive(_4); ++ StorageLive(_5); ++ StorageLive(_8); ++ StorageLive(_24); ++ StorageLive(_25); ++ _24 = move _2; ++ goto -> bb10; + } + +- bb30 (cleanup): { +- StorageDead(_6); +- goto -> bb31; ++ bb30: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb30, unwind continue]; + } + +- bb31 (cleanup): { +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb32, unwind terminate(cleanup)]; ++ bb31: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb31, unwind continue]; + } + +- bb32 (cleanup): { +- resume; +- } +- +- bb33 (cleanup): { +- StorageDead(_11); +- drop(_6) -> [return: bb34, unwind terminate(cleanup)]; +- } +- +- bb34 (cleanup): { +- StorageDead(_6); +- goto -> bb35; +- } +- +- bb35 (cleanup): { +- StorageDead(_8); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb32, unwind terminate(cleanup)]; ++ bb32: { ++ nop; ++ (((*_28) as variant#3).0: u32) = copy ((*_28).0: u32); ++ StorageLive(_4); ++ StorageLive(_5); ++ nop; ++ (((*_28) as variant#3).1: std::string::String) = String::new() -> [return: bb1, unwind: bb24]; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..20525a4cc712d --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,131 @@ +// MIR for `partial_init::{closure#0}` 0 coroutine_drop + +fn partial_init::{closure#0}(_1: &mut {async fn body of partial_init()}) -> () { + debug _task_context => _2; + debug x => ((*_1).0: u32); + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let _3: u32; + let mut _4: !; + let mut _6: std::string::String; + let mut _7: !; + let mut _8: {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _9: {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _10: &u32; + let mut _12: (); + let _13: (); + let mut _14: std::task::Poll; + let mut _15: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>; + let mut _16: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _17: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _18: &mut std::task::Context<'_>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: &mut std::task::Context<'_>; + let mut _21: isize; + let mut _23: !; + let mut _24: &mut std::task::Context<'_>; + let mut _25: (); + let mut _26: u32; + let mut _27: u32; + scope 1 { + debug x => (((*_1) as variant#3).0: u32); + scope 2 { + debug _x => _5; + } + scope 3 { + let _5: (std::string::String, !); + let mut _11: {async block@$DIR/async_fn.rs:80:50: 80:55}; + scope 4 { + debug __awaitee => (((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55}); + let _22: u32; + scope 5 { + debug result => _22; + } + } + } + } + + bb0: { + _27 = discriminant((*_1)); + switchInt(move _27) -> [0: bb11, 3: bb14, otherwise: bb15]; + } + + bb1: { + StorageDead(_25); + StorageDead(_24); + drop((((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb2, unwind: bb7]; + } + + bb2: { + nop; + drop((((*_1) as variant#3).1: std::string::String)) -> [return: bb3, unwind: bb8]; + } + + bb3: { + nop; + goto -> bb4; + } + + bb4: { + StorageDead(_8); + StorageDead(_5); + StorageDead(_4); + nop; + goto -> bb12; + } + + bb5: { + return; + } + + bb6 (cleanup): { + resume; + } + + bb7 (cleanup): { + nop; + drop((((*_1) as variant#3).1: std::string::String)) -> [return: bb8, unwind terminate(cleanup)]; + } + + bb8 (cleanup): { + nop; + goto -> bb9; + } + + bb9 (cleanup): { + StorageDead(_8); + StorageDead(_5); + StorageDead(_4); + nop; + goto -> bb6; + } + + bb10: { + return; + } + + bb11: { + goto -> bb13; + } + + bb12: { + goto -> bb5; + } + + bb13: { + goto -> bb10; + } + + bb14: { + StorageLive(_4); + StorageLive(_5); + StorageLive(_8); + StorageLive(_24); + StorageLive(_25); + goto -> bb1; + } + + bb15: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..1f67854bef25c --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,24 @@ +// MIR for `partial_init::{closure#0}` 0 coroutine_drop_proxy_async + +fn partial_init::{closure#0}(_1: {async fn body of partial_init()}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + scope 1 { + scope 2 { + } + scope 3 { + scope 4 { + scope 5 { + } + } + } + } + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.rs b/tests/mir-opt/coroutine/async_fn.rs new file mode 100644 index 0000000000000..2e8f2e1d9973b --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.rs @@ -0,0 +1,139 @@ +//@ skip-filecheck +//@ compile-flags: -Zmir-opt-level=0 +//@ needs-unwind +//@ edition: 2024 + +#![feature(never_type)] + +use std::future::Future; + +// See if we can run a basic `async fn` +// EMIT_MIR async_fn.foo-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.foo-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir +// EMIT_MIR async_fn.foo-{closure#0}-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.foo-{closure#0}-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir +pub async fn foo(x: &u32, y: u32) -> u32 { + let y = &y; + let z = 9; + let z = &z; + let y = async { *y + *z }.await; + let a = 10; + let a = &a; + *x + y + *a +} + +// EMIT_MIR async_fn.add-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.add-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir +// EMIT_MIR async_fn.add-{closure#0}-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir +async fn add(x: u32, y: u32) -> u32 { + let a = async { x + y }; + a.await +} + +// EMIT_MIR async_fn.build_aggregate-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.build_aggregate-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir +async fn build_aggregate(a: u32, b: u32, c: u32, d: u32) -> u32 { + let x = (add(a, b).await, add(c, d).await); + x.0 + x.1 +} + +enum Never {} +fn never() -> Never { + panic!() +} + +// EMIT_MIR async_fn.includes_never-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.includes_never-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir +// EMIT_MIR async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir +// EMIT_MIR async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff +// EMIT_MIR async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir +// EMIT_MIR async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir +async fn includes_never(crash: bool, x: u32) -> u32 { + let result = async { x * x }.await; + if !crash { + return result; + } + #[allow(unused)] + let bad = never(); + result *= async { x + x }.await; + drop(bad); + result +} + +// EMIT_MIR async_fn.partial_init-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.partial_init-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir +// EMIT_MIR async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir +async fn partial_init(x: u32) -> u32 { + #[allow(unreachable_code)] + let _x: (String, !) = (String::new(), return async { x + x }.await); +} + +async fn read_exact(_from: &mut &[u8], _to: &mut [u8]) -> Option<()> { + Some(()) +} + +// EMIT_MIR async_fn.hello_world-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.hello_world-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir +async fn hello_world() { + let data = [0u8; 1]; + let mut reader = &data[..]; + + let mut marker = [0u8; 1]; + read_exact(&mut reader, &mut marker).await.unwrap(); +} + +// This example comes from https://github.com/rust-lang/rust/issues/115145 +// EMIT_MIR async_fn.uninhabited_variant-{closure#0}.StateTransform.diff +// EMIT_MIR async_fn.uninhabited_variant-{closure#0}.coroutine_drop.0.mir +// EMIT_MIR async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir +#[allow(unreachable_patterns)] +async fn uninhabited_variant() { + async fn unreachable(_: Never) {} + + let c = async {}; + match None:: { + None => { + c.await; + } + Some(r) => { + unreachable(r).await; + } + } +} + +fn run_fut(fut: impl Future) -> T { + use std::task::{Context, Poll, Waker}; + + let mut context = Context::from_waker(Waker::noop()); + + let mut pinned = Box::pin(fut); + loop { + match pinned.as_mut().poll(&mut context) { + Poll::Pending => continue, + Poll::Ready(v) => return v, + } + } +} + +fn main() { + let x = 5; + assert_eq!(run_fut(foo(&x, 7)), 31); + assert_eq!(run_fut(build_aggregate(1, 2, 3, 4)), 10); + assert_eq!(run_fut(includes_never(false, 4)), 16); + assert_eq!(run_fut(partial_init(4)), 8); + run_fut(hello_world()); + run_fut(uninhabited_variant()); +} diff --git a/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..f29242c468c04 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.StateTransform.diff @@ -0,0 +1,683 @@ +- // MIR for `uninhabited_variant::{closure#0}` before StateTransform ++ // MIR for `uninhabited_variant::{closure#0}` after StateTransform + +- fn uninhabited_variant::{closure#0}(_1: {async fn body of uninhabited_variant()}, _2: std::future::ResumeTy) -> () +- yields () +- { ++ fn uninhabited_variant::{closure#0}(_1: Pin<&mut {async fn body of uninhabited_variant()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: {async block@$DIR/async_fn.rs:106:13: 106:18}; ++ field _s1: {async block@$DIR/async_fn.rs:106:13: 106:18}; ++ field _s2: {async fn body of uninhabited_variant::{closure#0}::unreachable()}; ++ field _s3: bool; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s1, _s3], ++ Suspend1 (4): [_s0, _s2, _s3], ++ } ++ storage_conflicts = BitMatrix(4x4) {(_s0, _s0), (_s0, _s2), (_s0, _s3), (_s1, _s1), (_s1, _s3), (_s2, _s0), (_s2, _s2), (_s2, _s3), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3)} ++ } + debug _task_context => _2; +- let mut _0: (); ++ coroutine debug c => _s0; ++ let mut _0: std::task::Poll<()>; + let _3: {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _4: std::option::Option; + let mut _5: isize; + let _6: (); + let mut _7: {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _8: {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _10: (); + let _11: (); + let mut _12: std::task::Poll<()>; + let mut _13: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:106:13: 106:18}>; + let mut _14: &mut {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _15: &mut {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut std::task::Context<'_>; +- let mut _18: std::future::ResumeTy; ++ let mut _18: &mut std::task::Context<'_>; + let mut _19: isize; + let mut _21: !; +- let mut _22: std::future::ResumeTy; ++ let mut _22: &mut std::task::Context<'_>; + let mut _23: (); + let _25: (); + let mut _26: {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + let mut _27: {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + let mut _28: Never; + let _30: (); + let mut _31: std::task::Poll<()>; + let mut _32: std::pin::Pin<&mut {async fn body of uninhabited_variant::{closure#0}::unreachable()}>; + let mut _33: &mut {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + let mut _34: &mut {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + let mut _35: &mut std::task::Context<'_>; + let mut _36: &mut std::task::Context<'_>; +- let mut _37: std::future::ResumeTy; ++ let mut _37: &mut std::task::Context<'_>; + let mut _38: isize; + let mut _40: !; +- let mut _41: std::future::ResumeTy; ++ let mut _41: &mut std::task::Context<'_>; + let mut _42: (); + let mut _43: bool; ++ let mut _44: (); ++ let mut _45: u32; ++ let mut _46: &mut {async fn body of uninhabited_variant()}; + scope 1 { +- debug c => _3; ++ debug c => (((*_46) as variant#4).0: {async block@$DIR/async_fn.rs:106:13: 106:18}); ++ coroutine debug __awaitee => _s1; + let mut _9: {async block@$DIR/async_fn.rs:106:13: 106:18}; + let _24: Never; + scope 2 { +- debug __awaitee => _9; ++ debug __awaitee => (((*_46) as variant#3).0: {async block@$DIR/async_fn.rs:106:13: 106:18}); + let _20: (); + scope 3 { + debug result => _20; + } + } + scope 4 { + debug r => _24; ++ coroutine debug __awaitee => _s2; + let mut _29: {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + scope 5 { +- debug __awaitee => _29; ++ debug __awaitee => (((*_46) as variant#4).1: {async fn body of uninhabited_variant::{closure#0}::unreachable()}); + let _39: (); + scope 6 { + debug result => _39; + } + } + } + } + + bb0: { +- _43 = const false; +- StorageLive(_3); +- _43 = const true; +- _3 = {coroutine@$DIR/async_fn.rs:106:13: 106:18 (#0)}; +- StorageLive(_4); +- _4 = Option::::None; +- PlaceMention(_4); +- _5 = discriminant(_4); +- switchInt(move _5) -> [0: bb3, 1: bb2, otherwise: bb1]; ++ _46 = copy (_1.0: &mut {async fn body of uninhabited_variant()}); ++ _45 = discriminant((*_46)); ++ switchInt(move _45) -> [0: bb56, 1: bb55, 2: bb54, 3: bb52, 4: bb53, otherwise: bb1]; + } + + bb1: { + unreachable; + } + + bb2: { + StorageLive(_24); + _24 = move ((_4 as Some).0: Never); + StorageLive(_25); + StorageLive(_26); + StorageLive(_27); + StorageLive(_28); + _28 = move _24; +- _27 = uninhabited_variant::{closure#0}::unreachable(move _28) -> [return: bb14, unwind: bb43]; ++ _27 = uninhabited_variant::{closure#0}::unreachable(move _28) -> [return: bb14, unwind: bb33]; + } + + bb3: { + StorageLive(_6); + StorageLive(_7); + StorageLive(_8); +- _43 = const false; +- _8 = move _3; +- _7 = <{async block@$DIR/async_fn.rs:106:13: 106:18} as IntoFuture>::into_future(move _8) -> [return: bb4, unwind: bb51]; ++ (((*_46) as variant#4).2: bool) = const false; ++ _8 = move (((*_46) as variant#4).0: {async block@$DIR/async_fn.rs:106:13: 106:18}); ++ _7 = <{async block@$DIR/async_fn.rs:106:13: 106:18} as IntoFuture>::into_future(move _8) -> [return: bb4, unwind: bb40]; + } + + bb4: { + StorageDead(_8); + PlaceMention(_7); +- StorageLive(_9); +- _9 = move _7; ++ nop; ++ (((*_46) as variant#3).0: {async block@$DIR/async_fn.rs:106:13: 106:18}) = move _7; + goto -> bb5; + } + + bb5: { + StorageLive(_11); + StorageLive(_12); + StorageLive(_13); + StorageLive(_14); + StorageLive(_15); +- _15 = &mut _9; ++ _15 = &mut (((*_46) as variant#3).0: {async block@$DIR/async_fn.rs:106:13: 106:18}); + _14 = &mut (*_15); +- _13 = Pin::<&mut {async block@$DIR/async_fn.rs:106:13: 106:18}>::new_unchecked(move _14) -> [return: bb6, unwind: bb48]; ++ _13 = Pin::<&mut {async block@$DIR/async_fn.rs:106:13: 106:18}>::new_unchecked(move _14) -> [return: bb6, unwind: bb37]; + } + + bb6: { + StorageDead(_14); + StorageLive(_16); + StorageLive(_17); + StorageLive(_18); + _18 = copy _2; +- _17 = std::future::get_context::<'_, '_>(move _18) -> [return: bb7, unwind: bb46]; ++ _17 = move _18; ++ goto -> bb7; + } + + bb7: { + _16 = &mut (*_17); + StorageDead(_18); +- _12 = <{async block@$DIR/async_fn.rs:106:13: 106:18} as Future>::poll(move _13, move _16) -> [return: bb8, unwind: bb47]; ++ _12 = <{async block@$DIR/async_fn.rs:106:13: 106:18} as Future>::poll(move _13, move _16) -> [return: bb8, unwind: bb36]; + } + + bb8: { + StorageDead(_17); + StorageDead(_16); + StorageDead(_15); + StorageDead(_13); + PlaceMention(_12); + _19 = discriminant(_12); + switchInt(move _19) -> [0: bb10, 1: bb9, otherwise: bb1]; + } + + bb9: { + _11 = const (); + StorageDead(_12); + StorageDead(_11); + StorageLive(_22); + StorageLive(_23); + _23 = (); +- _22 = yield(move _23) -> [resume: bb11, drop: bb31]; ++ _0 = Poll::<()>::Pending; ++ StorageDead(_4); ++ StorageDead(_6); ++ StorageDead(_7); ++ StorageDead(_22); ++ StorageDead(_23); ++ discriminant((*_46)) = 3; ++ return; + } + + bb10: { + StorageLive(_20); + _20 = copy ((_12 as Ready).0: ()); + _6 = copy _20; + StorageDead(_20); + StorageDead(_12); + StorageDead(_11); +- drop(_9) -> [return: bb12, unwind: bb50]; ++ drop((((*_46) as variant#3).0: {async block@$DIR/async_fn.rs:106:13: 106:18})) -> [return: bb12, unwind: bb39]; + } + + bb11: { + StorageDead(_23); + _2 = move _22; + StorageDead(_22); + _10 = const (); + goto -> bb5; + } + + bb12: { +- StorageDead(_9); ++ nop; + goto -> bb13; + } + + bb13: { + StorageDead(_7); + StorageDead(_6); +- _0 = const (); ++ _44 = const (); + goto -> bb25; + } + + bb14: { + StorageDead(_28); +- _26 = <{async fn body of uninhabited_variant::{closure#0}::unreachable()} as IntoFuture>::into_future(move _27) -> [return: bb15, unwind: bb42]; ++ _26 = <{async fn body of uninhabited_variant::{closure#0}::unreachable()} as IntoFuture>::into_future(move _27) -> [return: bb15, unwind: bb32]; + } + + bb15: { + StorageDead(_27); + PlaceMention(_26); +- StorageLive(_29); +- _29 = move _26; ++ nop; ++ (((*_46) as variant#4).1: {async fn body of uninhabited_variant::{closure#0}::unreachable()}) = move _26; + goto -> bb16; + } + + bb16: { + StorageLive(_30); + StorageLive(_31); + StorageLive(_32); + StorageLive(_33); + StorageLive(_34); +- _34 = &mut _29; ++ _34 = &mut (((*_46) as variant#4).1: {async fn body of uninhabited_variant::{closure#0}::unreachable()}); + _33 = &mut (*_34); +- _32 = Pin::<&mut {async fn body of uninhabited_variant::{closure#0}::unreachable()}>::new_unchecked(move _33) -> [return: bb17, unwind: bb39]; ++ _32 = Pin::<&mut {async fn body of uninhabited_variant::{closure#0}::unreachable()}>::new_unchecked(move _33) -> [return: bb17, unwind: bb29]; + } + + bb17: { + StorageDead(_33); + StorageLive(_35); + StorageLive(_36); + StorageLive(_37); + _37 = copy _2; +- _36 = std::future::get_context::<'_, '_>(move _37) -> [return: bb18, unwind: bb37]; ++ _36 = move _37; ++ goto -> bb18; + } + + bb18: { + _35 = &mut (*_36); + StorageDead(_37); +- _31 = <{async fn body of uninhabited_variant::{closure#0}::unreachable()} as Future>::poll(move _32, move _35) -> [return: bb19, unwind: bb38]; ++ _31 = <{async fn body of uninhabited_variant::{closure#0}::unreachable()} as Future>::poll(move _32, move _35) -> [return: bb19, unwind: bb28]; + } + + bb19: { + StorageDead(_36); + StorageDead(_35); + StorageDead(_34); + StorageDead(_32); + PlaceMention(_31); + _38 = discriminant(_31); + switchInt(move _38) -> [0: bb21, 1: bb20, otherwise: bb1]; + } + + bb20: { + _30 = const (); + StorageDead(_31); + StorageDead(_30); + StorageLive(_41); + StorageLive(_42); + _42 = (); +- _41 = yield(move _42) -> [resume: bb22, drop: bb28]; ++ _0 = Poll::<()>::Pending; ++ StorageDead(_4); ++ StorageDead(_24); ++ StorageDead(_25); ++ StorageDead(_26); ++ StorageDead(_41); ++ StorageDead(_42); ++ discriminant((*_46)) = 4; ++ return; + } + + bb21: { + StorageLive(_39); + _39 = copy ((_31 as Ready).0: ()); + _25 = copy _39; + StorageDead(_39); + StorageDead(_31); + StorageDead(_30); +- drop(_29) -> [return: bb23, unwind: bb41]; ++ drop((((*_46) as variant#4).1: {async fn body of uninhabited_variant::{closure#0}::unreachable()})) -> [return: bb23, unwind: bb31]; + } + + bb22: { + StorageDead(_42); + _2 = move _41; + StorageDead(_41); + _10 = const (); + goto -> bb16; + } + + bb23: { +- StorageDead(_29); ++ nop; + goto -> bb24; + } + + bb24: { + StorageDead(_26); + StorageDead(_25); +- _0 = const (); ++ _44 = const (); + StorageDead(_24); + goto -> bb25; + } + + bb25: { + StorageDead(_4); +- goto -> bb64; ++ goto -> bb47; + } + + bb26: { +- _43 = const false; +- StorageDead(_3); +- drop(_1) -> [return: bb27, unwind: bb56]; ++ (((*_46) as variant#4).2: bool) = const false; ++ nop; ++ goto -> bb50; + } + + bb27: { ++ _0 = Poll::<()>::Ready(move _44); ++ discriminant((*_46)) = 1; + return; + } + +- bb28: { +- StorageDead(_42); +- StorageDead(_41); +- drop(_29) -> [return: bb29, unwind: bb57]; +- } +- +- bb29: { +- StorageDead(_29); +- goto -> bb30; +- } +- +- bb30: { +- StorageDead(_26); +- StorageDead(_25); +- StorageDead(_24); +- goto -> bb34; +- } +- +- bb31: { +- StorageDead(_23); +- StorageDead(_22); +- drop(_9) -> [return: bb32, unwind: bb59]; +- } +- +- bb32: { +- StorageDead(_9); +- goto -> bb33; +- } +- +- bb33: { +- StorageDead(_7); +- StorageDead(_6); +- goto -> bb34; +- } +- +- bb34: { +- StorageDead(_4); +- goto -> bb66; +- } +- +- bb35: { +- _43 = const false; +- StorageDead(_3); +- drop(_1) -> [return: bb36, unwind: bb56]; +- } +- +- bb36: { +- coroutine_drop; +- } +- +- bb37 (cleanup): { +- StorageDead(_37); +- goto -> bb38; +- } +- +- bb38 (cleanup): { ++ bb28 (cleanup): { + StorageDead(_36); + StorageDead(_35); +- goto -> bb40; ++ goto -> bb30; + } + +- bb39 (cleanup): { ++ bb29 (cleanup): { + StorageDead(_33); +- goto -> bb40; ++ goto -> bb30; + } + +- bb40 (cleanup): { ++ bb30 (cleanup): { + StorageDead(_34); + StorageDead(_32); + StorageDead(_31); + StorageDead(_30); +- drop(_29) -> [return: bb41, unwind terminate(cleanup)]; ++ drop((((*_46) as variant#4).1: {async fn body of uninhabited_variant::{closure#0}::unreachable()})) -> [return: bb31, unwind terminate(cleanup)]; + } + +- bb41 (cleanup): { +- StorageDead(_29); +- goto -> bb45; ++ bb31 (cleanup): { ++ nop; ++ goto -> bb35; + } + +- bb42 (cleanup): { +- goto -> bb44; ++ bb32 (cleanup): { ++ goto -> bb34; + } + +- bb43 (cleanup): { ++ bb33 (cleanup): { + StorageDead(_28); +- goto -> bb44; ++ goto -> bb34; + } + +- bb44 (cleanup): { ++ bb34 (cleanup): { + StorageDead(_27); +- goto -> bb45; ++ goto -> bb35; + } + +- bb45 (cleanup): { ++ bb35 (cleanup): { + StorageDead(_26); + StorageDead(_25); + StorageDead(_24); +- goto -> bb54; ++ goto -> bb43; + } + +- bb46 (cleanup): { +- StorageDead(_18); +- goto -> bb47; +- } +- +- bb47 (cleanup): { ++ bb36 (cleanup): { + StorageDead(_17); + StorageDead(_16); +- goto -> bb49; ++ goto -> bb38; + } + +- bb48 (cleanup): { ++ bb37 (cleanup): { + StorageDead(_14); +- goto -> bb49; ++ goto -> bb38; + } + +- bb49 (cleanup): { ++ bb38 (cleanup): { + StorageDead(_15); + StorageDead(_13); + StorageDead(_12); + StorageDead(_11); +- drop(_9) -> [return: bb50, unwind terminate(cleanup)]; ++ drop((((*_46) as variant#3).0: {async block@$DIR/async_fn.rs:106:13: 106:18})) -> [return: bb39, unwind terminate(cleanup)]; + } + +- bb50 (cleanup): { +- StorageDead(_9); +- goto -> bb53; ++ bb39 (cleanup): { ++ nop; ++ goto -> bb42; + } + +- bb51 (cleanup): { +- goto -> bb52; ++ bb40 (cleanup): { ++ goto -> bb41; + } + +- bb52 (cleanup): { ++ bb41 (cleanup): { + StorageDead(_8); +- goto -> bb53; ++ goto -> bb42; + } + +- bb53 (cleanup): { ++ bb42 (cleanup): { + StorageDead(_7); + StorageDead(_6); +- goto -> bb54; ++ goto -> bb43; + } + +- bb54 (cleanup): { ++ bb43 (cleanup): { + StorageDead(_4); +- goto -> bb68; ++ goto -> bb49; + } + +- bb55 (cleanup): { +- _43 = const false; +- StorageDead(_3); +- drop(_1) -> [return: bb56, unwind terminate(cleanup)]; ++ bb44 (cleanup): { ++ (((*_46) as variant#4).2: bool) = const false; ++ nop; ++ goto -> bb45; + } + +- bb56 (cleanup): { +- resume; ++ bb45 (cleanup): { ++ goto -> bb51; + } + +- bb57 (cleanup): { +- StorageDead(_29); +- goto -> bb58; ++ bb46: { ++ drop((((*_46) as variant#4).0: {async block@$DIR/async_fn.rs:106:13: 106:18})) -> [return: bb26, unwind: bb44]; + } + +- bb58 (cleanup): { +- StorageDead(_26); +- StorageDead(_25); +- StorageDead(_24); +- goto -> bb61; ++ bb47: { ++ switchInt(copy (((*_46) as variant#4).2: bool)) -> [0: bb26, otherwise: bb46]; + } + +- bb59 (cleanup): { +- StorageDead(_9); +- goto -> bb60; ++ bb48 (cleanup): { ++ drop((((*_46) as variant#4).0: {async block@$DIR/async_fn.rs:106:13: 106:18})) -> [return: bb44, unwind terminate(cleanup)]; + } + +- bb60 (cleanup): { +- StorageDead(_7); +- StorageDead(_6); +- goto -> bb61; ++ bb49 (cleanup): { ++ switchInt(copy (((*_46) as variant#4).2: bool)) -> [0: bb44, otherwise: bb48]; + } + +- bb61 (cleanup): { +- StorageDead(_4); +- goto -> bb70; ++ bb50: { ++ goto -> bb27; + } + +- bb62 (cleanup): { +- _43 = const false; +- StorageDead(_3); +- drop(_1) -> [return: bb56, unwind terminate(cleanup)]; ++ bb51 (cleanup): { ++ discriminant((*_46)) = 2; ++ resume; + } + +- bb63: { +- drop(_3) -> [return: bb26, unwind: bb55]; ++ bb52: { ++ StorageLive(_4); ++ StorageLive(_6); ++ StorageLive(_7); ++ StorageLive(_22); ++ StorageLive(_23); ++ _22 = move _2; ++ goto -> bb11; + } + +- bb64: { +- switchInt(copy _43) -> [0: bb26, otherwise: bb63]; ++ bb53: { ++ StorageLive(_4); ++ StorageLive(_24); ++ StorageLive(_25); ++ StorageLive(_26); ++ StorageLive(_41); ++ StorageLive(_42); ++ _41 = move _2; ++ goto -> bb22; + } + +- bb65: { +- drop(_3) -> [return: bb35, unwind: bb62]; ++ bb54: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb54, unwind continue]; + } + +- bb66: { +- switchInt(copy _43) -> [0: bb35, otherwise: bb65]; ++ bb55: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb55, unwind continue]; + } + +- bb67 (cleanup): { +- drop(_3) -> [return: bb55, unwind terminate(cleanup)]; +- } +- +- bb68 (cleanup): { +- switchInt(copy _43) -> [0: bb55, otherwise: bb67]; +- } +- +- bb69 (cleanup): { +- drop(_3) -> [return: bb62, unwind terminate(cleanup)]; +- } +- +- bb70 (cleanup): { +- switchInt(copy _43) -> [0: bb62, otherwise: bb69]; ++ bb56: { ++ (((*_46) as variant#4).2: bool) = const false; ++ nop; ++ (((*_46) as variant#4).2: bool) = const true; ++ (((*_46) as variant#4).0: {async block@$DIR/async_fn.rs:106:13: 106:18}) = {coroutine@$DIR/async_fn.rs:106:13: 106:18 (#0)}; ++ StorageLive(_4); ++ _4 = Option::::None; ++ PlaceMention(_4); ++ _5 = discriminant(_4); ++ switchInt(move _5) -> [0: bb3, 1: bb2, otherwise: bb1]; + } + } + diff --git a/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop.0.mir new file mode 100644 index 0000000000000..31b418c7efad9 --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop.0.mir @@ -0,0 +1,216 @@ +// MIR for `uninhabited_variant::{closure#0}` 0 coroutine_drop + +fn uninhabited_variant::{closure#0}(_1: &mut {async fn body of uninhabited_variant()}) -> () { + debug _task_context => _2; + let mut _0: (); + let mut _2: &mut std::task::Context<'_>; + let _3: {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _4: std::option::Option; + let mut _5: isize; + let _6: (); + let mut _7: {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _8: {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _10: (); + let _11: (); + let mut _12: std::task::Poll<()>; + let mut _13: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:106:13: 106:18}>; + let mut _14: &mut {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _15: &mut {async block@$DIR/async_fn.rs:106:13: 106:18}; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut std::task::Context<'_>; + let mut _19: isize; + let mut _21: !; + let mut _22: &mut std::task::Context<'_>; + let mut _23: (); + let _25: (); + let mut _26: {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + let mut _27: {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + let mut _28: Never; + let _30: (); + let mut _31: std::task::Poll<()>; + let mut _32: std::pin::Pin<&mut {async fn body of uninhabited_variant::{closure#0}::unreachable()}>; + let mut _33: &mut {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + let mut _34: &mut {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + let mut _35: &mut std::task::Context<'_>; + let mut _36: &mut std::task::Context<'_>; + let mut _37: &mut std::task::Context<'_>; + let mut _38: isize; + let mut _40: !; + let mut _41: &mut std::task::Context<'_>; + let mut _42: (); + let mut _43: bool; + let mut _44: (); + let mut _45: u32; + scope 1 { + debug c => (((*_1) as variant#4).0: {async block@$DIR/async_fn.rs:106:13: 106:18}); + let mut _9: {async block@$DIR/async_fn.rs:106:13: 106:18}; + let _24: Never; + scope 2 { + debug __awaitee => (((*_1) as variant#3).0: {async block@$DIR/async_fn.rs:106:13: 106:18}); + let _20: (); + scope 3 { + debug result => _20; + } + } + scope 4 { + debug r => _24; + let mut _29: {async fn body of uninhabited_variant::{closure#0}::unreachable()}; + scope 5 { + debug __awaitee => (((*_1) as variant#4).1: {async fn body of uninhabited_variant::{closure#0}::unreachable()}); + let _39: (); + scope 6 { + debug result => _39; + } + } + } + } + + bb0: { + _45 = discriminant((*_1)); + switchInt(move _45) -> [0: bb22, 3: bb25, 4: bb26, otherwise: bb27]; + } + + bb1: { + StorageDead(_42); + StorageDead(_41); + drop((((*_1) as variant#4).1: {async fn body of uninhabited_variant::{closure#0}::unreachable()})) -> [return: bb2, unwind: bb11]; + } + + bb2: { + nop; + goto -> bb3; + } + + bb3: { + StorageDead(_26); + StorageDead(_25); + StorageDead(_24); + goto -> bb7; + } + + bb4: { + StorageDead(_23); + StorageDead(_22); + drop((((*_1) as variant#3).0: {async block@$DIR/async_fn.rs:106:13: 106:18})) -> [return: bb5, unwind: bb13]; + } + + bb5: { + nop; + goto -> bb6; + } + + bb6: { + StorageDead(_7); + StorageDead(_6); + goto -> bb7; + } + + bb7: { + StorageDead(_4); + goto -> bb18; + } + + bb8: { + (((*_1) as variant#4).2: bool) = const false; + nop; + goto -> bb23; + } + + bb9: { + return; + } + + bb10 (cleanup): { + resume; + } + + bb11 (cleanup): { + nop; + goto -> bb12; + } + + bb12 (cleanup): { + StorageDead(_26); + StorageDead(_25); + StorageDead(_24); + goto -> bb15; + } + + bb13 (cleanup): { + nop; + goto -> bb14; + } + + bb14 (cleanup): { + StorageDead(_7); + StorageDead(_6); + goto -> bb15; + } + + bb15 (cleanup): { + StorageDead(_4); + goto -> bb20; + } + + bb16 (cleanup): { + (((*_1) as variant#4).2: bool) = const false; + nop; + goto -> bb10; + } + + bb17: { + drop((((*_1) as variant#4).0: {async block@$DIR/async_fn.rs:106:13: 106:18})) -> [return: bb8, unwind: bb16]; + } + + bb18: { + switchInt(copy (((*_1) as variant#4).2: bool)) -> [0: bb8, otherwise: bb17]; + } + + bb19 (cleanup): { + drop((((*_1) as variant#4).0: {async block@$DIR/async_fn.rs:106:13: 106:18})) -> [return: bb16, unwind terminate(cleanup)]; + } + + bb20 (cleanup): { + switchInt(copy (((*_1) as variant#4).2: bool)) -> [0: bb16, otherwise: bb19]; + } + + bb21: { + return; + } + + bb22: { + goto -> bb24; + } + + bb23: { + goto -> bb9; + } + + bb24: { + goto -> bb21; + } + + bb25: { + StorageLive(_4); + StorageLive(_6); + StorageLive(_7); + StorageLive(_22); + StorageLive(_23); + goto -> bb4; + } + + bb26: { + StorageLive(_4); + StorageLive(_24); + StorageLive(_25); + StorageLive(_26); + StorageLive(_41); + StorageLive(_42); + goto -> bb1; + } + + bb27: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir new file mode 100644 index 0000000000000..f460d8984bacf --- /dev/null +++ b/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -0,0 +1,26 @@ +// MIR for `uninhabited_variant::{closure#0}` 0 coroutine_drop_proxy_async + +fn uninhabited_variant::{closure#0}(_1: {async fn body of uninhabited_variant()}, _2: &mut Context<'_>) -> Poll<()> { + let mut _0: std::task::Poll<()>; + scope 1 { + scope 2 { + scope 3 { + } + } + scope 4 { + scope 5 { + scope 6 { + } + } + } + } + + bb0: { + drop(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} From 25d297e884fa56d86a0b9f742029ec1473e010cf Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 16:43:05 +0000 Subject: [PATCH 02/12] Async drop tests. --- ...sure#0}.AsyncEnum.MentionedItems.after.mir | 142 ++ ...-{closure#0}.AsyncEnum.StateTransform.diff | 304 ++++ ...osure#0}.AsyncInt.MentionedItems.after.mir | 49 + ...e-{closure#0}.AsyncInt.StateTransform.diff | 141 ++ ...syncReference_'__.MentionedItems.after.mir | 49 + ...#0}.AsyncReference_'__.StateTransform.diff | 141 ++ ...re#0}.AsyncStruct.MentionedItems.after.mir | 159 ++ ...closure#0}.AsyncStruct.StateTransform.diff | 381 +++++ ...e-{closure#0}.Int.MentionedItems.after.mir | 15 + ..._place-{closure#0}.Int.StateTransform.diff | 43 + ...losure#0}.SyncInt.MentionedItems.after.mir | 15 + ...ce-{closure#0}.SyncInt.StateTransform.diff | 59 + ...#0}.SyncThenAsync.MentionedItems.after.mir | 154 ++ ...osure#0}.SyncThenAsync.StateTransform.diff | 303 ++++ ...rop.double-{closure#0}.ElaborateDrops.diff | 174 +++ ...rop.double-{closure#0}.StateTransform.diff | 345 +++++ ...osure#0}.coroutine_async_drop_expand.0.mir | 278 ++++ ...ble-{closure#0}.coroutine_drop_async.0.mir | 197 +++ ...rate_drops-{closure#0}.ElaborateDrops.diff | 811 +++++++++++ ...rate_drops-{closure#0}.StateTransform.diff | 1275 +++++++++++++++++ tests/mir-opt/coroutine/async_drop.rs | 260 ++++ ...rop.simple-{closure#0}.ElaborateDrops.diff | 123 ++ ...rop.simple-{closure#0}.StateTransform.diff | 237 +++ ...osure#0}.coroutine_async_drop_expand.0.mir | 173 +++ ...ple-{closure#0}.coroutine_drop_async.0.mir | 136 ++ 25 files changed, 5964 insertions(+) create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.Int.MentionedItems.after.mir create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.Int.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir create mode 100644 tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff create mode 100644 tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir create mode 100644 tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir create mode 100644 tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff create mode 100644 tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.rs create mode 100644 tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff create mode 100644 tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff create mode 100644 tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir create mode 100644 tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir new file mode 100644 index 0000000000000..f53de21edb0ed --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir @@ -0,0 +1,142 @@ +// MIR for `std::future::async_drop_in_place::{closure#0}` after MentionedItems + +fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +yields () + { + let mut _0: (); + let mut _3: &mut AsyncEnum; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncInt; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: &mut AsyncInt; + let mut _10: std::pin::Pin<&mut AsyncInt>; + let mut _11: &mut AsyncInt; + let mut _12: isize; + let mut _13: isize; + let mut _14: isize; + let mut _15: impl std::future::Future; + let mut _16: &mut AsyncEnum; + let mut _17: std::pin::Pin<&mut AsyncEnum>; + + bb0: { + _3 = move (_1.0: &mut AsyncEnum); + goto -> bb21; + } + + bb1: { + StorageDead(_8); + return; + } + + bb2 (cleanup): { + StorageDead(_4); + StorageDead(_8); + resume; + } + + bb3: { + goto -> bb1; + } + + bb4 (cleanup): { + drop((((*_3) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb5 (cleanup): { + drop((((*_3) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb6: { + _5 = &mut (((*_3) as A).0: AsyncInt); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; + } + + bb7: { + StorageDead(_4); + goto -> bb1; + } + + bb8: { + async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2]; + } + + bb9: { + _7 = copy (_6.0: &mut AsyncInt); + StorageLive(_4); + _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb2]; + } + + bb10: { + _9 = &mut (((*_3) as A).0: AsyncInt); + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb2]; + } + + bb11: { + StorageDead(_8); + goto -> bb3; + } + + bb12: { + async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb11, unwind: bb2, drop: bb1]; + } + + bb13: { + _11 = copy (_10.0: &mut AsyncInt); + StorageLive(_8); + _8 = async_drop_in_place::(move _11) -> [return: bb12, unwind: bb2]; + } + + bb14 (cleanup): { + drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb15 (cleanup): { + drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb16: { + drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; + } + + bb17: { + drop((((*_3) as B).0: SyncInt)) -> [return: bb3, unwind: bb2]; + } + + bb18: { + _12 = discriminant((*_3)); + switchInt(move _12) -> [0: bb10, otherwise: bb17]; + } + + bb19 (cleanup): { + StorageDead(_15); + _13 = discriminant((*_3)); + switchInt(move _13) -> [0: bb4, otherwise: bb14]; + } + + bb20: { + StorageDead(_15); + _14 = discriminant((*_3)); + switchInt(move _14) -> [0: bb6, otherwise: bb16]; + } + + bb21: { + _16 = &mut (*_3); + _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb24, unwind: bb19]; + } + + bb22: { + StorageDead(_15); + goto -> bb18; + } + + bb23: { + async drop((*_3); poll=_15) -> [return: bb22, unwind: bb19, drop: bb20]; + } + + bb24: { + StorageLive(_15); + _15 = ::drop(move _17) -> [return: bb23, unwind: bb19]; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff new file mode 100644 index 0000000000000..0c8f627414c80 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff @@ -0,0 +1,304 @@ +- // MIR for `std::future::async_drop_in_place::{closure#0}` before StateTransform ++ // MIR for `std::future::async_drop_in_place::{closure#0}` after StateTransform + +- fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +- yields () +- { +- let mut _0: (); ++ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in_place()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: &mut AsyncEnum; ++ field _s1: impl Future; ++ field _s2: impl Future; ++ field _s3: impl Future; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s1], ++ Suspend1 (4): [_s2], ++ Suspend2 (5): [_s2], ++ Suspend3 (6): [_s0, _s3], ++ Suspend4 (7): [_s0, _s3], ++ } ++ storage_conflicts = BitMatrix(4x4) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s1, _s0), (_s1, _s1), (_s2, _s0), (_s2, _s2), (_s3, _s0), (_s3, _s3)} ++ } ++ let mut _0: std::task::Poll<()>; + let mut _3: &mut AsyncEnum; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncInt; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: &mut AsyncInt; + let mut _10: std::pin::Pin<&mut AsyncInt>; + let mut _11: &mut AsyncInt; + let mut _12: isize; + let mut _13: isize; + let mut _14: isize; + let mut _15: impl std::future::Future; + let mut _16: &mut AsyncEnum; + let mut _17: std::pin::Pin<&mut AsyncEnum>; ++ let mut _18: std::task::Poll<()>; ++ let mut _19: &mut std::task::Context<'_>; ++ let mut _20: &mut impl std::future::Future; ++ let mut _21: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _22: isize; ++ let mut _23: std::task::Poll<()>; ++ let mut _24: &mut std::task::Context<'_>; ++ let mut _25: &mut impl std::future::Future; ++ let mut _26: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _27: isize; ++ let mut _28: &mut std::task::Context<'_>; ++ let mut _29: &mut impl std::future::Future; ++ let mut _30: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _31: isize; ++ let mut _32: std::task::Poll<()>; ++ let mut _33: &mut std::task::Context<'_>; ++ let mut _34: &mut impl std::future::Future; ++ let mut _35: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _36: isize; ++ let mut _37: &mut std::task::Context<'_>; ++ let mut _38: &mut impl std::future::Future; ++ let mut _39: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _40: isize; ++ let mut _41: (); ++ let mut _42: u32; ++ let mut _43: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _44: &mut AsyncEnum; ++ let mut _45: &mut AsyncEnum; ++ let mut _46: &mut AsyncEnum; ++ let mut _47: &mut AsyncEnum; ++ let mut _48: &mut AsyncEnum; ++ let mut _49: &mut AsyncEnum; ++ let mut _50: &mut AsyncEnum; + + bb0: { +- _3 = move (_1.0: &mut AsyncEnum); +- _16 = &mut (*_3); +- _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb19, unwind: bb15]; ++ _43 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _42 = discriminant((*_43)); ++ switchInt(move _42) -> [0: bb34, 1: bb33, 2: bb32, 3: bb27, 4: bb28, 5: bb29, 6: bb30, 7: bb31, otherwise: bb17]; + } + + bb1: { +- StorageDead(_8); ++ nop; ++ _0 = Poll::<()>::Ready(move _41); ++ discriminant((*_43)) = 1; + return; + } + + bb2 (cleanup): { +- StorageDead(_4); +- StorageDead(_8); +- resume; ++ nop; ++ nop; ++ goto -> bb26; + } + + bb3 (cleanup): { +- drop((((*_3) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _44 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); ++ drop((((*_44) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb4: { +- _5 = &mut (((*_3) as A).0: AsyncInt); +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; ++ _45 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); ++ _9 = &mut (((*_45) as A).0: AsyncInt); ++ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb7, unwind: bb2]; + } + + bb5: { +- StorageDead(_4); ++ nop; + goto -> bb1; + } + + bb6: { +- async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb5, unwind: bb2]; ++ _24 = move _2; ++ goto -> bb16; + } + + bb7: { +- _7 = copy (_6.0: &mut AsyncInt); +- StorageLive(_4); +- _4 = async_drop_in_place::(move _7) -> [return: bb6, unwind: bb2]; ++ _11 = copy (_10.0: &mut AsyncInt); ++ nop; ++ (((*_43) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _11) -> [return: bb6, unwind: bb2]; + } + +- bb8: { +- _9 = &mut (((*_3) as A).0: AsyncInt); +- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb11, unwind: bb2]; ++ bb8 (cleanup): { ++ _46 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); ++ drop((((*_46) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb9: { +- StorageDead(_8); +- goto -> bb1; ++ _47 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); ++ drop((((*_47) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; + } + +- bb10: { +- async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb9, unwind: bb2, drop: bb1]; ++ bb10 (cleanup): { ++ nop; ++ _48 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); ++ _13 = discriminant((*_48)); ++ switchInt(move _13) -> [0: bb3, otherwise: bb8]; + } + + bb11: { +- _11 = copy (_10.0: &mut AsyncInt); +- StorageLive(_8); +- _8 = async_drop_in_place::(move _11) -> [return: bb10, unwind: bb2]; ++ nop; ++ _49 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); ++ _12 = discriminant((*_49)); ++ switchInt(move _12) -> [0: bb4, otherwise: bb9]; + } + +- bb12 (cleanup): { +- drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ bb12: { ++ _33 = move _2; ++ goto -> bb22; + } + + bb13: { +- drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; ++ nop; ++ (((*_43) as variant#7).1: impl std::future::Future) = ::drop(move _17) -> [return: bb12, unwind: bb10]; + } + + bb14: { +- drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb26]; + } + +- bb15 (cleanup): { +- StorageDead(_15); +- _13 = discriminant((*_3)); +- switchInt(move _13) -> [0: bb3, otherwise: bb12]; ++ bb15: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_43)) = 4; ++ return; + } + + bb16: { +- StorageDead(_15); +- _14 = discriminant((*_3)); +- switchInt(move _14) -> [0: bb4, otherwise: bb13]; ++ StorageLive(_26); ++ _25 = &mut (((*_43) as variant#5).0: impl std::future::Future); ++ _26 = Pin::<&mut impl Future>::new_unchecked(move _25) -> [return: bb19, unwind: bb26]; + } + + bb17: { +- StorageDead(_15); +- _12 = discriminant((*_3)); +- switchInt(move _12) -> [0: bb8, otherwise: bb14]; ++ unreachable; + } + + bb18: { +- async drop((*_3); poll=_15) -> [return: bb17, unwind: bb15, drop: bb16]; ++ StorageDead(_26); ++ _27 = discriminant(_23); ++ switchInt(move _27) -> [0: bb5, 1: bb15, otherwise: bb17]; + } + + bb19: { +- StorageLive(_15); +- _15 = ::drop(move _17) -> [return: bb18, unwind: bb15]; ++ _23 = as Future>::poll(move _26, move _24) -> [return: bb18, unwind: bb2]; ++ } ++ ++ bb20: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb20, unwind: bb26]; ++ } ++ ++ bb21: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_43)) = 6; ++ return; ++ } ++ ++ bb22: { ++ StorageLive(_35); ++ _34 = &mut (((*_43) as variant#7).1: impl std::future::Future); ++ _35 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb24, unwind: bb26]; ++ } ++ ++ bb23: { ++ StorageDead(_35); ++ _36 = discriminant(_32); ++ switchInt(move _36) -> [0: bb11, 1: bb21, otherwise: bb17]; ++ } ++ ++ bb24: { ++ _32 = as Future>::poll(move _35, move _33) -> [return: bb23, unwind: bb10]; ++ } ++ ++ bb25: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb25, unwind: bb26]; ++ } ++ ++ bb26 (cleanup): { ++ discriminant((*_43)) = 2; ++ resume; ++ } ++ ++ bb27: { ++ _19 = move _2; ++ goto -> bb14; ++ } ++ ++ bb28: { ++ _24 = move _2; ++ goto -> bb16; ++ } ++ ++ bb29: { ++ _28 = move _2; ++ goto -> bb20; ++ } ++ ++ bb30: { ++ _33 = move _2; ++ goto -> bb22; ++ } ++ ++ bb31: { ++ _37 = move _2; ++ goto -> bb25; ++ } ++ ++ bb32: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb32, unwind continue]; ++ } ++ ++ bb33: { ++ _0 = Poll::<()>::Ready(const ()); ++ return; ++ } ++ ++ bb34: { ++ (((*_43) as variant#7).0: &mut AsyncEnum) = move ((*_43).0: &mut AsyncEnum); ++ _50 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); ++ _16 = &mut (*_50); ++ _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb13, unwind: bb10]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir new file mode 100644 index 0000000000000..5c41d70197194 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir @@ -0,0 +1,49 @@ +// MIR for `std::future::async_drop_in_place::{closure#0}` after MentionedItems + +fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +yields () + { + let mut _0: (); + let mut _3: &mut AsyncInt; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncInt; + let mut _6: std::pin::Pin<&mut AsyncInt>; + + bb0: { + _3 = move (_1.0: &mut AsyncInt); + goto -> bb4; + } + + bb1: { + StorageDead(_4); + return; + } + + bb2 (cleanup): { + StorageDead(_4); + resume; + } + + bb3: { + goto -> bb1; + } + + bb4: { + _5 = &mut (*_3); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; + } + + bb5: { + StorageDead(_4); + goto -> bb3; + } + + bb6: { + async drop((*_3); poll=_4) -> [return: bb5, unwind: bb2, drop: bb1]; + } + + bb7: { + StorageLive(_4); + _4 = ::drop(move _6) -> [return: bb6, unwind: bb2]; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff new file mode 100644 index 0000000000000..0df9e00cef41c --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff @@ -0,0 +1,141 @@ +- // MIR for `std::future::async_drop_in_place::{closure#0}` before StateTransform ++ // MIR for `std::future::async_drop_in_place::{closure#0}` after StateTransform + +- fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +- yields () +- { +- let mut _0: (); ++ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in_place()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: impl Future; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0], ++ Suspend1 (4): [_s0], ++ } ++ storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} ++ } ++ let mut _0: std::task::Poll<()>; + let mut _3: &mut AsyncInt; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncInt; + let mut _6: std::pin::Pin<&mut AsyncInt>; ++ let mut _7: std::task::Poll<()>; ++ let mut _8: &mut std::task::Context<'_>; ++ let mut _9: &mut impl std::future::Future; ++ let mut _10: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _11: isize; ++ let mut _12: &mut std::task::Context<'_>; ++ let mut _13: &mut impl std::future::Future; ++ let mut _14: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _15: isize; ++ let mut _16: (); ++ let mut _17: u32; ++ let mut _18: &mut {async fn body of std::future::async_drop_in_place()}; + + bb0: { +- _3 = move (_1.0: &mut AsyncInt); +- _5 = &mut (*_3); +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb5, unwind: bb2]; ++ _18 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _17 = discriminant((*_18)); ++ switchInt(move _17) -> [0: bb17, 1: bb16, 2: bb15, 3: bb13, 4: bb14, otherwise: bb8]; + } + + bb1: { +- StorageDead(_4); ++ nop; ++ _0 = Poll::<()>::Ready(move _16); ++ discriminant((*_18)) = 1; + return; + } + + bb2 (cleanup): { +- StorageDead(_4); +- resume; ++ nop; ++ goto -> bb12; + } + + bb3: { +- StorageDead(_4); ++ nop; + goto -> bb1; + } + + bb4: { +- async drop((*_3); poll=_4) -> [return: bb3, unwind: bb2, drop: bb1]; ++ _8 = move _2; ++ goto -> bb7; + } + + bb5: { +- StorageLive(_4); +- _4 = ::drop(move _6) -> [return: bb4, unwind: bb2]; ++ nop; ++ (((*_18) as variant#4).0: impl std::future::Future) = ::drop(move _6) -> [return: bb4, unwind: bb2]; ++ } ++ ++ bb6: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_18)) = 3; ++ return; ++ } ++ ++ bb7: { ++ StorageLive(_10); ++ _9 = &mut (((*_18) as variant#4).0: impl std::future::Future); ++ _10 = Pin::<&mut impl Future>::new_unchecked(move _9) -> [return: bb10, unwind: bb12]; ++ } ++ ++ bb8: { ++ unreachable; ++ } ++ ++ bb9: { ++ StorageDead(_10); ++ _11 = discriminant(_7); ++ switchInt(move _11) -> [0: bb3, 1: bb6, otherwise: bb8]; ++ } ++ ++ bb10: { ++ _7 = as Future>::poll(move _10, move _8) -> [return: bb9, unwind: bb2]; ++ } ++ ++ bb11: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb11, unwind: bb12]; ++ } ++ ++ bb12 (cleanup): { ++ discriminant((*_18)) = 2; ++ resume; ++ } ++ ++ bb13: { ++ _8 = move _2; ++ goto -> bb7; ++ } ++ ++ bb14: { ++ _12 = move _2; ++ goto -> bb11; ++ } ++ ++ bb15: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb15, unwind continue]; ++ } ++ ++ bb16: { ++ _0 = Poll::<()>::Ready(const ()); ++ return; ++ } ++ ++ bb17: { ++ _3 = move ((*_18).0: &mut AsyncInt); ++ _5 = &mut (*_3); ++ _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb5, unwind: bb2]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir new file mode 100644 index 0000000000000..ec5530e75e1cc --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir @@ -0,0 +1,49 @@ +// MIR for `std::future::async_drop_in_place::{closure#0}` after MentionedItems + +fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place>()}, _2: std::future::ResumeTy) -> () +yields () + { + let mut _0: (); + let mut _3: &mut AsyncReference<'_>; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncReference<'_>; + let mut _6: std::pin::Pin<&mut AsyncReference<'_>>; + + bb0: { + _3 = move (_1.0: &mut AsyncReference<'_>); + goto -> bb4; + } + + bb1: { + StorageDead(_4); + return; + } + + bb2 (cleanup): { + StorageDead(_4); + resume; + } + + bb3: { + goto -> bb1; + } + + bb4: { + _5 = &mut (*_3); + _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; + } + + bb5: { + StorageDead(_4); + goto -> bb3; + } + + bb6: { + async drop((*_3); poll=_4) -> [return: bb5, unwind: bb2, drop: bb1]; + } + + bb7: { + StorageLive(_4); + _4 = as AsyncDrop>::drop(move _6) -> [return: bb6, unwind: bb2]; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff new file mode 100644 index 0000000000000..a4919a71d921c --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff @@ -0,0 +1,141 @@ +- // MIR for `std::future::async_drop_in_place::{closure#0}` before StateTransform ++ // MIR for `std::future::async_drop_in_place::{closure#0}` after StateTransform + +- fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place>()}, _2: std::future::ResumeTy) -> () +- yields () +- { +- let mut _0: (); ++ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in_place>()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: impl Future; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0], ++ Suspend1 (4): [_s0], ++ } ++ storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} ++ } ++ let mut _0: std::task::Poll<()>; + let mut _3: &mut AsyncReference<'_>; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncReference<'_>; + let mut _6: std::pin::Pin<&mut AsyncReference<'_>>; ++ let mut _7: std::task::Poll<()>; ++ let mut _8: &mut std::task::Context<'_>; ++ let mut _9: &mut impl std::future::Future; ++ let mut _10: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _11: isize; ++ let mut _12: &mut std::task::Context<'_>; ++ let mut _13: &mut impl std::future::Future; ++ let mut _14: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _15: isize; ++ let mut _16: (); ++ let mut _17: u32; ++ let mut _18: &mut {async fn body of std::future::async_drop_in_place>()}; + + bb0: { +- _3 = move (_1.0: &mut AsyncReference<'_>); +- _5 = &mut (*_3); +- _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb5, unwind: bb2]; ++ _18 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place>()}); ++ _17 = discriminant((*_18)); ++ switchInt(move _17) -> [0: bb17, 1: bb16, 2: bb15, 3: bb13, 4: bb14, otherwise: bb8]; + } + + bb1: { +- StorageDead(_4); ++ nop; ++ _0 = Poll::<()>::Ready(move _16); ++ discriminant((*_18)) = 1; + return; + } + + bb2 (cleanup): { +- StorageDead(_4); +- resume; ++ nop; ++ goto -> bb12; + } + + bb3: { +- StorageDead(_4); ++ nop; + goto -> bb1; + } + + bb4: { +- async drop((*_3); poll=_4) -> [return: bb3, unwind: bb2, drop: bb1]; ++ _8 = move _2; ++ goto -> bb7; + } + + bb5: { +- StorageLive(_4); +- _4 = as AsyncDrop>::drop(move _6) -> [return: bb4, unwind: bb2]; ++ nop; ++ (((*_18) as variant#4).0: impl std::future::Future) = as AsyncDrop>::drop(move _6) -> [return: bb4, unwind: bb2]; ++ } ++ ++ bb6: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_18)) = 3; ++ return; ++ } ++ ++ bb7: { ++ StorageLive(_10); ++ _9 = &mut (((*_18) as variant#4).0: impl std::future::Future); ++ _10 = Pin::<&mut impl Future>::new_unchecked(move _9) -> [return: bb10, unwind: bb12]; ++ } ++ ++ bb8: { ++ unreachable; ++ } ++ ++ bb9: { ++ StorageDead(_10); ++ _11 = discriminant(_7); ++ switchInt(move _11) -> [0: bb3, 1: bb6, otherwise: bb8]; ++ } ++ ++ bb10: { ++ _7 = as Future>::poll(move _10, move _8) -> [return: bb9, unwind: bb2]; ++ } ++ ++ bb11: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb11, unwind: bb12]; ++ } ++ ++ bb12 (cleanup): { ++ discriminant((*_18)) = 2; ++ resume; ++ } ++ ++ bb13: { ++ _8 = move _2; ++ goto -> bb7; ++ } ++ ++ bb14: { ++ _12 = move _2; ++ goto -> bb11; ++ } ++ ++ bb15: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb15, unwind continue]; ++ } ++ ++ bb16: { ++ _0 = Poll::<()>::Ready(const ()); ++ return; ++ } ++ ++ bb17: { ++ _3 = move ((*_18).0: &mut AsyncReference<'_>); ++ _5 = &mut (*_3); ++ _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb5, unwind: bb2]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir new file mode 100644 index 0000000000000..1c091c3916e6f --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir @@ -0,0 +1,159 @@ +// MIR for `std::future::async_drop_in_place::{closure#0}` after MentionedItems + +fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +yields () + { + let mut _0: (); + let mut _3: &mut AsyncStruct; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncInt; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: &mut AsyncInt; + let mut _10: std::pin::Pin<&mut AsyncInt>; + let mut _11: &mut AsyncInt; + let mut _12: impl std::future::Future; + let mut _13: &mut AsyncInt; + let mut _14: std::pin::Pin<&mut AsyncInt>; + let mut _15: &mut AsyncInt; + let mut _16: impl std::future::Future; + let mut _17: &mut AsyncInt; + let mut _18: std::pin::Pin<&mut AsyncInt>; + let mut _19: &mut AsyncInt; + let mut _20: impl std::future::Future; + let mut _21: &mut AsyncStruct; + let mut _22: std::pin::Pin<&mut AsyncStruct>; + + bb0: { + _3 = move (_1.0: &mut AsyncStruct); + goto -> bb22; + } + + bb1: { + StorageDead(_12); + return; + } + + bb2 (cleanup): { + StorageDead(_4); + StorageDead(_12); + resume; + } + + bb3: { + goto -> bb1; + } + + bb4 (cleanup): { + StorageDead(_8); + StorageDead(_16); + drop(((*_3).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb5 (cleanup): { + StorageDead(_20); + drop(((*_3).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; + } + + bb6: { + _5 = &mut ((*_3).2: AsyncInt); + StorageDead(_16); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; + } + + bb7: { + StorageDead(_4); + goto -> bb1; + } + + bb8: { + async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2]; + } + + bb9: { + _7 = copy (_6.0: &mut AsyncInt); + StorageLive(_4); + _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb2]; + } + + bb10: { + _9 = &mut ((*_3).1: AsyncInt); + StorageDead(_20); + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb4]; + } + + bb11: { + StorageDead(_8); + goto -> bb6; + } + + bb12: { + async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb11, unwind: bb4]; + } + + bb13: { + _11 = copy (_10.0: &mut AsyncInt); + StorageLive(_8); + _8 = async_drop_in_place::(move _11) -> [return: bb12, unwind: bb4]; + } + + bb14: { + _13 = &mut ((*_3).2: AsyncInt); + _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb17, unwind: bb2]; + } + + bb15: { + StorageDead(_12); + goto -> bb3; + } + + bb16: { + async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb15, unwind: bb2, drop: bb1]; + } + + bb17: { + _15 = copy (_14.0: &mut AsyncInt); + StorageLive(_12); + _12 = async_drop_in_place::(move _15) -> [return: bb16, unwind: bb2]; + } + + bb18: { + _17 = &mut ((*_3).1: AsyncInt); + _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb21, unwind: bb4]; + } + + bb19: { + StorageDead(_16); + goto -> bb14; + } + + bb20: { + async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb19, unwind: bb4, drop: bb6]; + } + + bb21: { + _19 = copy (_18.0: &mut AsyncInt); + StorageLive(_16); + _16 = async_drop_in_place::(move _19) -> [return: bb20, unwind: bb4]; + } + + bb22: { + _21 = &mut (*_3); + _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb25, unwind: bb5]; + } + + bb23: { + StorageDead(_20); + goto -> bb18; + } + + bb24: { + async drop((*_3); poll=_20) -> [return: bb23, unwind: bb5, drop: bb10]; + } + + bb25: { + StorageLive(_20); + _20 = ::drop(move _22) -> [return: bb24, unwind: bb5]; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff new file mode 100644 index 0000000000000..658a6efa16a2c --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff @@ -0,0 +1,381 @@ +- // MIR for `std::future::async_drop_in_place::{closure#0}` before StateTransform ++ // MIR for `std::future::async_drop_in_place::{closure#0}` after StateTransform + +- fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +- yields () +- { +- let mut _0: (); ++ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in_place()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: &mut AsyncStruct; ++ field _s1: impl Future; ++ field _s2: impl Future; ++ field _s3: impl Future; ++ field _s4: impl Future; ++ field _s5: impl Future; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s1], ++ Suspend1 (4): [_s0, _s2], ++ Suspend2 (5): [_s3], ++ Suspend3 (6): [_s3], ++ Suspend4 (7): [_s0, _s4], ++ Suspend5 (8): [_s0, _s4], ++ Suspend6 (9): [_s0, _s5], ++ Suspend7 (10): [_s0, _s5], ++ } ++ storage_conflicts = BitMatrix(6x6) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s0, _s4), (_s0, _s5), (_s1, _s0), (_s1, _s1), (_s2, _s0), (_s2, _s2), (_s3, _s0), (_s3, _s3), (_s4, _s0), (_s4, _s4), (_s5, _s0), (_s5, _s5)} ++ } ++ let mut _0: std::task::Poll<()>; + let mut _3: &mut AsyncStruct; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncInt; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: &mut AsyncInt; + let mut _10: std::pin::Pin<&mut AsyncInt>; + let mut _11: &mut AsyncInt; + let mut _12: impl std::future::Future; + let mut _13: &mut AsyncInt; + let mut _14: std::pin::Pin<&mut AsyncInt>; + let mut _15: &mut AsyncInt; + let mut _16: impl std::future::Future; + let mut _17: &mut AsyncInt; + let mut _18: std::pin::Pin<&mut AsyncInt>; + let mut _19: &mut AsyncInt; + let mut _20: impl std::future::Future; + let mut _21: &mut AsyncStruct; + let mut _22: std::pin::Pin<&mut AsyncStruct>; ++ let mut _23: std::task::Poll<()>; ++ let mut _24: &mut std::task::Context<'_>; ++ let mut _25: &mut impl std::future::Future; ++ let mut _26: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _27: isize; ++ let mut _28: std::task::Poll<()>; ++ let mut _29: &mut std::task::Context<'_>; ++ let mut _30: &mut impl std::future::Future; ++ let mut _31: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _32: isize; ++ let mut _33: std::task::Poll<()>; ++ let mut _34: &mut std::task::Context<'_>; ++ let mut _35: &mut impl std::future::Future; ++ let mut _36: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _37: isize; ++ let mut _38: &mut std::task::Context<'_>; ++ let mut _39: &mut impl std::future::Future; ++ let mut _40: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _41: isize; ++ let mut _42: std::task::Poll<()>; ++ let mut _43: &mut std::task::Context<'_>; ++ let mut _44: &mut impl std::future::Future; ++ let mut _45: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _46: isize; ++ let mut _47: &mut std::task::Context<'_>; ++ let mut _48: &mut impl std::future::Future; ++ let mut _49: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _50: isize; ++ let mut _51: std::task::Poll<()>; ++ let mut _52: &mut std::task::Context<'_>; ++ let mut _53: &mut impl std::future::Future; ++ let mut _54: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _55: isize; ++ let mut _56: &mut std::task::Context<'_>; ++ let mut _57: &mut impl std::future::Future; ++ let mut _58: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _59: isize; ++ let mut _60: (); ++ let mut _61: u32; ++ let mut _62: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _63: &mut AsyncStruct; ++ let mut _64: &mut AsyncStruct; ++ let mut _65: &mut AsyncStruct; ++ let mut _66: &mut AsyncStruct; ++ let mut _67: &mut AsyncStruct; + + bb0: { +- _3 = move (_1.0: &mut AsyncStruct); +- _21 = &mut (*_3); +- _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb21, unwind: bb4]; ++ _62 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _61 = discriminant((*_62)); ++ switchInt(move _61) -> [0: bb43, 1: bb42, 2: bb41, 3: bb33, 4: bb34, 5: bb35, 6: bb36, 7: bb37, 8: bb38, 9: bb39, 10: bb40, otherwise: bb18]; + } + + bb1: { +- StorageDead(_12); ++ nop; ++ _0 = Poll::<()>::Ready(move _60); ++ discriminant((*_62)) = 1; + return; + } + + bb2 (cleanup): { +- StorageDead(_4); +- StorageDead(_12); +- resume; ++ nop; ++ nop; ++ goto -> bb32; + } + + bb3 (cleanup): { +- StorageDead(_8); +- StorageDead(_16); +- drop(((*_3).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ nop; ++ nop; ++ _63 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); ++ drop(((*_63).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb4 (cleanup): { +- StorageDead(_20); +- drop(((*_3).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; ++ nop; ++ _64 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); ++ drop(((*_64).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; + } + + bb5: { +- _5 = &mut ((*_3).2: AsyncInt); +- StorageDead(_16); +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; ++ nop; ++ goto -> bb1; + } + + bb6: { +- StorageDead(_4); +- goto -> bb1; ++ _34 = move _2; ++ goto -> bb17; + } + + bb7: { +- async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2]; ++ _15 = copy (_14.0: &mut AsyncInt); ++ nop; ++ (((*_62) as variant#6).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb6, unwind: bb2]; + } + + bb8: { +- _7 = copy (_6.0: &mut AsyncInt); +- StorageLive(_4); +- _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb2]; ++ nop; ++ _65 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); ++ _13 = &mut ((*_65).2: AsyncInt); ++ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb7, unwind: bb2]; + } + + bb9: { +- _9 = &mut ((*_3).1: AsyncInt); +- StorageDead(_20); +- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb12, unwind: bb3]; ++ _43 = move _2; ++ goto -> bb23; + } + + bb10: { +- StorageDead(_8); +- goto -> bb5; ++ _19 = copy (_18.0: &mut AsyncInt); ++ nop; ++ (((*_62) as variant#8).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb9, unwind: bb3]; + } + + bb11: { +- async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb10, unwind: bb3]; ++ nop; ++ _66 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); ++ _17 = &mut ((*_66).1: AsyncInt); ++ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb10, unwind: bb3]; + } + + bb12: { +- _11 = copy (_10.0: &mut AsyncInt); +- StorageLive(_8); +- _8 = async_drop_in_place::(move _11) -> [return: bb11, unwind: bb3]; ++ _52 = move _2; ++ goto -> bb28; + } + + bb13: { +- StorageDead(_12); +- goto -> bb1; ++ nop; ++ (((*_62) as variant#10).1: impl std::future::Future) = ::drop(move _22) -> [return: bb12, unwind: bb4]; + } + + bb14: { +- async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb13, unwind: bb2, drop: bb1]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb32]; + } + + bb15: { +- _15 = copy (_14.0: &mut AsyncInt); +- StorageLive(_12); +- _12 = async_drop_in_place::(move _15) -> [return: bb14, unwind: bb2]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb15, unwind: bb32]; + } + + bb16: { +- StorageDead(_16); +- _13 = &mut ((*_3).2: AsyncInt); +- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb15, unwind: bb2]; ++ _0 = Poll::<()>::Pending; ++ discriminant((*_62)) = 5; ++ return; + } + + bb17: { +- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb16, unwind: bb3, drop: bb5]; ++ StorageLive(_36); ++ _35 = &mut (((*_62) as variant#6).0: impl std::future::Future); ++ _36 = Pin::<&mut impl Future>::new_unchecked(move _35) -> [return: bb20, unwind: bb32]; + } + + bb18: { +- _19 = copy (_18.0: &mut AsyncInt); +- StorageLive(_16); +- _16 = async_drop_in_place::(move _19) -> [return: bb17, unwind: bb3]; ++ unreachable; + } + + bb19: { +- StorageDead(_20); +- _17 = &mut ((*_3).1: AsyncInt); +- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb18, unwind: bb3]; ++ StorageDead(_36); ++ _37 = discriminant(_33); ++ switchInt(move _37) -> [0: bb5, 1: bb16, otherwise: bb18]; + } + + bb20: { +- async drop((*_3); poll=_20) -> [return: bb19, unwind: bb4, drop: bb9]; ++ _33 = as Future>::poll(move _36, move _34) -> [return: bb19, unwind: bb2]; + } + + bb21: { +- StorageLive(_20); +- _20 = ::drop(move _22) -> [return: bb20, unwind: bb4]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb21, unwind: bb32]; ++ } ++ ++ bb22: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_62)) = 7; ++ return; ++ } ++ ++ bb23: { ++ StorageLive(_45); ++ _44 = &mut (((*_62) as variant#8).1: impl std::future::Future); ++ _45 = Pin::<&mut impl Future>::new_unchecked(move _44) -> [return: bb25, unwind: bb32]; ++ } ++ ++ bb24: { ++ StorageDead(_45); ++ _46 = discriminant(_42); ++ switchInt(move _46) -> [0: bb8, 1: bb22, otherwise: bb18]; ++ } ++ ++ bb25: { ++ _42 = as Future>::poll(move _45, move _43) -> [return: bb24, unwind: bb3]; ++ } ++ ++ bb26: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb26, unwind: bb32]; ++ } ++ ++ bb27: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_62)) = 9; ++ return; ++ } ++ ++ bb28: { ++ StorageLive(_54); ++ _53 = &mut (((*_62) as variant#10).1: impl std::future::Future); ++ _54 = Pin::<&mut impl Future>::new_unchecked(move _53) -> [return: bb30, unwind: bb32]; ++ } ++ ++ bb29: { ++ StorageDead(_54); ++ _55 = discriminant(_51); ++ switchInt(move _55) -> [0: bb11, 1: bb27, otherwise: bb18]; ++ } ++ ++ bb30: { ++ _51 = as Future>::poll(move _54, move _52) -> [return: bb29, unwind: bb4]; ++ } ++ ++ bb31: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb31, unwind: bb32]; ++ } ++ ++ bb32 (cleanup): { ++ discriminant((*_62)) = 2; ++ resume; ++ } ++ ++ bb33: { ++ _24 = move _2; ++ goto -> bb14; ++ } ++ ++ bb34: { ++ _29 = move _2; ++ goto -> bb15; ++ } ++ ++ bb35: { ++ _34 = move _2; ++ goto -> bb17; ++ } ++ ++ bb36: { ++ _38 = move _2; ++ goto -> bb21; ++ } ++ ++ bb37: { ++ _43 = move _2; ++ goto -> bb23; ++ } ++ ++ bb38: { ++ _47 = move _2; ++ goto -> bb26; ++ } ++ ++ bb39: { ++ _52 = move _2; ++ goto -> bb28; ++ } ++ ++ bb40: { ++ _56 = move _2; ++ goto -> bb31; ++ } ++ ++ bb41: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb41, unwind continue]; ++ } ++ ++ bb42: { ++ _0 = Poll::<()>::Ready(const ()); ++ return; ++ } ++ ++ bb43: { ++ (((*_62) as variant#10).0: &mut AsyncStruct) = move ((*_62).0: &mut AsyncStruct); ++ _67 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); ++ _21 = &mut (*_67); ++ _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb13, unwind: bb4]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.Int.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.Int.MentionedItems.after.mir new file mode 100644 index 0000000000000..7823a862bbded --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.Int.MentionedItems.after.mir @@ -0,0 +1,15 @@ +// MIR for `std::future::async_drop_in_place::{closure#0}` after MentionedItems + +fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +yields () + { + let mut _0: (); + + bb0: { + goto -> bb1; + } + + bb1: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.Int.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.Int.StateTransform.diff new file mode 100644 index 0000000000000..1536d5bca0c21 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.Int.StateTransform.diff @@ -0,0 +1,43 @@ +- // MIR for `std::future::async_drop_in_place::{closure#0}` before StateTransform ++ // MIR for `std::future::async_drop_in_place::{closure#0}` after StateTransform + +- fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +- yields () +- { +- let mut _0: (); ++ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in_place()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ } ++ storage_conflicts = BitMatrix(0x0) {} ++ } ++ let mut _0: std::task::Poll<()>; ++ let mut _3: (); ++ let mut _4: u32; ++ let mut _5: &mut {async fn body of std::future::async_drop_in_place()}; + + bb0: { ++ _5 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _4 = discriminant((*_5)); ++ switchInt(move _4) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ } ++ ++ bb1: { ++ _0 = Poll::<()>::Ready(const ()); ++ return; ++ } ++ ++ bb2: { ++ unreachable; ++ } ++ ++ bb3: { ++ _0 = Poll::<()>::Ready(move _3); ++ discriminant((*_5)) = 1; + return; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir new file mode 100644 index 0000000000000..21f26a30f75e7 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir @@ -0,0 +1,15 @@ +// MIR for `std::future::async_drop_in_place::{closure#0}` after MentionedItems + +fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +yields () + { + let mut _0: (); + + bb0: { + drop((*(_1.0: &mut SyncInt))) -> [return: bb1, unwind continue]; + } + + bb1: { + return; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff new file mode 100644 index 0000000000000..aafff3292dd4f --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff @@ -0,0 +1,59 @@ +- // MIR for `std::future::async_drop_in_place::{closure#0}` before StateTransform ++ // MIR for `std::future::async_drop_in_place::{closure#0}` after StateTransform + +- fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +- yields () +- { +- let mut _0: (); ++ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in_place()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ } ++ storage_conflicts = BitMatrix(0x0) {} ++ } ++ let mut _0: std::task::Poll<()>; ++ let mut _3: (); ++ let mut _4: u32; ++ let mut _5: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _6: &mut SyncInt; + + bb0: { +- drop((*(_1.0: &mut SyncInt))) -> [return: bb1, unwind continue]; ++ _5 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _4 = discriminant((*_5)); ++ switchInt(move _4) -> [0: bb6, 1: bb4, 2: bb3, otherwise: bb5]; + } + + bb1: { ++ _0 = Poll::<()>::Ready(move _3); ++ discriminant((*_5)) = 1; + return; ++ } ++ ++ bb2 (cleanup): { ++ discriminant((*_5)) = 2; ++ resume; ++ } ++ ++ bb3: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb3, unwind continue]; ++ } ++ ++ bb4: { ++ _0 = Poll::<()>::Ready(const ()); ++ return; ++ } ++ ++ bb5: { ++ unreachable; ++ } ++ ++ bb6: { ++ _6 = no_retag copy ((*_5).0: &mut SyncInt); ++ drop((*_6)) -> [return: bb1, unwind: bb2]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir new file mode 100644 index 0000000000000..89cfec6966226 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir @@ -0,0 +1,154 @@ +// MIR for `std::future::async_drop_in_place::{closure#0}` after MentionedItems + +fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +yields () + { + let mut _0: (); + let mut _3: &mut SyncThenAsync; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncInt; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: &mut AsyncInt; + let mut _10: std::pin::Pin<&mut AsyncInt>; + let mut _11: &mut AsyncInt; + let mut _12: impl std::future::Future; + let mut _13: &mut AsyncInt; + let mut _14: std::pin::Pin<&mut AsyncInt>; + let mut _15: &mut AsyncInt; + let mut _16: impl std::future::Future; + let mut _17: &mut AsyncInt; + let mut _18: std::pin::Pin<&mut AsyncInt>; + let mut _19: &mut AsyncInt; + let mut _20: &mut SyncThenAsync; + let mut _21: (); + + bb0: { + _3 = move (_1.0: &mut SyncThenAsync); + goto -> bb25; + } + + bb1: { + StorageDead(_12); + return; + } + + bb2 (cleanup): { + StorageDead(_4); + StorageDead(_12); + resume; + } + + bb3: { + goto -> bb1; + } + + bb4 (cleanup): { + drop(((*_3).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb5 (cleanup): { + StorageDead(_8); + StorageDead(_16); + drop(((*_3).2: SyncInt)) -> [return: bb4, unwind terminate(cleanup)]; + } + + bb6 (cleanup): { + drop(((*_3).1: AsyncInt)) -> [return: bb5, unwind terminate(cleanup)]; + } + + bb7: { + _5 = &mut ((*_3).3: AsyncInt); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb10, unwind: bb2]; + } + + bb8: { + StorageDead(_4); + goto -> bb1; + } + + bb9: { + async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb8, unwind: bb2]; + } + + bb10: { + _7 = copy (_6.0: &mut AsyncInt); + StorageLive(_4); + _4 = async_drop_in_place::(move _7) -> [return: bb9, unwind: bb2]; + } + + bb11: { + StorageDead(_16); + drop(((*_3).2: SyncInt)) -> [return: bb7, unwind: bb4]; + } + + bb12: { + _9 = &mut ((*_3).1: AsyncInt); + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb15, unwind: bb5]; + } + + bb13: { + StorageDead(_8); + goto -> bb11; + } + + bb14: { + async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb13, unwind: bb5]; + } + + bb15: { + _11 = copy (_10.0: &mut AsyncInt); + StorageLive(_8); + _8 = async_drop_in_place::(move _11) -> [return: bb14, unwind: bb5]; + } + + bb16: { + _13 = &mut ((*_3).3: AsyncInt); + _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb19, unwind: bb2]; + } + + bb17: { + StorageDead(_12); + goto -> bb3; + } + + bb18: { + async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb17, unwind: bb2, drop: bb1]; + } + + bb19: { + _15 = copy (_14.0: &mut AsyncInt); + StorageLive(_12); + _12 = async_drop_in_place::(move _15) -> [return: bb18, unwind: bb2]; + } + + bb20: { + drop(((*_3).2: SyncInt)) -> [return: bb16, unwind: bb4]; + } + + bb21: { + _17 = &mut ((*_3).1: AsyncInt); + _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb24, unwind: bb5]; + } + + bb22: { + StorageDead(_16); + goto -> bb20; + } + + bb23: { + async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb22, unwind: bb5, drop: bb11]; + } + + bb24: { + _19 = copy (_18.0: &mut AsyncInt); + StorageLive(_16); + _16 = async_drop_in_place::(move _19) -> [return: bb23, unwind: bb5]; + } + + bb25: { + _20 = &mut (*_3); + _21 = ::drop(move _20) -> [return: bb21, unwind: bb6]; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff new file mode 100644 index 0000000000000..ebb03e7fe474a --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff @@ -0,0 +1,303 @@ +- // MIR for `std::future::async_drop_in_place::{closure#0}` before StateTransform ++ // MIR for `std::future::async_drop_in_place::{closure#0}` after StateTransform + +- fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place()}, _2: std::future::ResumeTy) -> () +- yields () +- { +- let mut _0: (); ++ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in_place()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: &mut SyncThenAsync; ++ field _s1: impl Future; ++ field _s2: impl Future; ++ field _s3: impl Future; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s1], ++ Suspend1 (4): [_s2], ++ Suspend2 (5): [_s2], ++ Suspend3 (6): [_s0, _s3], ++ Suspend4 (7): [_s0, _s3], ++ } ++ storage_conflicts = BitMatrix(4x4) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s1, _s0), (_s1, _s1), (_s2, _s0), (_s2, _s2), (_s3, _s0), (_s3, _s3)} ++ } ++ let mut _0: std::task::Poll<()>; + let mut _3: &mut SyncThenAsync; + let mut _4: impl std::future::Future; + let mut _5: &mut AsyncInt; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: &mut AsyncInt; + let mut _10: std::pin::Pin<&mut AsyncInt>; + let mut _11: &mut AsyncInt; + let mut _12: impl std::future::Future; + let mut _13: &mut AsyncInt; + let mut _14: std::pin::Pin<&mut AsyncInt>; + let mut _15: &mut AsyncInt; + let mut _16: impl std::future::Future; + let mut _17: &mut AsyncInt; + let mut _18: std::pin::Pin<&mut AsyncInt>; + let mut _19: &mut AsyncInt; + let mut _20: &mut SyncThenAsync; + let mut _21: (); ++ let mut _22: std::task::Poll<()>; ++ let mut _23: &mut std::task::Context<'_>; ++ let mut _24: &mut impl std::future::Future; ++ let mut _25: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _26: isize; ++ let mut _27: std::task::Poll<()>; ++ let mut _28: &mut std::task::Context<'_>; ++ let mut _29: &mut impl std::future::Future; ++ let mut _30: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _31: isize; ++ let mut _32: &mut std::task::Context<'_>; ++ let mut _33: &mut impl std::future::Future; ++ let mut _34: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _35: isize; ++ let mut _36: std::task::Poll<()>; ++ let mut _37: &mut std::task::Context<'_>; ++ let mut _38: &mut impl std::future::Future; ++ let mut _39: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _40: isize; ++ let mut _41: &mut std::task::Context<'_>; ++ let mut _42: &mut impl std::future::Future; ++ let mut _43: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _44: isize; ++ let mut _45: (); ++ let mut _46: u32; ++ let mut _47: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _48: &mut SyncThenAsync; ++ let mut _49: &mut SyncThenAsync; ++ let mut _50: &mut SyncThenAsync; ++ let mut _51: &mut SyncThenAsync; ++ let mut _52: &mut SyncThenAsync; ++ let mut _53: &mut SyncThenAsync; ++ let mut _54: &mut SyncThenAsync; + + bb0: { +- _3 = move (_1.0: &mut SyncThenAsync); +- _20 = &mut (*_3); +- _21 = ::drop(move _20) -> [return: bb15, unwind: bb5]; ++ _47 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _46 = discriminant((*_47)); ++ switchInt(move _46) -> [0: bb34, 1: bb33, 2: bb32, 3: bb27, 4: bb28, 5: bb29, 6: bb30, 7: bb31, otherwise: bb17]; + } + + bb1: { +- StorageDead(_12); ++ nop; ++ _0 = Poll::<()>::Ready(move _45); ++ discriminant((*_47)) = 1; + return; + } + + bb2 (cleanup): { +- StorageDead(_4); +- StorageDead(_12); +- resume; ++ nop; ++ nop; ++ goto -> bb26; + } + + bb3 (cleanup): { +- drop(((*_3).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _48 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_48).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb4 (cleanup): { + StorageDead(_8); +- StorageDead(_16); +- drop(((*_3).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; ++ nop; ++ _49 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_49).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; + } + + bb5 (cleanup): { +- drop(((*_3).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; ++ _50 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_50).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; + } + + bb6: { +- _5 = &mut ((*_3).3: AsyncInt); +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; ++ _51 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ _13 = &mut ((*_51).3: AsyncInt); ++ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb9, unwind: bb2]; + } + + bb7: { +- StorageDead(_4); ++ nop; + goto -> bb1; + } + + bb8: { +- async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2]; ++ _28 = move _2; ++ goto -> bb16; + } + + bb9: { +- _7 = copy (_6.0: &mut AsyncInt); +- StorageLive(_4); +- _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb2]; ++ _15 = copy (_14.0: &mut AsyncInt); ++ nop; ++ (((*_47) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb8, unwind: bb2]; + } + + bb10: { +- StorageDead(_16); +- drop(((*_3).2: SyncInt)) -> [return: bb6, unwind: bb3]; ++ _52 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ _17 = &mut ((*_52).1: AsyncInt); ++ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb13, unwind: bb4]; + } + + bb11: { +- _13 = &mut ((*_3).3: AsyncInt); +- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb14, unwind: bb2]; ++ nop; ++ _53 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_53).2: SyncInt)) -> [return: bb6, unwind: bb3]; + } + + bb12: { +- StorageDead(_12); +- goto -> bb1; ++ _37 = move _2; ++ goto -> bb22; + } + + bb13: { +- async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb12, unwind: bb2, drop: bb1]; ++ _19 = copy (_18.0: &mut AsyncInt); ++ nop; ++ (((*_47) as variant#7).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb12, unwind: bb4]; + } + + bb14: { +- _15 = copy (_14.0: &mut AsyncInt); +- StorageLive(_12); +- _12 = async_drop_in_place::(move _15) -> [return: bb13, unwind: bb2]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb26]; + } + + bb15: { +- _17 = &mut ((*_3).1: AsyncInt); +- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb18, unwind: bb4]; ++ _0 = Poll::<()>::Pending; ++ discriminant((*_47)) = 4; ++ return; + } + + bb16: { +- StorageDead(_16); +- drop(((*_3).2: SyncInt)) -> [return: bb11, unwind: bb3]; ++ StorageLive(_30); ++ _29 = &mut (((*_47) as variant#5).0: impl std::future::Future); ++ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb19, unwind: bb26]; + } + + bb17: { +- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb16, unwind: bb4, drop: bb10]; ++ unreachable; + } + + bb18: { +- _19 = copy (_18.0: &mut AsyncInt); +- StorageLive(_16); +- _16 = async_drop_in_place::(move _19) -> [return: bb17, unwind: bb4]; ++ StorageDead(_30); ++ _31 = discriminant(_27); ++ switchInt(move _31) -> [0: bb7, 1: bb15, otherwise: bb17]; ++ } ++ ++ bb19: { ++ _27 = as Future>::poll(move _30, move _28) -> [return: bb18, unwind: bb2]; ++ } ++ ++ bb20: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb20, unwind: bb26]; ++ } ++ ++ bb21: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_47)) = 6; ++ return; ++ } ++ ++ bb22: { ++ StorageLive(_39); ++ _38 = &mut (((*_47) as variant#7).1: impl std::future::Future); ++ _39 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb24, unwind: bb26]; ++ } ++ ++ bb23: { ++ StorageDead(_39); ++ _40 = discriminant(_36); ++ switchInt(move _40) -> [0: bb11, 1: bb21, otherwise: bb17]; ++ } ++ ++ bb24: { ++ _36 = as Future>::poll(move _39, move _37) -> [return: bb23, unwind: bb4]; ++ } ++ ++ bb25: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb25, unwind: bb26]; ++ } ++ ++ bb26 (cleanup): { ++ discriminant((*_47)) = 2; ++ resume; ++ } ++ ++ bb27: { ++ _23 = move _2; ++ goto -> bb14; ++ } ++ ++ bb28: { ++ _28 = move _2; ++ goto -> bb16; ++ } ++ ++ bb29: { ++ _32 = move _2; ++ goto -> bb20; ++ } ++ ++ bb30: { ++ _37 = move _2; ++ goto -> bb22; ++ } ++ ++ bb31: { ++ _41 = move _2; ++ goto -> bb25; ++ } ++ ++ bb32: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb32, unwind continue]; ++ } ++ ++ bb33: { ++ _0 = Poll::<()>::Ready(const ()); ++ return; ++ } ++ ++ bb34: { ++ (((*_47) as variant#7).0: &mut SyncThenAsync) = move ((*_47).0: &mut SyncThenAsync); ++ _54 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ _20 = &mut (*_54); ++ _21 = ::drop(move _20) -> [return: bb10, unwind: bb5]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff new file mode 100644 index 0000000000000..005d204e75fa8 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff @@ -0,0 +1,174 @@ +- // MIR for `double::{closure#0}` before ElaborateDrops ++ // MIR for `double::{closure#0}` after ElaborateDrops + + fn double::{closure#0}(_1: {async fn body of double()}, _2: std::future::ResumeTy) -> () + yields () + { + debug _task_context => _2; + let mut _0: (); + let _3: SyncInt; ++ let mut _6: impl std::future::Future; ++ let mut _7: &mut AsyncInt; ++ let mut _8: std::pin::Pin<&mut AsyncInt>; ++ let mut _9: &mut AsyncInt; ++ let mut _10: impl std::future::Future; ++ let mut _11: &mut AsyncInt; ++ let mut _12: std::pin::Pin<&mut AsyncInt>; ++ let mut _13: &mut AsyncInt; ++ let mut _14: impl std::future::Future; ++ let mut _15: &mut {async fn body of double()}; ++ let mut _16: std::pin::Pin<&mut {async fn body of double()}>; ++ let mut _17: &mut {async fn body of double()}; + scope 1 { + debug sync_int => _3; + let _4: AsyncInt; + scope 2 { + debug async_int => _4; + let _5: AsyncInt; + scope 3 { + debug async_int_again => _5; + } + } + } + + bb0: { + StorageLive(_3); + _3 = SyncInt(const 0_i32); + StorageLive(_4); + _4 = AsyncInt(const 0_i32); + StorageLive(_5); + _5 = AsyncInt(const 0_i32); + _0 = const (); +- drop(_5) -> [return: bb1, unwind: bb9, drop: bb5]; ++ _7 = &mut _5; ++ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb17, unwind: bb9]; + } + + bb1: { + StorageDead(_5); +- drop(_4) -> [return: bb2, unwind: bb10, drop: bb6]; ++ _11 = &mut _4; ++ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb20, unwind: bb10]; + } + + bb2: { + StorageDead(_4); + drop(_3) -> [return: bb3, unwind: bb11]; + } + + bb3: { + StorageDead(_3); +- drop(_1) -> [return: bb4, drop: bb8, unwind continue]; ++ _15 = &mut _1; ++ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb23, unwind: bb12]; + } + + bb4: { + return; + } + + bb5: { ++ StorageDead(_6); + StorageDead(_5); +- drop(_4) -> [return: bb6, unwind: bb13]; ++ goto -> bb6; + } + + bb6: { ++ StorageDead(_10); + StorageDead(_4); +- drop(_3) -> [return: bb7, unwind: bb14]; ++ goto -> bb7; + } + + bb7: { + StorageDead(_3); +- drop(_1) -> [return: bb8, unwind continue]; ++ goto -> bb8; + } + + bb8: { ++ StorageDead(_14); + coroutine_drop; + } + + bb9 (cleanup): { ++ StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb10, unwind terminate(cleanup)]; + } + + bb10 (cleanup): { ++ StorageDead(_10); + StorageDead(_4); + drop(_3) -> [return: bb11, unwind terminate(cleanup)]; + } + + bb11 (cleanup): { + StorageDead(_3); + drop(_1) -> [return: bb12, unwind terminate(cleanup)]; + } + + bb12 (cleanup): { ++ StorageDead(_14); + resume; + } + + bb13 (cleanup): { + StorageDead(_4); +- drop(_3) -> [return: bb14, unwind terminate(cleanup)]; ++ goto -> bb14; + } + + bb14 (cleanup): { + StorageDead(_3); +- drop(_1) -> [return: bb12, unwind terminate(cleanup)]; ++ goto -> bb12; ++ } ++ ++ bb15: { ++ StorageDead(_6); ++ goto -> bb1; ++ } ++ ++ bb16: { ++ async drop(_5; poll=_6) -> [return: bb15, unwind: bb9, drop: bb5]; ++ } ++ ++ bb17: { ++ _9 = copy (_8.0: &mut AsyncInt); ++ StorageLive(_6); ++ _6 = async_drop_in_place::(move _9) -> [return: bb16, unwind: bb9]; ++ } ++ ++ bb18: { ++ StorageDead(_10); ++ goto -> bb2; ++ } ++ ++ bb19: { ++ async drop(_4; poll=_10) -> [return: bb18, unwind: bb10, drop: bb6]; ++ } ++ ++ bb20: { ++ _13 = copy (_12.0: &mut AsyncInt); ++ StorageLive(_10); ++ _10 = async_drop_in_place::(move _13) -> [return: bb19, unwind: bb10]; ++ } ++ ++ bb21: { ++ StorageDead(_14); ++ goto -> bb4; ++ } ++ ++ bb22: { ++ async drop(_1; poll=_14) -> [return: bb21, unwind: bb12, drop: bb8]; ++ } ++ ++ bb23: { ++ _17 = copy (_16.0: &mut {async fn body of double()}); ++ StorageLive(_14); ++ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb22, unwind: bb12]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..0495100fd3e51 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff @@ -0,0 +1,345 @@ +- // MIR for `double::{closure#0}` before StateTransform ++ // MIR for `double::{closure#0}` after StateTransform + +- fn double::{closure#0}(_1: {async fn body of double()}, _2: std::future::ResumeTy) -> () +- yields () +- { ++ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: (); ++ field _s1: SyncInt; ++ field _s2: AsyncInt; ++ field _s3: AsyncInt; ++ field _s4: impl Future; ++ field _s5: impl Future; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s2, _s3, _s4], ++ Suspend1 (4): [_s1, _s2, _s3, _s4], ++ Suspend2 (5): [_s0, _s1, _s2, _s5], ++ Suspend3 (6): [_s1, _s2, _s5], ++ } ++ storage_conflicts = BitMatrix(6x6) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s0, _s4), (_s0, _s5), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s1, _s4), (_s1, _s5), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s2, _s4), (_s2, _s5), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3), (_s3, _s4), (_s4, _s0), (_s4, _s1), (_s4, _s2), (_s4, _s3), (_s4, _s4), (_s5, _s0), (_s5, _s1), (_s5, _s2), (_s5, _s5)} ++ } + debug _task_context => _2; +- let mut _0: (); ++ coroutine debug sync_int => _s1; ++ let mut _0: std::task::Poll<()>; + let _3: SyncInt; + let mut _6: impl std::future::Future; + let mut _7: &mut AsyncInt; + let mut _8: std::pin::Pin<&mut AsyncInt>; + let mut _9: &mut AsyncInt; + let mut _10: impl std::future::Future; + let mut _11: &mut AsyncInt; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; + let mut _15: &mut {async fn body of double()}; + let mut _16: std::pin::Pin<&mut {async fn body of double()}>; + let mut _17: &mut {async fn body of double()}; ++ let mut _18: std::task::Poll<()>; ++ let mut _19: &mut std::task::Context<'_>; ++ let mut _20: &mut impl std::future::Future; ++ let mut _21: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _22: isize; ++ let mut _23: &mut std::task::Context<'_>; ++ let mut _24: &mut impl std::future::Future; ++ let mut _25: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _26: isize; ++ let mut _27: std::task::Poll<()>; ++ let mut _28: &mut std::task::Context<'_>; ++ let mut _29: &mut impl std::future::Future; ++ let mut _30: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _31: isize; ++ let mut _32: &mut std::task::Context<'_>; ++ let mut _33: &mut impl std::future::Future; ++ let mut _34: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _35: isize; ++ let mut _36: (); ++ let mut _37: u32; ++ let mut _38: &mut {async fn body of double()}; + scope 1 { +- debug sync_int => _3; ++ debug sync_int => (((*_38) as variant#6).0: SyncInt); ++ coroutine debug async_int => _s2; + let _4: AsyncInt; + scope 2 { +- debug async_int => _4; ++ debug async_int => (((*_38) as variant#6).1: AsyncInt); ++ coroutine debug async_int_again => _s3; + let _5: AsyncInt; + scope 3 { +- debug async_int_again => _5; ++ debug async_int_again => (((*_38) as variant#4).2: AsyncInt); + } + } + } + + bb0: { +- StorageLive(_3); +- _3 = SyncInt(const 0_i32); +- StorageLive(_4); +- _4 = AsyncInt(const 0_i32); +- StorageLive(_5); +- _5 = AsyncInt(const 0_i32); +- _0 = const (); +- _7 = &mut _5; +- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb9]; ++ _38 = copy (_1.0: &mut {async fn body of double()}); ++ _37 = discriminant((*_38)); ++ switchInt(move _37) -> [0: bb37, 1: bb36, 2: bb35, 3: bb31, 4: bb32, 5: bb33, 6: bb34, otherwise: bb20]; + } + + bb1: { +- StorageDead(_5); +- _11 = &mut _4; +- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb18, unwind: bb10]; ++ nop; ++ _11 = &mut (((*_38) as variant#6).1: AsyncInt); ++ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb14, unwind: bb6]; + } + + bb2: { +- StorageDead(_4); +- drop(_3) -> [return: bb3, unwind: bb11]; ++ nop; ++ drop((((*_38) as variant#6).0: SyncInt)) -> [return: bb3, unwind: bb7]; + } + + bb3: { +- StorageDead(_3); +- _15 = &mut _1; +- _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb21, unwind: bb12]; ++ nop; ++ _15 = &mut (*_38); ++ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb17, unwind: bb8]; + } + + bb4: { ++ _0 = Poll::<()>::Ready(move (((*_38) as variant#5).0: ())); ++ discriminant((*_38)) = 1; + return; + } + +- bb5: { +- StorageDead(_6); +- StorageDead(_5); +- goto -> bb6; ++ bb5 (cleanup): { ++ nop; ++ nop; ++ drop((((*_38) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; + } + +- bb6: { +- StorageDead(_10); +- StorageDead(_4); +- goto -> bb7; ++ bb6 (cleanup): { ++ nop; ++ nop; ++ drop((((*_38) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; + } + +- bb7: { +- StorageDead(_3); ++ bb7 (cleanup): { ++ nop; + goto -> bb8; + } + +- bb8: { ++ bb8 (cleanup): { + StorageDead(_14); +- coroutine_drop; ++ goto -> bb30; + } + +- bb9 (cleanup): { +- StorageDead(_6); +- StorageDead(_5); +- drop(_4) -> [return: bb10, unwind terminate(cleanup)]; ++ bb9: { ++ nop; ++ goto -> bb1; + } + +- bb10 (cleanup): { +- StorageDead(_10); +- StorageDead(_4); +- drop(_3) -> [return: bb11, unwind terminate(cleanup)]; ++ bb10: { ++ _19 = move _2; ++ goto -> bb19; + } + +- bb11 (cleanup): { +- StorageDead(_3); +- drop(_1) -> [return: bb12, unwind terminate(cleanup)]; ++ bb11: { ++ _9 = copy (_8.0: &mut AsyncInt); ++ nop; ++ (((*_38) as variant#4).3: impl std::future::Future) = async_drop_in_place::(move _9) -> [return: bb10, unwind: bb5]; + } + +- bb12 (cleanup): { +- StorageDead(_14); +- resume; ++ bb12: { ++ nop; ++ goto -> bb2; + } + + bb13: { +- StorageDead(_6); +- goto -> bb1; ++ _28 = move _2; ++ goto -> bb25; + } + + bb14: { +- async drop(_5; poll=_6) -> [return: bb13, unwind: bb9, drop: bb5]; ++ _13 = copy (_12.0: &mut AsyncInt); ++ nop; ++ (((*_38) as variant#6).2: impl std::future::Future) = async_drop_in_place::(move _13) -> [return: bb13, unwind: bb6]; + } + + bb15: { +- _9 = copy (_8.0: &mut AsyncInt); +- StorageLive(_6); +- _6 = async_drop_in_place::(move _9) -> [return: bb14, unwind: bb9]; ++ StorageDead(_14); ++ goto -> bb4; + } + + bb16: { +- StorageDead(_10); +- goto -> bb2; ++ goto -> bb29; + } + + bb17: { +- async drop(_4; poll=_10) -> [return: bb16, unwind: bb10, drop: bb6]; ++ _17 = copy (_16.0: &mut {async fn body of double()}); ++ StorageLive(_14); ++ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb16, unwind: bb8]; + } + + bb18: { +- _13 = copy (_12.0: &mut AsyncInt); +- StorageLive(_10); +- _10 = async_drop_in_place::(move _13) -> [return: bb17, unwind: bb10]; ++ _0 = Poll::<()>::Pending; ++ discriminant((*_38)) = 3; ++ return; + } + + bb19: { +- StorageDead(_14); +- goto -> bb4; ++ StorageLive(_21); ++ _20 = &mut (((*_38) as variant#4).3: impl std::future::Future); ++ _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb22, unwind: bb30]; + } + + bb20: { +- async drop(_1; poll=_14) -> [return: bb19, unwind: bb12, drop: bb8]; ++ unreachable; + } + + bb21: { +- _17 = copy (_16.0: &mut {async fn body of double()}); +- StorageLive(_14); +- _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb20, unwind: bb12]; ++ StorageDead(_21); ++ _22 = discriminant(_18); ++ switchInt(move _22) -> [0: bb9, 1: bb18, otherwise: bb20]; ++ } ++ ++ bb22: { ++ _18 = as Future>::poll(move _21, move _19) -> [return: bb21, unwind: bb5]; ++ } ++ ++ bb23: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb23, unwind: bb30]; ++ } ++ ++ bb24: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_38)) = 5; ++ return; ++ } ++ ++ bb25: { ++ StorageLive(_30); ++ _29 = &mut (((*_38) as variant#6).2: impl std::future::Future); ++ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb27, unwind: bb30]; ++ } ++ ++ bb26: { ++ StorageDead(_30); ++ _31 = discriminant(_27); ++ switchInt(move _31) -> [0: bb12, 1: bb24, otherwise: bb20]; ++ } ++ ++ bb27: { ++ _27 = as Future>::poll(move _30, move _28) -> [return: bb26, unwind: bb6]; ++ } ++ ++ bb28: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb28, unwind: bb30]; ++ } ++ ++ bb29: { ++ goto -> bb15; ++ } ++ ++ bb30 (cleanup): { ++ discriminant((*_38)) = 2; ++ resume; ++ } ++ ++ bb31: { ++ _19 = move _2; ++ goto -> bb19; ++ } ++ ++ bb32: { ++ _23 = move _2; ++ goto -> bb23; ++ } ++ ++ bb33: { ++ _28 = move _2; ++ goto -> bb25; ++ } ++ ++ bb34: { ++ _32 = move _2; ++ goto -> bb28; ++ } ++ ++ bb35: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb35, unwind continue]; ++ } ++ ++ bb36: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb36, unwind continue]; ++ } ++ ++ bb37: { ++ nop; ++ (((*_38) as variant#6).0: SyncInt) = SyncInt(const 0_i32); ++ nop; ++ (((*_38) as variant#6).1: AsyncInt) = AsyncInt(const 0_i32); ++ nop; ++ (((*_38) as variant#4).2: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_38) as variant#5).0: ()) = const (); ++ _7 = &mut (((*_38) as variant#4).2: AsyncInt); ++ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb11, unwind: bb5]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir new file mode 100644 index 0000000000000..64bf0bc38833b --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir @@ -0,0 +1,278 @@ +// MIR for `double::{closure#0}` 0 coroutine_async_drop_expand + +fn double::{closure#0}(_1: {async fn body of double()}, _2: &mut Context<'_>) -> () +yields () + { + debug _task_context => _2; + let mut _0: (); + let _3: SyncInt; + let mut _6: impl std::future::Future; + let mut _7: &mut AsyncInt; + let mut _8: std::pin::Pin<&mut AsyncInt>; + let mut _9: &mut AsyncInt; + let mut _10: impl std::future::Future; + let mut _11: &mut AsyncInt; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; + let mut _15: &mut {async fn body of double()}; + let mut _16: std::pin::Pin<&mut {async fn body of double()}>; + let mut _17: &mut {async fn body of double()}; + let mut _18: std::task::Poll<()>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: &mut impl std::future::Future; + let mut _21: std::pin::Pin<&mut impl std::future::Future>; + let mut _22: isize; + let mut _23: &mut std::task::Context<'_>; + let mut _24: &mut impl std::future::Future; + let mut _25: std::pin::Pin<&mut impl std::future::Future>; + let mut _26: isize; + let mut _27: std::task::Poll<()>; + let mut _28: &mut std::task::Context<'_>; + let mut _29: &mut impl std::future::Future; + let mut _30: std::pin::Pin<&mut impl std::future::Future>; + let mut _31: isize; + let mut _32: &mut std::task::Context<'_>; + let mut _33: &mut impl std::future::Future; + let mut _34: std::pin::Pin<&mut impl std::future::Future>; + let mut _35: isize; + scope 1 { + debug sync_int => _3; + let _4: AsyncInt; + scope 2 { + debug async_int => _4; + let _5: AsyncInt; + scope 3 { + debug async_int_again => _5; + } + } + } + + bb0: { + StorageLive(_3); + _3 = SyncInt(const 0_i32); + StorageLive(_4); + _4 = AsyncInt(const 0_i32); + StorageLive(_5); + _5 = AsyncInt(const 0_i32); + _0 = const (); + _7 = &mut _5; + _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb9]; + } + + bb1: { + StorageDead(_5); + _11 = &mut _4; + _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb18, unwind: bb10]; + } + + bb2: { + StorageDead(_4); + drop(_3) -> [return: bb3, unwind: bb11]; + } + + bb3: { + StorageDead(_3); + _15 = &mut _1; + _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb21, unwind: bb12]; + } + + bb4: { + return; + } + + bb5: { + StorageDead(_6); + StorageDead(_5); + goto -> bb6; + } + + bb6: { + StorageDead(_10); + StorageDead(_4); + goto -> bb7; + } + + bb7: { + StorageDead(_3); + goto -> bb8; + } + + bb8: { + StorageDead(_14); + coroutine_drop; + } + + bb9 (cleanup): { + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb10, unwind terminate(cleanup)]; + } + + bb10 (cleanup): { + StorageDead(_10); + StorageDead(_4); + drop(_3) -> [return: bb11, unwind terminate(cleanup)]; + } + + bb11 (cleanup): { + StorageDead(_3); + drop(_1) -> [return: bb12, unwind terminate(cleanup)]; + } + + bb12 (cleanup): { + StorageDead(_14); + resume; + } + + bb13: { + StorageDead(_6); + goto -> bb1; + } + + bb14: { + _19 = move _2; + goto -> bb23; + } + + bb15: { + _9 = copy (_8.0: &mut AsyncInt); + StorageLive(_6); + _6 = async_drop_in_place::(move _9) -> [return: bb14, unwind: bb9]; + } + + bb16: { + StorageDead(_10); + goto -> bb2; + } + + bb17: { + _28 = move _2; + goto -> bb34; + } + + bb18: { + _13 = copy (_12.0: &mut AsyncInt); + StorageLive(_10); + _10 = async_drop_in_place::(move _13) -> [return: bb17, unwind: bb10]; + } + + bb19: { + StorageDead(_14); + goto -> bb4; + } + + bb20: { + drop(_1) -> [return: bb19, unwind: bb12]; + } + + bb21: { + _17 = copy (_16.0: &mut {async fn body of double()}); + StorageLive(_14); + _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb20, unwind: bb12]; + } + + bb22: { + _19 = yield(const false) -> [resume: bb23, drop: bb28]; + } + + bb23: { + StorageLive(_21); + _20 = &mut _6; + _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb26, unwind continue]; + } + + bb24: { + unreachable; + } + + bb25: { + StorageDead(_21); + _22 = discriminant(_18); + switchInt(move _22) -> [0: bb13, 1: bb22, otherwise: bb24]; + } + + bb26: { + _18 = as Future>::poll(move _21, move _19) -> [return: bb25, unwind: bb9]; + } + + bb27: { + _23 = yield(const false) -> [resume: bb32, drop: bb28]; + } + + bb28: { + StorageLive(_25); + _24 = &mut _6; + _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb31, unwind continue]; + } + + bb29: { + unreachable; + } + + bb30: { + StorageDead(_25); + _26 = discriminant(_18); + switchInt(move _26) -> [0: bb5, 1: bb27, otherwise: bb29]; + } + + bb31: { + _18 = as Future>::poll(move _25, move _23) -> [return: bb30, unwind: bb9]; + } + + bb32: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb32, unwind continue]; + } + + bb33: { + _28 = yield(const false) -> [resume: bb34, drop: bb39]; + } + + bb34: { + StorageLive(_30); + _29 = &mut _10; + _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb37, unwind continue]; + } + + bb35: { + unreachable; + } + + bb36: { + StorageDead(_30); + _31 = discriminant(_27); + switchInt(move _31) -> [0: bb16, 1: bb33, otherwise: bb35]; + } + + bb37: { + _27 = as Future>::poll(move _30, move _28) -> [return: bb36, unwind: bb10]; + } + + bb38: { + _32 = yield(const false) -> [resume: bb43, drop: bb39]; + } + + bb39: { + StorageLive(_34); + _33 = &mut _10; + _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb42, unwind continue]; + } + + bb40: { + unreachable; + } + + bb41: { + StorageDead(_34); + _35 = discriminant(_27); + switchInt(move _35) -> [0: bb6, 1: bb38, otherwise: bb40]; + } + + bb42: { + _27 = as Future>::poll(move _34, move _32) -> [return: bb41, unwind: bb10]; + } + + bb43: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb43, unwind continue]; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir new file mode 100644 index 0000000000000..7d16583b7ae96 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir @@ -0,0 +1,197 @@ +// MIR for `double::{closure#0}` 0 coroutine_drop_async + +fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Context<'_>) -> Poll<()> { + debug _task_context => _2; + let mut _0: std::task::Poll<()>; + let _3: SyncInt; + let mut _6: impl std::future::Future; + let mut _7: &mut AsyncInt; + let mut _8: std::pin::Pin<&mut AsyncInt>; + let mut _9: &mut AsyncInt; + let mut _10: impl std::future::Future; + let mut _11: &mut AsyncInt; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; + let mut _15: &mut {async fn body of double()}; + let mut _16: std::pin::Pin<&mut {async fn body of double()}>; + let mut _17: &mut {async fn body of double()}; + let mut _18: std::task::Poll<()>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: &mut impl std::future::Future; + let mut _21: std::pin::Pin<&mut impl std::future::Future>; + let mut _22: isize; + let mut _23: &mut std::task::Context<'_>; + let mut _24: &mut impl std::future::Future; + let mut _25: std::pin::Pin<&mut impl std::future::Future>; + let mut _26: isize; + let mut _27: std::task::Poll<()>; + let mut _28: &mut std::task::Context<'_>; + let mut _29: &mut impl std::future::Future; + let mut _30: std::pin::Pin<&mut impl std::future::Future>; + let mut _31: isize; + let mut _32: &mut std::task::Context<'_>; + let mut _33: &mut impl std::future::Future; + let mut _34: std::pin::Pin<&mut impl std::future::Future>; + let mut _35: isize; + let mut _36: (); + let mut _37: u32; + let mut _38: &mut {async fn body of double()}; + scope 1 { + debug sync_int => (((*_38) as variant#6).0: SyncInt); + let _4: AsyncInt; + scope 2 { + debug async_int => (((*_38) as variant#6).1: AsyncInt); + let _5: AsyncInt; + scope 3 { + debug async_int_again => (((*_38) as variant#4).2: AsyncInt); + } + } + } + + bb0: { + _38 = copy (_1.0: &mut {async fn body of double()}); + _37 = discriminant((*_38)); + switchInt(move _37) -> [0: bb19, 2: bb26, 3: bb22, 4: bb23, 5: bb24, 6: bb25, otherwise: bb27]; + } + + bb1: { + nop; + nop; + goto -> bb2; + } + + bb2: { + nop; + nop; + goto -> bb3; + } + + bb3: { + nop; + goto -> bb4; + } + + bb4: { + StorageDead(_14); + _0 = Poll::<()>::Ready(const ()); + return; + } + + bb5 (cleanup): { + nop; + nop; + drop((((*_38) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; + } + + bb6 (cleanup): { + nop; + nop; + drop((((*_38) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; + } + + bb7 (cleanup): { + nop; + goto -> bb8; + } + + bb8 (cleanup): { + StorageDead(_14); + goto -> bb21; + } + + bb9: { + _0 = Poll::<()>::Pending; + discriminant((*_38)) = 4; + return; + } + + bb10: { + StorageLive(_25); + _24 = &mut (((*_38) as variant#4).3: impl std::future::Future); + _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb13, unwind: bb21]; + } + + bb11: { + unreachable; + } + + bb12: { + StorageDead(_25); + _26 = discriminant(_18); + switchInt(move _26) -> [0: bb1, 1: bb9, otherwise: bb11]; + } + + bb13: { + _18 = as Future>::poll(move _25, move _23) -> [return: bb12, unwind: bb5]; + } + + bb14: { + _0 = Poll::<()>::Pending; + discriminant((*_38)) = 6; + return; + } + + bb15: { + StorageLive(_34); + _33 = &mut (((*_38) as variant#6).2: impl std::future::Future); + _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb17, unwind: bb21]; + } + + bb16: { + StorageDead(_34); + _35 = discriminant(_27); + switchInt(move _35) -> [0: bb2, 1: bb14, otherwise: bb11]; + } + + bb17: { + _27 = as Future>::poll(move _34, move _32) -> [return: bb16, unwind: bb6]; + } + + bb18: { + _0 = Poll::<()>::Ready(const ()); + return; + } + + bb19: { + goto -> bb20; + } + + bb20: { + goto -> bb18; + } + + bb21 (cleanup): { + discriminant((*_38)) = 2; + resume; + } + + bb22: { + _19 = move _2; + goto -> bb10; + } + + bb23: { + _23 = move _2; + goto -> bb10; + } + + bb24: { + _28 = move _2; + goto -> bb15; + } + + bb25: { + _32 = move _2; + goto -> bb15; + } + + bb26: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb26, unwind continue]; + } + + bb27: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff new file mode 100644 index 0000000000000..936543ef54f7e --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff @@ -0,0 +1,811 @@ +- // MIR for `elaborate_drops::{closure#0}` before ElaborateDrops ++ // MIR for `elaborate_drops::{closure#0}` after ElaborateDrops + + fn elaborate_drops::{closure#0}(_1: {async fn body of elaborate_drops()}, _2: std::future::ResumeTy) -> () + yields () + { + debug _task_context => _2; + let mut _0: (); + let _3: SyncInt; + let mut _6: AsyncInt; + let mut _7: AsyncInt; + let mut _9: AsyncInt; + let mut _10: AsyncInt; + let mut _12: AsyncInt; + let mut _13: SyncInt; + let mut _14: AsyncInt; + let mut _16: AsyncInt; + let mut _18: AsyncInt; + let mut _21: &AsyncInt; + let _22: &AsyncInt; ++ let mut _27: impl std::future::Future; ++ let mut _28: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; ++ let mut _29: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>; ++ let mut _30: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; ++ let mut _31: impl std::future::Future; ++ let mut _32: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; ++ let mut _33: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>; ++ let mut _34: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; ++ let mut _35: impl std::future::Future; ++ let mut _36: &mut AsyncReference<'_>; ++ let mut _37: std::pin::Pin<&mut AsyncReference<'_>>; ++ let mut _38: &mut AsyncReference<'_>; ++ let mut _39: impl std::future::Future; ++ let mut _40: &mut AsyncInt; ++ let mut _41: std::pin::Pin<&mut AsyncInt>; ++ let mut _42: &mut AsyncInt; ++ let mut _43: impl std::future::Future; ++ let mut _44: &mut AsyncEnum; ++ let mut _45: std::pin::Pin<&mut AsyncEnum>; ++ let mut _46: &mut AsyncEnum; ++ let mut _47: impl std::future::Future; ++ let mut _48: &mut SyncThenAsync; ++ let mut _49: std::pin::Pin<&mut SyncThenAsync>; ++ let mut _50: &mut SyncThenAsync; ++ let mut _51: impl std::future::Future; ++ let mut _52: &mut AsyncStruct; ++ let mut _53: std::pin::Pin<&mut AsyncStruct>; ++ let mut _54: &mut AsyncStruct; ++ let mut _55: impl std::future::Future; ++ let mut _56: &mut [AsyncInt; 2]; ++ let mut _57: std::pin::Pin<&mut [AsyncInt; 2]>; ++ let mut _58: &mut [AsyncInt; 2]; ++ let mut _59: impl std::future::Future; ++ let mut _60: &mut AsyncInt; ++ let mut _61: std::pin::Pin<&mut AsyncInt>; ++ let mut _62: &mut AsyncInt; ++ let mut _63: impl std::future::Future; ++ let mut _64: &mut {async fn body of elaborate_drops()}; ++ let mut _65: std::pin::Pin<&mut {async fn body of elaborate_drops()}>; ++ let mut _66: &mut {async fn body of elaborate_drops()}; + scope 1 { + debug sync_int => _3; + let _4: AsyncInt; + scope 2 { + debug async_int => _4; + let _5: [AsyncInt; 2]; + scope 3 { + debug tuple => _5; + let _8: AsyncStruct; + scope 4 { + debug async_struct => _8; + let _11: SyncThenAsync; + scope 5 { + debug async_struct_mix => _11; + let _15: AsyncEnum; + scope 6 { + debug async_enum => _15; + let _17: std::mem::ManuallyDrop; + scope 7 { + debug manually_drop_async_int => _17; + let _19: AsyncInt; + scope 8 { + debug foo => _19; + let _20: AsyncReference<'_>; + scope 9 { + debug async_ref => _20; + let _23: AsyncInt; + scope 10 { + debug foo => _23; + let _24: {closure@$DIR/async_drop.rs:72:25: 72:27}; + scope 11 { + debug async_closure => _24; + let _25: AsyncInt; + scope 12 { + debug foo => _25; + let _26: {async closure@$DIR/async_drop.rs:80:27: 80:35}; + scope 13 { + debug async_coroutine => _26; + } + } + } + } + } + } + } + } + } + } + } + } + } + + bb0: { + StorageLive(_3); + _3 = SyncInt(const 0_i32); + StorageLive(_4); + _4 = AsyncInt(const 0_i32); + StorageLive(_5); + StorageLive(_6); + _6 = AsyncInt(const 1_i32); + StorageLive(_7); + _7 = AsyncInt(const 2_i32); + _5 = [move _6, move _7]; +- drop(_7) -> [return: bb1, unwind: bb62, drop: bb38]; ++ goto -> bb1; + } + + bb1: { + StorageDead(_7); +- drop(_6) -> [return: bb2, unwind: bb63, drop: bb39]; ++ goto -> bb2; + } + + bb2: { + StorageDead(_6); + StorageLive(_8); + StorageLive(_9); + _9 = AsyncInt(const 5_i32); + StorageLive(_10); + _10 = AsyncInt(const 4_i32); + _8 = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; +- drop(_10) -> [return: bb3, unwind: bb59, drop: bb35]; ++ goto -> bb3; + } + + bb3: { + StorageDead(_10); +- drop(_9) -> [return: bb4, unwind: bb60, drop: bb36]; ++ goto -> bb4; + } + + bb4: { + StorageDead(_9); + StorageLive(_11); + StorageLive(_12); + _12 = AsyncInt(const 7_i32); + StorageLive(_13); + _13 = SyncInt(const 8_i32); + StorageLive(_14); + _14 = AsyncInt(const 9_i32); + _11 = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; +- drop(_14) -> [return: bb5, unwind: bb55, drop: bb31]; ++ goto -> bb5; + } + + bb5: { + StorageDead(_14); +- drop(_13) -> [return: bb6, unwind: bb56]; ++ goto -> bb6; + } + + bb6: { + StorageDead(_13); +- drop(_12) -> [return: bb7, unwind: bb57, drop: bb33]; ++ goto -> bb7; + } + + bb7: { + StorageDead(_12); + StorageLive(_15); + StorageLive(_16); + _16 = AsyncInt(const 10_i32); + _15 = AsyncEnum::A(move _16); +- drop(_16) -> [return: bb8, unwind: bb53, drop: bb29]; ++ goto -> bb8; + } + + bb8: { + StorageDead(_16); + StorageLive(_17); + StorageLive(_18); + _18 = AsyncInt(const 11_i32); + _17 = ManuallyDrop::::new(move _18) -> [return: bb9, unwind: bb50]; + } + + bb9: { + StorageDead(_18); + StorageLive(_19); + _19 = AsyncInt(const 12_i32); + StorageLive(_20); + StorageLive(_21); + StorageLive(_22); + _22 = &_19; + _21 = &(*_22); + _20 = AsyncReference::<'_> { foo: move _21 }; + StorageDead(_21); + StorageDead(_22); + StorageLive(_23); + _23 = AsyncInt(const 14_i32); + StorageLive(_24); + _24 = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; + StorageLive(_25); + _25 = AsyncInt(const 15_i32); + StorageLive(_26); + _26 = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; + _0 = const (); +- drop(_26) -> [return: bb10, unwind: bb44, drop: bb23]; ++ _28 = &mut _26; ++ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb85, unwind: bb44]; + } + + bb10: { + StorageDead(_26); +- drop(_25) -> [return: bb11, unwind: bb45, drop: bb24]; ++ goto -> bb11; + } + + bb11: { + StorageDead(_25); +- drop(_24) -> [return: bb12, unwind: bb46, drop: bb25]; ++ _32 = &mut _24; ++ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb88, unwind: bb46]; + } + + bb12: { + StorageDead(_24); +- drop(_23) -> [return: bb13, unwind: bb47, drop: bb26]; ++ goto -> bb13; + } + + bb13: { + StorageDead(_23); +- drop(_20) -> [return: bb14, unwind: bb48, drop: bb27]; ++ _36 = &mut _20; ++ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb91, unwind: bb48]; + } + + bb14: { + StorageDead(_20); +- drop(_19) -> [return: bb15, unwind: bb49, drop: bb28]; ++ _40 = &mut _19; ++ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb94, unwind: bb49]; + } + + bb15: { + StorageDead(_19); + StorageDead(_17); +- drop(_15) -> [return: bb16, unwind: bb54, drop: bb30]; ++ _44 = &mut _15; ++ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb97, unwind: bb54]; + } + + bb16: { + StorageDead(_15); +- drop(_11) -> [return: bb17, unwind: bb58, drop: bb34]; ++ _48 = &mut _11; ++ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb100, unwind: bb58]; + } + + bb17: { + StorageDead(_11); +- drop(_8) -> [return: bb18, unwind: bb61, drop: bb37]; ++ _52 = &mut _8; ++ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb103, unwind: bb61]; + } + + bb18: { + StorageDead(_8); +- drop(_5) -> [return: bb19, unwind: bb64, drop: bb40]; ++ _56 = &mut _5; ++ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb106, unwind: bb64]; + } + + bb19: { + StorageDead(_5); +- drop(_4) -> [return: bb20, unwind: bb65, drop: bb41]; ++ _60 = &mut _4; ++ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb109, unwind: bb65]; + } + + bb20: { + StorageDead(_4); + drop(_3) -> [return: bb21, unwind: bb66]; + } + + bb21: { + StorageDead(_3); +- drop(_1) -> [return: bb22, drop: bb43, unwind continue]; ++ _64 = &mut _1; ++ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb112, unwind: bb67]; + } + + bb22: { + return; + } + + bb23: { ++ StorageDead(_27); + StorageDead(_26); +- drop(_25) -> [return: bb24, unwind: bb68]; ++ goto -> bb24; + } + + bb24: { + StorageDead(_25); +- drop(_24) -> [return: bb25, unwind: bb69]; ++ goto -> bb25; + } + + bb25: { ++ StorageDead(_31); + StorageDead(_24); +- drop(_23) -> [return: bb26, unwind: bb70]; ++ goto -> bb26; + } + + bb26: { + StorageDead(_23); +- drop(_20) -> [return: bb27, unwind: bb71]; ++ goto -> bb27; + } + + bb27: { ++ StorageDead(_35); + StorageDead(_20); +- drop(_19) -> [return: bb28, unwind: bb72]; ++ goto -> bb28; + } + + bb28: { ++ StorageDead(_39); + StorageDead(_19); + StorageDead(_17); +- drop(_15) -> [return: bb30, unwind: bb73]; ++ goto -> bb30; + } + + bb29: { + StorageDead(_16); + goto -> bb30; + } + + bb30: { ++ StorageDead(_43); + StorageDead(_15); +- drop(_11) -> [return: bb34, unwind: bb76]; ++ goto -> bb34; + } + + bb31: { + StorageDead(_14); +- drop(_13) -> [return: bb32, unwind: bb74]; ++ goto -> bb32; + } + + bb32: { + StorageDead(_13); +- drop(_12) -> [return: bb33, unwind: bb75]; ++ goto -> bb33; + } + + bb33: { + StorageDead(_12); + goto -> bb34; + } + + bb34: { ++ StorageDead(_47); + StorageDead(_11); +- drop(_8) -> [return: bb37, unwind: bb78]; ++ goto -> bb37; + } + + bb35: { + StorageDead(_10); +- drop(_9) -> [return: bb36, unwind: bb77]; ++ goto -> bb36; + } + + bb36: { + StorageDead(_9); + goto -> bb37; + } + + bb37: { ++ StorageDead(_51); + StorageDead(_8); +- drop(_5) -> [return: bb40, unwind: bb80]; ++ goto -> bb40; + } + + bb38: { + StorageDead(_7); +- drop(_6) -> [return: bb39, unwind: bb79]; ++ goto -> bb39; + } + + bb39: { + StorageDead(_6); + goto -> bb40; + } + + bb40: { ++ StorageDead(_55); + StorageDead(_5); +- drop(_4) -> [return: bb41, unwind: bb81]; ++ goto -> bb41; + } + + bb41: { ++ StorageDead(_59); + StorageDead(_4); +- drop(_3) -> [return: bb42, unwind: bb82]; ++ goto -> bb42; + } + + bb42: { + StorageDead(_3); +- drop(_1) -> [return: bb43, unwind continue]; ++ goto -> bb43; + } + + bb43: { ++ StorageDead(_63); + coroutine_drop; + } + + bb44 (cleanup): { ++ StorageDead(_27); + StorageDead(_26); +- drop(_25) -> [return: bb45, unwind terminate(cleanup)]; ++ goto -> bb45; + } + + bb45 (cleanup): { + StorageDead(_25); + drop(_24) -> [return: bb46, unwind terminate(cleanup)]; + } + + bb46 (cleanup): { ++ StorageDead(_31); + StorageDead(_24); +- drop(_23) -> [return: bb47, unwind terminate(cleanup)]; ++ goto -> bb47; + } + + bb47 (cleanup): { + StorageDead(_23); + drop(_20) -> [return: bb48, unwind terminate(cleanup)]; + } + + bb48 (cleanup): { ++ StorageDead(_35); + StorageDead(_20); + drop(_19) -> [return: bb49, unwind terminate(cleanup)]; + } + + bb49 (cleanup): { ++ StorageDead(_39); + StorageDead(_19); + goto -> bb52; + } + + bb50 (cleanup): { +- drop(_18) -> [return: bb51, unwind terminate(cleanup)]; ++ goto -> bb51; + } + + bb51 (cleanup): { + StorageDead(_18); + goto -> bb52; + } + + bb52 (cleanup): { + StorageDead(_17); + drop(_15) -> [return: bb54, unwind terminate(cleanup)]; + } + + bb53 (cleanup): { + StorageDead(_16); + goto -> bb54; + } + + bb54 (cleanup): { ++ StorageDead(_43); + StorageDead(_15); + drop(_11) -> [return: bb58, unwind terminate(cleanup)]; + } + + bb55 (cleanup): { + StorageDead(_14); +- drop(_13) -> [return: bb56, unwind terminate(cleanup)]; ++ goto -> bb56; + } + + bb56 (cleanup): { + StorageDead(_13); +- drop(_12) -> [return: bb57, unwind terminate(cleanup)]; ++ goto -> bb57; + } + + bb57 (cleanup): { + StorageDead(_12); + goto -> bb58; + } + + bb58 (cleanup): { ++ StorageDead(_47); + StorageDead(_11); + drop(_8) -> [return: bb61, unwind terminate(cleanup)]; + } + + bb59 (cleanup): { + StorageDead(_10); +- drop(_9) -> [return: bb60, unwind terminate(cleanup)]; ++ goto -> bb60; + } + + bb60 (cleanup): { + StorageDead(_9); + goto -> bb61; + } + + bb61 (cleanup): { ++ StorageDead(_51); + StorageDead(_8); + drop(_5) -> [return: bb64, unwind terminate(cleanup)]; + } + + bb62 (cleanup): { + StorageDead(_7); +- drop(_6) -> [return: bb63, unwind terminate(cleanup)]; ++ goto -> bb63; + } + + bb63 (cleanup): { + StorageDead(_6); + goto -> bb64; + } + + bb64 (cleanup): { ++ StorageDead(_55); + StorageDead(_5); + drop(_4) -> [return: bb65, unwind terminate(cleanup)]; + } + + bb65 (cleanup): { ++ StorageDead(_59); + StorageDead(_4); + drop(_3) -> [return: bb66, unwind terminate(cleanup)]; + } + + bb66 (cleanup): { + StorageDead(_3); + drop(_1) -> [return: bb67, unwind terminate(cleanup)]; + } + + bb67 (cleanup): { ++ StorageDead(_63); + resume; + } + + bb68 (cleanup): { + StorageDead(_25); +- drop(_24) -> [return: bb69, unwind terminate(cleanup)]; ++ goto -> bb69; + } + + bb69 (cleanup): { + StorageDead(_24); +- drop(_23) -> [return: bb70, unwind terminate(cleanup)]; ++ goto -> bb70; + } + + bb70 (cleanup): { + StorageDead(_23); +- drop(_20) -> [return: bb71, unwind terminate(cleanup)]; ++ goto -> bb71; + } + + bb71 (cleanup): { + StorageDead(_20); +- drop(_19) -> [return: bb72, unwind terminate(cleanup)]; ++ goto -> bb72; + } + + bb72 (cleanup): { + StorageDead(_19); + StorageDead(_17); +- drop(_15) -> [return: bb73, unwind terminate(cleanup)]; ++ goto -> bb73; + } + + bb73 (cleanup): { + StorageDead(_15); +- drop(_11) -> [return: bb76, unwind terminate(cleanup)]; ++ goto -> bb76; + } + + bb74 (cleanup): { + StorageDead(_13); +- drop(_12) -> [return: bb75, unwind terminate(cleanup)]; ++ goto -> bb75; + } + + bb75 (cleanup): { + StorageDead(_12); + goto -> bb76; + } + + bb76 (cleanup): { + StorageDead(_11); +- drop(_8) -> [return: bb78, unwind terminate(cleanup)]; ++ goto -> bb78; + } + + bb77 (cleanup): { + StorageDead(_9); + goto -> bb78; + } + + bb78 (cleanup): { + StorageDead(_8); +- drop(_5) -> [return: bb80, unwind terminate(cleanup)]; ++ goto -> bb80; + } + + bb79 (cleanup): { + StorageDead(_6); + goto -> bb80; + } + + bb80 (cleanup): { + StorageDead(_5); +- drop(_4) -> [return: bb81, unwind terminate(cleanup)]; ++ goto -> bb81; + } + + bb81 (cleanup): { + StorageDead(_4); +- drop(_3) -> [return: bb82, unwind terminate(cleanup)]; ++ goto -> bb82; + } + + bb82 (cleanup): { + StorageDead(_3); +- drop(_1) -> [return: bb67, unwind terminate(cleanup)]; ++ goto -> bb67; ++ } ++ ++ bb83: { ++ StorageDead(_27); ++ goto -> bb10; ++ } ++ ++ bb84: { ++ async drop(_26; poll=_27) -> [return: bb83, unwind: bb44, drop: bb23]; ++ } ++ ++ bb85: { ++ _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ StorageLive(_27); ++ _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb84, unwind: bb44]; ++ } ++ ++ bb86: { ++ StorageDead(_31); ++ goto -> bb12; ++ } ++ ++ bb87: { ++ async drop(_24; poll=_31) -> [return: bb86, unwind: bb46, drop: bb25]; ++ } ++ ++ bb88: { ++ _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); ++ StorageLive(_31); ++ _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb87, unwind: bb46]; ++ } ++ ++ bb89: { ++ StorageDead(_35); ++ goto -> bb14; ++ } ++ ++ bb90: { ++ async drop(_20; poll=_35) -> [return: bb89, unwind: bb48, drop: bb27]; ++ } ++ ++ bb91: { ++ _38 = copy (_37.0: &mut AsyncReference<'_>); ++ StorageLive(_35); ++ _35 = async_drop_in_place::>(move _38) -> [return: bb90, unwind: bb48]; ++ } ++ ++ bb92: { ++ StorageDead(_39); ++ goto -> bb15; ++ } ++ ++ bb93: { ++ async drop(_19; poll=_39) -> [return: bb92, unwind: bb49, drop: bb28]; ++ } ++ ++ bb94: { ++ _42 = copy (_41.0: &mut AsyncInt); ++ StorageLive(_39); ++ _39 = async_drop_in_place::(move _42) -> [return: bb93, unwind: bb49]; ++ } ++ ++ bb95: { ++ StorageDead(_43); ++ goto -> bb16; ++ } ++ ++ bb96: { ++ async drop(_15; poll=_43) -> [return: bb95, unwind: bb54, drop: bb30]; ++ } ++ ++ bb97: { ++ _46 = copy (_45.0: &mut AsyncEnum); ++ StorageLive(_43); ++ _43 = async_drop_in_place::(move _46) -> [return: bb96, unwind: bb54]; ++ } ++ ++ bb98: { ++ StorageDead(_47); ++ goto -> bb17; ++ } ++ ++ bb99: { ++ async drop(_11; poll=_47) -> [return: bb98, unwind: bb58, drop: bb34]; ++ } ++ ++ bb100: { ++ _50 = copy (_49.0: &mut SyncThenAsync); ++ StorageLive(_47); ++ _47 = async_drop_in_place::(move _50) -> [return: bb99, unwind: bb58]; ++ } ++ ++ bb101: { ++ StorageDead(_51); ++ goto -> bb18; ++ } ++ ++ bb102: { ++ async drop(_8; poll=_51) -> [return: bb101, unwind: bb61, drop: bb37]; ++ } ++ ++ bb103: { ++ _54 = copy (_53.0: &mut AsyncStruct); ++ StorageLive(_51); ++ _51 = async_drop_in_place::(move _54) -> [return: bb102, unwind: bb61]; ++ } ++ ++ bb104: { ++ StorageDead(_55); ++ goto -> bb19; ++ } ++ ++ bb105: { ++ async drop(_5; poll=_55) -> [return: bb104, unwind: bb64, drop: bb40]; ++ } ++ ++ bb106: { ++ _58 = copy (_57.0: &mut [AsyncInt; 2]); ++ StorageLive(_55); ++ _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb105, unwind: bb64]; ++ } ++ ++ bb107: { ++ StorageDead(_59); ++ goto -> bb20; ++ } ++ ++ bb108: { ++ async drop(_4; poll=_59) -> [return: bb107, unwind: bb65, drop: bb41]; ++ } ++ ++ bb109: { ++ _62 = copy (_61.0: &mut AsyncInt); ++ StorageLive(_59); ++ _59 = async_drop_in_place::(move _62) -> [return: bb108, unwind: bb65]; ++ } ++ ++ bb110: { ++ StorageDead(_63); ++ goto -> bb22; ++ } ++ ++ bb111: { ++ async drop(_1; poll=_63) -> [return: bb110, unwind: bb67, drop: bb43]; ++ } ++ ++ bb112: { ++ _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); ++ StorageLive(_63); ++ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb111, unwind: bb67]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..a1fc27c9783b2 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff @@ -0,0 +1,1275 @@ +- // MIR for `elaborate_drops::{closure#0}` before StateTransform ++ // MIR for `elaborate_drops::{closure#0}` after StateTransform + +- fn elaborate_drops::{closure#0}(_1: {async fn body of elaborate_drops()}, _2: std::future::ResumeTy) -> () +- yields () +- { ++ fn elaborate_drops::{closure#0}(_1: Pin<&mut {async fn body of elaborate_drops()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: (); ++ field _s1: SyncInt; ++ field _s2: AsyncInt; ++ field _s3: [AsyncInt; 2]; ++ field _s4: AsyncStruct; ++ field _s5: SyncThenAsync; ++ field _s6: AsyncEnum; ++ field _s7: AsyncInt; ++ field _s8: AsyncReference<'_>; ++ field _s9: {closure@$DIR/async_drop.rs:72:25: 72:27}; ++ field _s10: {async closure@$DIR/async_drop.rs:80:27: 80:35}; ++ field _s11: impl Future; ++ field _s12: impl Future; ++ field _s13: impl Future; ++ field _s14: impl Future; ++ field _s15: impl Future; ++ field _s16: impl Future; ++ field _s17: impl Future; ++ field _s18: impl Future; ++ field _s19: impl Future; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11], ++ Suspend1 (4): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11], ++ Suspend2 (5): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s12], ++ Suspend3 (6): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s12], ++ Suspend4 (7): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s13], ++ Suspend5 (8): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s13], ++ Suspend6 (9): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s14], ++ Suspend7 (10): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s14], ++ Suspend8 (11): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s15], ++ Suspend9 (12): [_s1, _s2, _s3, _s4, _s5, _s6, _s15], ++ Suspend10(13): [_s0, _s1, _s2, _s3, _s4, _s5, _s16], ++ Suspend11(14): [_s1, _s2, _s3, _s4, _s5, _s16], ++ Suspend12(15): [_s0, _s1, _s2, _s3, _s4, _s17], ++ Suspend13(16): [_s1, _s2, _s3, _s4, _s17], ++ Suspend14(17): [_s0, _s1, _s2, _s3, _s18], ++ Suspend15(18): [_s1, _s2, _s3, _s18], ++ Suspend16(19): [_s0, _s1, _s2, _s19], ++ Suspend17(20): [_s1, _s2, _s19], ++ } ++ storage_conflicts = BitMatrix(20x20) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s0, _s4), (_s0, _s5), (_s0, _s6), (_s0, _s7), (_s0, _s8), (_s0, _s9), (_s0, _s10), (_s0, _s11), (_s0, _s12), (_s0, _s13), (_s0, _s14), (_s0, _s15), (_s0, _s16), (_s0, _s17), (_s0, _s18), (_s0, _s19), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s1, _s4), (_s1, _s5), (_s1, _s6), (_s1, _s7), (_s1, _s8), (_s1, _s9), (_s1, _s10), (_s1, _s11), (_s1, _s12), (_s1, _s13), (_s1, _s14), (_s1, _s15), (_s1, _s16), (_s1, _s17), (_s1, _s18), (_s1, _s19), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s2, _s4), (_s2, _s5), (_s2, _s6), (_s2, _s7), (_s2, _s8), (_s2, _s9), (_s2, _s10), (_s2, _s11), (_s2, _s12), (_s2, _s13), (_s2, _s14), (_s2, _s15), (_s2, _s16), (_s2, _s17), (_s2, _s18), (_s2, _s19), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3), (_s3, _s4), (_s3, _s5), (_s3, _s6), (_s3, _s7), (_s3, _s8), (_s3, _s9), (_s3, _s10), (_s3, _s11), (_s3, _s12), (_s3, _s13), (_s3, _s14), (_s3, _s15), (_s3, _s16), (_s3, _s17), (_s3, _s18), (_s4, _s0), (_s4, _s1), (_s4, _s2), (_s4, _s3), (_s4, _s4), (_s4, _s5), (_s4, _s6), (_s4, _s7), (_s4, _s8), (_s4, _s9), (_s4, _s10), (_s4, _s11), (_s4, _s12), (_s4, _s13), (_s4, _s14), (_s4, _s15), (_s4, _s16), (_s4, _s17), (_s5, _s0), (_s5, _s1), (_s5, _s2), (_s5, _s3), (_s5, _s4), (_s5, _s5), (_s5, _s6), (_s5, _s7), (_s5, _s8), (_s5, _s9), (_s5, _s10), (_s5, _s11), (_s5, _s12), (_s5, _s13), (_s5, _s14), (_s5, _s15), (_s5, _s16), (_s6, _s0), (_s6, _s1), (_s6, _s2), (_s6, _s3), (_s6, _s4), (_s6, _s5), (_s6, _s6), (_s6, _s7), (_s6, _s8), (_s6, _s9), (_s6, _s10), (_s6, _s11), (_s6, _s12), (_s6, _s13), (_s6, _s14), (_s6, _s15), (_s7, _s0), (_s7, _s1), (_s7, _s2), (_s7, _s3), (_s7, _s4), (_s7, _s5), (_s7, _s6), (_s7, _s7), (_s7, _s8), (_s7, _s9), (_s7, _s10), (_s7, _s11), (_s7, _s12), (_s7, _s13), (_s7, _s14), (_s8, _s0), (_s8, _s1), (_s8, _s2), (_s8, _s3), (_s8, _s4), (_s8, _s5), (_s8, _s6), (_s8, _s7), (_s8, _s8), (_s8, _s9), (_s8, _s10), (_s8, _s11), (_s8, _s12), (_s8, _s13), (_s9, _s0), (_s9, _s1), (_s9, _s2), (_s9, _s3), (_s9, _s4), (_s9, _s5), (_s9, _s6), (_s9, _s7), (_s9, _s8), (_s9, _s9), (_s9, _s10), (_s9, _s11), (_s9, _s12), (_s10, _s0), (_s10, _s1), (_s10, _s2), (_s10, _s3), (_s10, _s4), (_s10, _s5), (_s10, _s6), (_s10, _s7), (_s10, _s8), (_s10, _s9), (_s10, _s10), (_s10, _s11), (_s11, _s0), (_s11, _s1), (_s11, _s2), (_s11, _s3), (_s11, _s4), (_s11, _s5), (_s11, _s6), (_s11, _s7), (_s11, _s8), (_s11, _s9), (_s11, _s10), (_s11, _s11), (_s12, _s0), (_s12, _s1), (_s12, _s2), (_s12, _s3), (_s12, _s4), (_s12, _s5), (_s12, _s6), (_s12, _s7), (_s12, _s8), (_s12, _s9), (_s12, _s12), (_s13, _s0), (_s13, _s1), (_s13, _s2), (_s13, _s3), (_s13, _s4), (_s13, _s5), (_s13, _s6), (_s13, _s7), (_s13, _s8), (_s13, _s13), (_s14, _s0), (_s14, _s1), (_s14, _s2), (_s14, _s3), (_s14, _s4), (_s14, _s5), (_s14, _s6), (_s14, _s7), (_s14, _s14), (_s15, _s0), (_s15, _s1), (_s15, _s2), (_s15, _s3), (_s15, _s4), (_s15, _s5), (_s15, _s6), (_s15, _s15), (_s16, _s0), (_s16, _s1), (_s16, _s2), (_s16, _s3), (_s16, _s4), (_s16, _s5), (_s16, _s16), (_s17, _s0), (_s17, _s1), (_s17, _s2), (_s17, _s3), (_s17, _s4), (_s17, _s17), (_s18, _s0), (_s18, _s1), (_s18, _s2), (_s18, _s3), (_s18, _s18), (_s19, _s0), (_s19, _s1), (_s19, _s2), (_s19, _s19)} ++ } + debug _task_context => _2; +- let mut _0: (); ++ coroutine debug sync_int => _s1; ++ let mut _0: std::task::Poll<()>; + let _3: SyncInt; + let mut _6: AsyncInt; + let mut _7: AsyncInt; + let mut _9: AsyncInt; + let mut _10: AsyncInt; + let mut _12: AsyncInt; + let mut _13: SyncInt; + let mut _14: AsyncInt; + let mut _16: AsyncInt; + let mut _18: AsyncInt; + let mut _21: &AsyncInt; + let _22: &AsyncInt; + let mut _27: impl std::future::Future; + let mut _28: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; + let mut _29: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>; + let mut _30: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; + let mut _31: impl std::future::Future; + let mut _32: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; + let mut _33: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>; + let mut _34: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; + let mut _35: impl std::future::Future; + let mut _36: &mut AsyncReference<'_>; + let mut _37: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _38: &mut AsyncReference<'_>; + let mut _39: impl std::future::Future; + let mut _40: &mut AsyncInt; + let mut _41: std::pin::Pin<&mut AsyncInt>; + let mut _42: &mut AsyncInt; + let mut _43: impl std::future::Future; + let mut _44: &mut AsyncEnum; + let mut _45: std::pin::Pin<&mut AsyncEnum>; + let mut _46: &mut AsyncEnum; + let mut _47: impl std::future::Future; + let mut _48: &mut SyncThenAsync; + let mut _49: std::pin::Pin<&mut SyncThenAsync>; + let mut _50: &mut SyncThenAsync; + let mut _51: impl std::future::Future; + let mut _52: &mut AsyncStruct; + let mut _53: std::pin::Pin<&mut AsyncStruct>; + let mut _54: &mut AsyncStruct; + let mut _55: impl std::future::Future; + let mut _56: &mut [AsyncInt; 2]; + let mut _57: std::pin::Pin<&mut [AsyncInt; 2]>; + let mut _58: &mut [AsyncInt; 2]; + let mut _59: impl std::future::Future; + let mut _60: &mut AsyncInt; + let mut _61: std::pin::Pin<&mut AsyncInt>; + let mut _62: &mut AsyncInt; + let mut _63: impl std::future::Future; + let mut _64: &mut {async fn body of elaborate_drops()}; + let mut _65: std::pin::Pin<&mut {async fn body of elaborate_drops()}>; + let mut _66: &mut {async fn body of elaborate_drops()}; ++ let mut _67: std::task::Poll<()>; ++ let mut _68: &mut std::task::Context<'_>; ++ let mut _69: &mut impl std::future::Future; ++ let mut _70: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _71: isize; ++ let mut _72: &mut std::task::Context<'_>; ++ let mut _73: &mut impl std::future::Future; ++ let mut _74: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _75: isize; ++ let mut _76: std::task::Poll<()>; ++ let mut _77: &mut std::task::Context<'_>; ++ let mut _78: &mut impl std::future::Future; ++ let mut _79: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _80: isize; ++ let mut _81: &mut std::task::Context<'_>; ++ let mut _82: &mut impl std::future::Future; ++ let mut _83: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _84: isize; ++ let mut _85: std::task::Poll<()>; ++ let mut _86: &mut std::task::Context<'_>; ++ let mut _87: &mut impl std::future::Future; ++ let mut _88: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _89: isize; ++ let mut _90: &mut std::task::Context<'_>; ++ let mut _91: &mut impl std::future::Future; ++ let mut _92: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _93: isize; ++ let mut _94: std::task::Poll<()>; ++ let mut _95: &mut std::task::Context<'_>; ++ let mut _96: &mut impl std::future::Future; ++ let mut _97: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _98: isize; ++ let mut _99: &mut std::task::Context<'_>; ++ let mut _100: &mut impl std::future::Future; ++ let mut _101: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _102: isize; ++ let mut _103: std::task::Poll<()>; ++ let mut _104: &mut std::task::Context<'_>; ++ let mut _105: &mut impl std::future::Future; ++ let mut _106: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _107: isize; ++ let mut _108: &mut std::task::Context<'_>; ++ let mut _109: &mut impl std::future::Future; ++ let mut _110: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _111: isize; ++ let mut _112: std::task::Poll<()>; ++ let mut _113: &mut std::task::Context<'_>; ++ let mut _114: &mut impl std::future::Future; ++ let mut _115: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _116: isize; ++ let mut _117: &mut std::task::Context<'_>; ++ let mut _118: &mut impl std::future::Future; ++ let mut _119: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _120: isize; ++ let mut _121: std::task::Poll<()>; ++ let mut _122: &mut std::task::Context<'_>; ++ let mut _123: &mut impl std::future::Future; ++ let mut _124: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _125: isize; ++ let mut _126: &mut std::task::Context<'_>; ++ let mut _127: &mut impl std::future::Future; ++ let mut _128: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _129: isize; ++ let mut _130: std::task::Poll<()>; ++ let mut _131: &mut std::task::Context<'_>; ++ let mut _132: &mut impl std::future::Future; ++ let mut _133: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _134: isize; ++ let mut _135: &mut std::task::Context<'_>; ++ let mut _136: &mut impl std::future::Future; ++ let mut _137: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _138: isize; ++ let mut _139: std::task::Poll<()>; ++ let mut _140: &mut std::task::Context<'_>; ++ let mut _141: &mut impl std::future::Future; ++ let mut _142: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _143: isize; ++ let mut _144: &mut std::task::Context<'_>; ++ let mut _145: &mut impl std::future::Future; ++ let mut _146: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _147: isize; ++ let mut _148: (); ++ let mut _149: u32; ++ let mut _150: &mut {async fn body of elaborate_drops()}; + scope 1 { +- debug sync_int => _3; ++ debug sync_int => (((*_150) as variant#20).0: SyncInt); ++ coroutine debug async_int => _s2; + let _4: AsyncInt; + scope 2 { +- debug async_int => _4; ++ debug async_int => (((*_150) as variant#20).1: AsyncInt); ++ coroutine debug tuple => _s3; + let _5: [AsyncInt; 2]; + scope 3 { +- debug tuple => _5; ++ debug tuple => (((*_150) as variant#18).2: [AsyncInt; 2]); ++ coroutine debug async_struct => _s4; + let _8: AsyncStruct; + scope 4 { +- debug async_struct => _8; ++ debug async_struct => (((*_150) as variant#16).3: AsyncStruct); ++ coroutine debug async_struct_mix => _s5; + let _11: SyncThenAsync; + scope 5 { +- debug async_struct_mix => _11; ++ debug async_struct_mix => (((*_150) as variant#14).4: SyncThenAsync); ++ coroutine debug async_enum => _s6; + let _15: AsyncEnum; + scope 6 { +- debug async_enum => _15; ++ debug async_enum => (((*_150) as variant#12).5: AsyncEnum); + let _17: std::mem::ManuallyDrop; + scope 7 { + debug manually_drop_async_int => _17; ++ coroutine debug foo => _s7; + let _19: AsyncInt; + scope 8 { +- debug foo => _19; ++ debug foo => (((*_150) as variant#10).6: AsyncInt); ++ coroutine debug async_ref => _s8; + let _20: AsyncReference<'_>; + scope 9 { +- debug async_ref => _20; ++ debug async_ref => (((*_150) as variant#8).7: AsyncReference<'_>); + let _23: AsyncInt; + scope 10 { + debug foo => _23; ++ coroutine debug async_closure => _s9; + let _24: {closure@$DIR/async_drop.rs:72:25: 72:27}; + scope 11 { +- debug async_closure => _24; ++ debug async_closure => (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); + let _25: AsyncInt; + scope 12 { + debug foo => _25; ++ coroutine debug async_coroutine => _s10; + let _26: {async closure@$DIR/async_drop.rs:80:27: 80:35}; + scope 13 { +- debug async_coroutine => _26; ++ debug async_coroutine => (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); + } + } + } + } + } + } + } + } + } + } + } + } + } + + bb0: { +- StorageLive(_3); +- _3 = SyncInt(const 0_i32); +- StorageLive(_4); +- _4 = AsyncInt(const 0_i32); +- StorageLive(_5); +- StorageLive(_6); +- _6 = AsyncInt(const 1_i32); +- StorageLive(_7); +- _7 = AsyncInt(const 2_i32); +- _5 = [move _6, move _7]; +- goto -> bb1; ++ _150 = copy (_1.0: &mut {async fn body of elaborate_drops()}); ++ _149 = discriminant((*_150)); ++ switchInt(move _149) -> [0: bb137, 1: bb136, 2: bb135, 3: bb117, 4: bb118, 5: bb119, 6: bb120, 7: bb121, 8: bb122, 9: bb123, 10: bb124, 11: bb125, 12: bb126, 13: bb127, 14: bb128, 15: bb129, 16: bb130, 17: bb131, 18: bb132, 19: bb133, 20: bb134, otherwise: bb71]; + } + + bb1: { + StorageDead(_7); + goto -> bb2; + } + + bb2: { + StorageDead(_6); +- StorageLive(_8); ++ nop; + StorageLive(_9); + _9 = AsyncInt(const 5_i32); + StorageLive(_10); + _10 = AsyncInt(const 4_i32); +- _8 = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; ++ (((*_150) as variant#16).3: AsyncStruct) = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; + goto -> bb3; + } + + bb3: { + StorageDead(_10); + goto -> bb4; + } + + bb4: { + StorageDead(_9); +- StorageLive(_11); ++ nop; + StorageLive(_12); + _12 = AsyncInt(const 7_i32); + StorageLive(_13); + _13 = SyncInt(const 8_i32); + StorageLive(_14); + _14 = AsyncInt(const 9_i32); +- _11 = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; ++ (((*_150) as variant#14).4: SyncThenAsync) = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; + goto -> bb5; + } + + bb5: { + StorageDead(_14); + goto -> bb6; + } + + bb6: { + StorageDead(_13); + goto -> bb7; + } + + bb7: { + StorageDead(_12); +- StorageLive(_15); ++ nop; + StorageLive(_16); + _16 = AsyncInt(const 10_i32); +- _15 = AsyncEnum::A(move _16); ++ (((*_150) as variant#12).5: AsyncEnum) = AsyncEnum::A(move _16); + goto -> bb8; + } + + bb8: { + StorageDead(_16); + StorageLive(_17); + StorageLive(_18); + _18 = AsyncInt(const 11_i32); +- _17 = ManuallyDrop::::new(move _18) -> [return: bb9, unwind: bb42]; ++ _17 = ManuallyDrop::::new(move _18) -> [return: bb9, unwind: bb29]; + } + + bb9: { + StorageDead(_18); +- StorageLive(_19); +- _19 = AsyncInt(const 12_i32); +- StorageLive(_20); ++ nop; ++ (((*_150) as variant#10).6: AsyncInt) = AsyncInt(const 12_i32); ++ nop; + StorageLive(_21); + StorageLive(_22); +- _22 = &_19; ++ _22 = &(((*_150) as variant#10).6: AsyncInt); + _21 = &(*_22); +- _20 = AsyncReference::<'_> { foo: move _21 }; ++ (((*_150) as variant#8).7: AsyncReference<'_>) = AsyncReference::<'_> { foo: move _21 }; + StorageDead(_21); + StorageDead(_22); + StorageLive(_23); + _23 = AsyncInt(const 14_i32); +- StorageLive(_24); +- _24 = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; ++ nop; ++ (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}) = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; + StorageLive(_25); + _25 = AsyncInt(const 15_i32); +- StorageLive(_26); +- _26 = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; +- _0 = const (); +- _28 = &mut _26; +- _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb54, unwind: bb36]; ++ nop; ++ (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}) = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; ++ (((*_150) as variant#19).0: ()) = const (); ++ _28 = &mut (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb41, unwind: bb23]; + } + + bb10: { +- StorageDead(_26); ++ nop; + goto -> bb11; + } + + bb11: { + StorageDead(_25); +- _32 = &mut _24; +- _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb57, unwind: bb38]; ++ _32 = &mut (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); ++ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb44, unwind: bb25]; + } + + bb12: { +- StorageDead(_24); ++ nop; + goto -> bb13; + } + + bb13: { + StorageDead(_23); +- _36 = &mut _20; +- _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb60, unwind: bb40]; ++ _36 = &mut (((*_150) as variant#8).7: AsyncReference<'_>); ++ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb47, unwind: bb27]; + } + + bb14: { +- StorageDead(_20); +- _40 = &mut _19; +- _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb63, unwind: bb41]; ++ nop; ++ _40 = &mut (((*_150) as variant#10).6: AsyncInt); ++ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb50, unwind: bb28]; + } + + bb15: { +- StorageDead(_19); ++ nop; + StorageDead(_17); +- _44 = &mut _15; +- _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb66, unwind: bb45]; ++ _44 = &mut (((*_150) as variant#12).5: AsyncEnum); ++ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb53, unwind: bb32]; + } + + bb16: { +- StorageDead(_15); +- _48 = &mut _11; +- _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb69, unwind: bb46]; ++ nop; ++ _48 = &mut (((*_150) as variant#14).4: SyncThenAsync); ++ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb56, unwind: bb33]; + } + + bb17: { +- StorageDead(_11); +- _52 = &mut _8; +- _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb72, unwind: bb47]; ++ nop; ++ _52 = &mut (((*_150) as variant#16).3: AsyncStruct); ++ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb59, unwind: bb34]; + } + + bb18: { +- StorageDead(_8); +- _56 = &mut _5; +- _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb75, unwind: bb48]; ++ nop; ++ _56 = &mut (((*_150) as variant#18).2: [AsyncInt; 2]); ++ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb62, unwind: bb35]; + } + + bb19: { +- StorageDead(_5); +- _60 = &mut _4; +- _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb78, unwind: bb49]; ++ nop; ++ _60 = &mut (((*_150) as variant#20).1: AsyncInt); ++ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb65, unwind: bb36]; + } + + bb20: { +- StorageDead(_4); +- drop(_3) -> [return: bb21, unwind: bb50]; ++ nop; ++ drop((((*_150) as variant#20).0: SyncInt)) -> [return: bb21, unwind: bb37]; + } + + bb21: { +- StorageDead(_3); +- _64 = &mut _1; +- _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb81, unwind: bb51]; ++ nop; ++ _64 = &mut (*_150); ++ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb68, unwind: bb38]; + } + + bb22: { ++ _0 = Poll::<()>::Ready(move (((*_150) as variant#19).0: ())); ++ discriminant((*_150)) = 1; + return; + } + +- bb23: { +- StorageDead(_27); +- StorageDead(_26); ++ bb23 (cleanup): { ++ nop; ++ nop; + goto -> bb24; + } + +- bb24: { ++ bb24 (cleanup): { + StorageDead(_25); +- goto -> bb25; ++ drop((((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb25, unwind terminate(cleanup)]; + } + +- bb25: { +- StorageDead(_31); +- StorageDead(_24); ++ bb25 (cleanup): { ++ nop; ++ nop; + goto -> bb26; + } + +- bb26: { ++ bb26 (cleanup): { + StorageDead(_23); +- goto -> bb27; ++ drop((((*_150) as variant#8).7: AsyncReference<'_>)) -> [return: bb27, unwind terminate(cleanup)]; + } + +- bb27: { +- StorageDead(_35); +- StorageDead(_20); +- goto -> bb28; ++ bb27 (cleanup): { ++ nop; ++ nop; ++ drop((((*_150) as variant#10).6: AsyncInt)) -> [return: bb28, unwind terminate(cleanup)]; + } + +- bb28: { +- StorageDead(_39); +- StorageDead(_19); +- StorageDead(_17); +- goto -> bb29; ++ bb28 (cleanup): { ++ nop; ++ nop; ++ goto -> bb31; + } + +- bb29: { +- StorageDead(_43); +- StorageDead(_15); ++ bb29 (cleanup): { + goto -> bb30; + } + +- bb30: { +- StorageDead(_47); +- StorageDead(_11); ++ bb30 (cleanup): { ++ StorageDead(_18); + goto -> bb31; + } + +- bb31: { +- StorageDead(_51); +- StorageDead(_8); +- goto -> bb32; ++ bb31 (cleanup): { ++ StorageDead(_17); ++ drop((((*_150) as variant#12).5: AsyncEnum)) -> [return: bb32, unwind terminate(cleanup)]; + } + +- bb32: { +- StorageDead(_55); +- StorageDead(_5); +- goto -> bb33; ++ bb32 (cleanup): { ++ nop; ++ nop; ++ drop((((*_150) as variant#14).4: SyncThenAsync)) -> [return: bb33, unwind terminate(cleanup)]; + } + +- bb33: { +- StorageDead(_59); +- StorageDead(_4); +- goto -> bb34; ++ bb33 (cleanup): { ++ nop; ++ nop; ++ drop((((*_150) as variant#16).3: AsyncStruct)) -> [return: bb34, unwind terminate(cleanup)]; + } + +- bb34: { +- StorageDead(_3); +- goto -> bb35; ++ bb34 (cleanup): { ++ nop; ++ nop; ++ drop((((*_150) as variant#18).2: [AsyncInt; 2])) -> [return: bb35, unwind terminate(cleanup)]; + } + +- bb35: { +- StorageDead(_63); +- coroutine_drop; ++ bb35 (cleanup): { ++ nop; ++ nop; ++ drop((((*_150) as variant#20).1: AsyncInt)) -> [return: bb36, unwind terminate(cleanup)]; + } + + bb36 (cleanup): { +- StorageDead(_27); +- StorageDead(_26); +- goto -> bb37; ++ nop; ++ nop; ++ drop((((*_150) as variant#20).0: SyncInt)) -> [return: bb37, unwind terminate(cleanup)]; + } + + bb37 (cleanup): { +- StorageDead(_25); +- drop(_24) -> [return: bb38, unwind terminate(cleanup)]; ++ nop; ++ goto -> bb38; + } + + bb38 (cleanup): { +- StorageDead(_31); +- StorageDead(_24); +- goto -> bb39; ++ StorageDead(_63); ++ goto -> bb116; + } + +- bb39 (cleanup): { +- StorageDead(_23); +- drop(_20) -> [return: bb40, unwind terminate(cleanup)]; ++ bb39: { ++ nop; ++ goto -> bb10; + } + +- bb40 (cleanup): { +- StorageDead(_35); +- StorageDead(_20); +- drop(_19) -> [return: bb41, unwind terminate(cleanup)]; ++ bb40: { ++ _68 = move _2; ++ goto -> bb70; + } + +- bb41 (cleanup): { +- StorageDead(_39); +- StorageDead(_19); +- goto -> bb44; ++ bb41: { ++ _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ nop; ++ (((*_150) as variant#4).10: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb40, unwind: bb23]; + } + +- bb42 (cleanup): { +- goto -> bb43; ++ bb42: { ++ nop; ++ goto -> bb12; + } + +- bb43 (cleanup): { +- StorageDead(_18); +- goto -> bb44; ++ bb43: { ++ _77 = move _2; ++ goto -> bb76; + } + +- bb44 (cleanup): { +- StorageDead(_17); +- drop(_15) -> [return: bb45, unwind terminate(cleanup)]; ++ bb44: { ++ _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); ++ nop; ++ (((*_150) as variant#6).9: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb43, unwind: bb25]; + } + +- bb45 (cleanup): { +- StorageDead(_43); +- StorageDead(_15); +- drop(_11) -> [return: bb46, unwind terminate(cleanup)]; ++ bb45: { ++ nop; ++ goto -> bb14; + } + +- bb46 (cleanup): { +- StorageDead(_47); +- StorageDead(_11); +- drop(_8) -> [return: bb47, unwind terminate(cleanup)]; ++ bb46: { ++ _86 = move _2; ++ goto -> bb81; + } + +- bb47 (cleanup): { +- StorageDead(_51); +- StorageDead(_8); +- drop(_5) -> [return: bb48, unwind terminate(cleanup)]; ++ bb47: { ++ _38 = copy (_37.0: &mut AsyncReference<'_>); ++ nop; ++ (((*_150) as variant#8).8: impl std::future::Future) = async_drop_in_place::>(move _38) -> [return: bb46, unwind: bb27]; + } + +- bb48 (cleanup): { +- StorageDead(_55); +- StorageDead(_5); +- drop(_4) -> [return: bb49, unwind terminate(cleanup)]; ++ bb48: { ++ nop; ++ goto -> bb15; + } + +- bb49 (cleanup): { +- StorageDead(_59); +- StorageDead(_4); +- drop(_3) -> [return: bb50, unwind terminate(cleanup)]; ++ bb49: { ++ _95 = move _2; ++ goto -> bb86; + } + +- bb50 (cleanup): { +- StorageDead(_3); +- drop(_1) -> [return: bb51, unwind terminate(cleanup)]; ++ bb50: { ++ _42 = copy (_41.0: &mut AsyncInt); ++ nop; ++ (((*_150) as variant#10).7: impl std::future::Future) = async_drop_in_place::(move _42) -> [return: bb49, unwind: bb28]; + } + +- bb51 (cleanup): { +- StorageDead(_63); +- resume; ++ bb51: { ++ nop; ++ goto -> bb16; + } + + bb52: { +- StorageDead(_27); +- goto -> bb10; ++ _104 = move _2; ++ goto -> bb91; + } + + bb53: { +- async drop(_26; poll=_27) -> [return: bb52, unwind: bb36, drop: bb23]; ++ _46 = copy (_45.0: &mut AsyncEnum); ++ nop; ++ (((*_150) as variant#12).6: impl std::future::Future) = async_drop_in_place::(move _46) -> [return: bb52, unwind: bb32]; + } + + bb54: { +- _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); +- StorageLive(_27); +- _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb53, unwind: bb36]; ++ nop; ++ goto -> bb17; + } + + bb55: { +- StorageDead(_31); +- goto -> bb12; ++ _113 = move _2; ++ goto -> bb96; + } + + bb56: { +- async drop(_24; poll=_31) -> [return: bb55, unwind: bb38, drop: bb25]; ++ _50 = copy (_49.0: &mut SyncThenAsync); ++ nop; ++ (((*_150) as variant#14).5: impl std::future::Future) = async_drop_in_place::(move _50) -> [return: bb55, unwind: bb33]; + } + + bb57: { +- _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); +- StorageLive(_31); +- _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb56, unwind: bb38]; ++ nop; ++ goto -> bb18; + } + + bb58: { +- StorageDead(_35); +- goto -> bb14; ++ _122 = move _2; ++ goto -> bb101; + } + + bb59: { +- async drop(_20; poll=_35) -> [return: bb58, unwind: bb40, drop: bb27]; ++ _54 = copy (_53.0: &mut AsyncStruct); ++ nop; ++ (((*_150) as variant#16).4: impl std::future::Future) = async_drop_in_place::(move _54) -> [return: bb58, unwind: bb34]; + } + + bb60: { +- _38 = copy (_37.0: &mut AsyncReference<'_>); +- StorageLive(_35); +- _35 = async_drop_in_place::>(move _38) -> [return: bb59, unwind: bb40]; ++ nop; ++ goto -> bb19; + } + + bb61: { +- StorageDead(_39); +- goto -> bb15; ++ _131 = move _2; ++ goto -> bb106; + } + + bb62: { +- async drop(_19; poll=_39) -> [return: bb61, unwind: bb41, drop: bb28]; ++ _58 = copy (_57.0: &mut [AsyncInt; 2]); ++ nop; ++ (((*_150) as variant#18).3: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb61, unwind: bb35]; + } + + bb63: { +- _42 = copy (_41.0: &mut AsyncInt); +- StorageLive(_39); +- _39 = async_drop_in_place::(move _42) -> [return: bb62, unwind: bb41]; ++ nop; ++ goto -> bb20; + } + + bb64: { +- StorageDead(_43); +- goto -> bb16; ++ _140 = move _2; ++ goto -> bb111; + } + + bb65: { +- async drop(_15; poll=_43) -> [return: bb64, unwind: bb45, drop: bb29]; ++ _62 = copy (_61.0: &mut AsyncInt); ++ nop; ++ (((*_150) as variant#20).2: impl std::future::Future) = async_drop_in_place::(move _62) -> [return: bb64, unwind: bb36]; + } + + bb66: { +- _46 = copy (_45.0: &mut AsyncEnum); +- StorageLive(_43); +- _43 = async_drop_in_place::(move _46) -> [return: bb65, unwind: bb45]; ++ StorageDead(_63); ++ goto -> bb22; + } + + bb67: { +- StorageDead(_47); +- goto -> bb17; ++ goto -> bb115; + } + + bb68: { +- async drop(_11; poll=_47) -> [return: bb67, unwind: bb46, drop: bb30]; ++ _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); ++ StorageLive(_63); ++ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb67, unwind: bb38]; + } + + bb69: { +- _50 = copy (_49.0: &mut SyncThenAsync); +- StorageLive(_47); +- _47 = async_drop_in_place::(move _50) -> [return: bb68, unwind: bb46]; ++ _0 = Poll::<()>::Pending; ++ StorageDead(_17); ++ StorageDead(_23); ++ StorageDead(_25); ++ discriminant((*_150)) = 3; ++ return; + } + + bb70: { +- StorageDead(_51); +- goto -> bb18; ++ StorageLive(_70); ++ _69 = &mut (((*_150) as variant#4).10: impl std::future::Future); ++ _70 = Pin::<&mut impl Future>::new_unchecked(move _69) -> [return: bb73, unwind: bb116]; + } + + bb71: { +- async drop(_8; poll=_51) -> [return: bb70, unwind: bb47, drop: bb31]; ++ unreachable; + } + + bb72: { +- _54 = copy (_53.0: &mut AsyncStruct); +- StorageLive(_51); +- _51 = async_drop_in_place::(move _54) -> [return: bb71, unwind: bb47]; ++ StorageDead(_70); ++ _71 = discriminant(_67); ++ switchInt(move _71) -> [0: bb39, 1: bb69, otherwise: bb71]; + } + + bb73: { +- StorageDead(_55); +- goto -> bb19; ++ _67 = as Future>::poll(move _70, move _68) -> [return: bb72, unwind: bb23]; + } + + bb74: { +- async drop(_5; poll=_55) -> [return: bb73, unwind: bb48, drop: bb32]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb74, unwind: bb116]; + } + + bb75: { +- _58 = copy (_57.0: &mut [AsyncInt; 2]); +- StorageLive(_55); +- _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb74, unwind: bb48]; ++ _0 = Poll::<()>::Pending; ++ StorageDead(_17); ++ StorageDead(_23); ++ discriminant((*_150)) = 5; ++ return; + } + + bb76: { +- StorageDead(_59); +- goto -> bb20; ++ StorageLive(_79); ++ _78 = &mut (((*_150) as variant#6).9: impl std::future::Future); ++ _79 = Pin::<&mut impl Future>::new_unchecked(move _78) -> [return: bb78, unwind: bb116]; + } + + bb77: { +- async drop(_4; poll=_59) -> [return: bb76, unwind: bb49, drop: bb33]; ++ StorageDead(_79); ++ _80 = discriminant(_76); ++ switchInt(move _80) -> [0: bb42, 1: bb75, otherwise: bb71]; + } + + bb78: { +- _62 = copy (_61.0: &mut AsyncInt); +- StorageLive(_59); +- _59 = async_drop_in_place::(move _62) -> [return: bb77, unwind: bb49]; ++ _76 = as Future>::poll(move _79, move _77) -> [return: bb77, unwind: bb25]; + } + + bb79: { +- StorageDead(_63); +- goto -> bb22; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb79, unwind: bb116]; + } + + bb80: { +- async drop(_1; poll=_63) -> [return: bb79, unwind: bb51, drop: bb35]; ++ _0 = Poll::<()>::Pending; ++ StorageDead(_17); ++ discriminant((*_150)) = 7; ++ return; + } + + bb81: { +- _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); +- StorageLive(_63); +- _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb80, unwind: bb51]; ++ StorageLive(_88); ++ _87 = &mut (((*_150) as variant#8).8: impl std::future::Future); ++ _88 = Pin::<&mut impl Future>::new_unchecked(move _87) -> [return: bb83, unwind: bb116]; ++ } ++ ++ bb82: { ++ StorageDead(_88); ++ _89 = discriminant(_85); ++ switchInt(move _89) -> [0: bb45, 1: bb80, otherwise: bb71]; ++ } ++ ++ bb83: { ++ _85 = as Future>::poll(move _88, move _86) -> [return: bb82, unwind: bb27]; ++ } ++ ++ bb84: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb84, unwind: bb116]; ++ } ++ ++ bb85: { ++ _0 = Poll::<()>::Pending; ++ StorageDead(_17); ++ discriminant((*_150)) = 9; ++ return; ++ } ++ ++ bb86: { ++ StorageLive(_97); ++ _96 = &mut (((*_150) as variant#10).7: impl std::future::Future); ++ _97 = Pin::<&mut impl Future>::new_unchecked(move _96) -> [return: bb88, unwind: bb116]; ++ } ++ ++ bb87: { ++ StorageDead(_97); ++ _98 = discriminant(_94); ++ switchInt(move _98) -> [0: bb48, 1: bb85, otherwise: bb71]; ++ } ++ ++ bb88: { ++ _94 = as Future>::poll(move _97, move _95) -> [return: bb87, unwind: bb28]; ++ } ++ ++ bb89: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb89, unwind: bb116]; ++ } ++ ++ bb90: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_150)) = 11; ++ return; ++ } ++ ++ bb91: { ++ StorageLive(_106); ++ _105 = &mut (((*_150) as variant#12).6: impl std::future::Future); ++ _106 = Pin::<&mut impl Future>::new_unchecked(move _105) -> [return: bb93, unwind: bb116]; ++ } ++ ++ bb92: { ++ StorageDead(_106); ++ _107 = discriminant(_103); ++ switchInt(move _107) -> [0: bb51, 1: bb90, otherwise: bb71]; ++ } ++ ++ bb93: { ++ _103 = as Future>::poll(move _106, move _104) -> [return: bb92, unwind: bb32]; ++ } ++ ++ bb94: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb94, unwind: bb116]; ++ } ++ ++ bb95: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_150)) = 13; ++ return; ++ } ++ ++ bb96: { ++ StorageLive(_115); ++ _114 = &mut (((*_150) as variant#14).5: impl std::future::Future); ++ _115 = Pin::<&mut impl Future>::new_unchecked(move _114) -> [return: bb98, unwind: bb116]; ++ } ++ ++ bb97: { ++ StorageDead(_115); ++ _116 = discriminant(_112); ++ switchInt(move _116) -> [0: bb54, 1: bb95, otherwise: bb71]; ++ } ++ ++ bb98: { ++ _112 = as Future>::poll(move _115, move _113) -> [return: bb97, unwind: bb33]; ++ } ++ ++ bb99: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb99, unwind: bb116]; ++ } ++ ++ bb100: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_150)) = 15; ++ return; ++ } ++ ++ bb101: { ++ StorageLive(_124); ++ _123 = &mut (((*_150) as variant#16).4: impl std::future::Future); ++ _124 = Pin::<&mut impl Future>::new_unchecked(move _123) -> [return: bb103, unwind: bb116]; ++ } ++ ++ bb102: { ++ StorageDead(_124); ++ _125 = discriminant(_121); ++ switchInt(move _125) -> [0: bb57, 1: bb100, otherwise: bb71]; ++ } ++ ++ bb103: { ++ _121 = as Future>::poll(move _124, move _122) -> [return: bb102, unwind: bb34]; ++ } ++ ++ bb104: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb104, unwind: bb116]; ++ } ++ ++ bb105: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_150)) = 17; ++ return; ++ } ++ ++ bb106: { ++ StorageLive(_133); ++ _132 = &mut (((*_150) as variant#18).3: impl std::future::Future); ++ _133 = Pin::<&mut impl Future>::new_unchecked(move _132) -> [return: bb108, unwind: bb116]; ++ } ++ ++ bb107: { ++ StorageDead(_133); ++ _134 = discriminant(_130); ++ switchInt(move _134) -> [0: bb60, 1: bb105, otherwise: bb71]; ++ } ++ ++ bb108: { ++ _130 = as Future>::poll(move _133, move _131) -> [return: bb107, unwind: bb35]; ++ } ++ ++ bb109: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb109, unwind: bb116]; ++ } ++ ++ bb110: { ++ _0 = Poll::<()>::Pending; ++ discriminant((*_150)) = 19; ++ return; ++ } ++ ++ bb111: { ++ StorageLive(_142); ++ _141 = &mut (((*_150) as variant#20).2: impl std::future::Future); ++ _142 = Pin::<&mut impl Future>::new_unchecked(move _141) -> [return: bb113, unwind: bb116]; ++ } ++ ++ bb112: { ++ StorageDead(_142); ++ _143 = discriminant(_139); ++ switchInt(move _143) -> [0: bb63, 1: bb110, otherwise: bb71]; ++ } ++ ++ bb113: { ++ _139 = as Future>::poll(move _142, move _140) -> [return: bb112, unwind: bb36]; ++ } ++ ++ bb114: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb114, unwind: bb116]; ++ } ++ ++ bb115: { ++ goto -> bb66; ++ } ++ ++ bb116 (cleanup): { ++ discriminant((*_150)) = 2; ++ resume; ++ } ++ ++ bb117: { ++ StorageLive(_17); ++ StorageLive(_23); ++ StorageLive(_25); ++ _68 = move _2; ++ goto -> bb70; ++ } ++ ++ bb118: { ++ StorageLive(_17); ++ StorageLive(_23); ++ StorageLive(_25); ++ _72 = move _2; ++ goto -> bb74; ++ } ++ ++ bb119: { ++ StorageLive(_17); ++ StorageLive(_23); ++ _77 = move _2; ++ goto -> bb76; ++ } ++ ++ bb120: { ++ StorageLive(_17); ++ StorageLive(_23); ++ _81 = move _2; ++ goto -> bb79; ++ } ++ ++ bb121: { ++ StorageLive(_17); ++ _86 = move _2; ++ goto -> bb81; ++ } ++ ++ bb122: { ++ StorageLive(_17); ++ _90 = move _2; ++ goto -> bb84; ++ } ++ ++ bb123: { ++ StorageLive(_17); ++ _95 = move _2; ++ goto -> bb86; ++ } ++ ++ bb124: { ++ StorageLive(_17); ++ _99 = move _2; ++ goto -> bb89; ++ } ++ ++ bb125: { ++ _104 = move _2; ++ goto -> bb91; ++ } ++ ++ bb126: { ++ _108 = move _2; ++ goto -> bb94; ++ } ++ ++ bb127: { ++ _113 = move _2; ++ goto -> bb96; ++ } ++ ++ bb128: { ++ _117 = move _2; ++ goto -> bb99; ++ } ++ ++ bb129: { ++ _122 = move _2; ++ goto -> bb101; ++ } ++ ++ bb130: { ++ _126 = move _2; ++ goto -> bb104; ++ } ++ ++ bb131: { ++ _131 = move _2; ++ goto -> bb106; ++ } ++ ++ bb132: { ++ _135 = move _2; ++ goto -> bb109; ++ } ++ ++ bb133: { ++ _140 = move _2; ++ goto -> bb111; ++ } ++ ++ bb134: { ++ _144 = move _2; ++ goto -> bb114; ++ } ++ ++ bb135: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb135, unwind continue]; ++ } ++ ++ bb136: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb136, unwind continue]; ++ } ++ ++ bb137: { ++ nop; ++ (((*_150) as variant#20).0: SyncInt) = SyncInt(const 0_i32); ++ nop; ++ (((*_150) as variant#20).1: AsyncInt) = AsyncInt(const 0_i32); ++ nop; ++ StorageLive(_6); ++ _6 = AsyncInt(const 1_i32); ++ StorageLive(_7); ++ _7 = AsyncInt(const 2_i32); ++ (((*_150) as variant#18).2: [AsyncInt; 2]) = [move _6, move _7]; ++ goto -> bb1; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.rs b/tests/mir-opt/coroutine/async_drop.rs new file mode 100644 index 0000000000000..7da1514f042e6 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.rs @@ -0,0 +1,260 @@ +//@ skip-filecheck +//@ compile-flags: -Zmir-opt-level=0 -Zvalidate-mir=no +//@ needs-unwind +//@ edition: 2024 + +// WARNING: If you would ever want to modify this test, +// please consider modifying rustc's async drop test at +// `tests/ui/async-await/async-drop/async-drop-initial.rs`. + +#![feature(async_drop, impl_trait_in_assoc_type)] +#![allow(incomplete_features, dead_code, unused_variables)] + +// FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests +use core::future::{AsyncDrop, Future, async_drop_in_place}; +use core::hint::black_box; +use core::mem::{self, ManuallyDrop}; +use core::pin::{Pin, pin}; +use core::task::{Context, Poll, Waker}; + +async fn test_async_drop(x: T) { + let mut x = mem::MaybeUninit::new(x); + let dtor = pin!(unsafe { async_drop_in_place(&mut *x.as_mut_ptr()) }); + test_idempotency(dtor).await; +} + +fn test_idempotency(mut x: Pin<&mut T>) -> impl Future + '_ +where + T: Future, +{ + core::future::poll_fn(move |cx| { + assert_eq!(x.as_mut().poll(cx), Poll::Ready(())); + assert_eq!(x.as_mut().poll(cx), Poll::Ready(())); + Poll::Ready(()) + }) +} + +// EMIT_MIR async_drop.simple-{closure#0}.ElaborateDrops.diff +// EMIT_MIR async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir +// EMIT_MIR async_drop.simple-{closure#0}.StateTransform.diff +// EMIT_MIR async_drop.simple-{closure#0}.coroutine_drop_async.0.mir +async fn simple() { + let sync_int = SyncInt(0); + let async_int = AsyncInt(0); +} + +// EMIT_MIR async_drop.double-{closure#0}.ElaborateDrops.diff +// EMIT_MIR async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir +// EMIT_MIR async_drop.double-{closure#0}.StateTransform.diff +// EMIT_MIR async_drop.double-{closure#0}.coroutine_drop_async.0.mir +async fn double() { + let sync_int = SyncInt(0); + let async_int = AsyncInt(0); + let async_int_again = AsyncInt(0); +} + +// EMIT_MIR async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff +// EMIT_MIR async_drop.elaborate_drops-{closure#0}.StateTransform.diff +async fn elaborate_drops() { + let sync_int = SyncInt(0); + let async_int = AsyncInt(0); + let tuple = [AsyncInt(1), AsyncInt(2)]; + + let async_struct = AsyncStruct { b: AsyncInt(5), a: AsyncInt(4), i: 3 }; + let async_struct_mix = SyncThenAsync { i: 6, a: AsyncInt(7), b: SyncInt(8), c: AsyncInt(9) }; + let async_enum = AsyncEnum::A(AsyncInt(10)); + + let manually_drop_async_int = ManuallyDrop::new(AsyncInt(11)); + let foo = AsyncInt(12); + let async_ref = AsyncReference { foo: &foo }; + + let foo = AsyncInt(14); + let async_closure = || { + black_box(foo); + let foo = AsyncInt(13); + foo + }; + + // We test dropping the coroutine, not running it. + let foo = AsyncInt(15); + let async_coroutine = async || { + black_box(foo); + let foo = AsyncInt(16); + // Await point there, but this is async closure so it's fine + black_box(core::future::ready(())).await; + foo + }; +} + +fn main() { + let waker = Waker::noop(); + let mut cx = Context::from_waker(&waker); + + let i = 13; + let fut = pin!(async { + elaborate_drops().await; + + test_async_drop(Int(0)).await; + test_async_drop(AsyncInt(0)).await; + test_async_drop([AsyncInt(1), AsyncInt(2)]).await; + test_async_drop((AsyncInt(3), AsyncInt(4))).await; + test_async_drop(5).await; + let j = 42; + test_async_drop(&i).await; + test_async_drop(&j).await; + test_async_drop(AsyncStruct { b: AsyncInt(8), a: AsyncInt(7), i: 6 }).await; + test_async_drop(ManuallyDrop::new(AsyncInt(9))).await; + + let foo = AsyncInt(10); + test_async_drop(AsyncReference { foo: &foo }).await; + + let foo = AsyncInt(11); + test_async_drop(|| { + black_box(foo); + let foo = AsyncInt(10); + foo + }) + .await; + + test_async_drop(AsyncEnum::A(AsyncInt(12))).await; + test_async_drop(AsyncEnum::B(SyncInt(13))).await; + + test_async_drop(SyncInt(14)).await; + test_async_drop(SyncThenAsync { i: 15, a: AsyncInt(16), b: SyncInt(17), c: AsyncInt(18) }) + .await; + + let mut ptr19 = mem::MaybeUninit::new(AsyncInt(19)); + let async_drop_fut = pin!(unsafe { async_drop_in_place(&mut *ptr19.as_mut_ptr()) }); + test_idempotency(async_drop_fut).await; + + let foo = AsyncInt(20); + test_async_drop(async || { + black_box(foo); + let foo = AsyncInt(19); + // Await point there, but this is async closure so it's fine + black_box(core::future::ready(())).await; + foo + }) + .await; + }); + let res = fut.poll(&mut cx); + assert_eq!(res, Poll::Ready(())); +} + +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff +struct AsyncInt(i32); + +impl Drop for AsyncInt { + fn drop(&mut self) { + println!("AsyncInt::drop: {}", self.0); + } +} +impl AsyncDrop for AsyncInt { + async fn drop(self: Pin<&mut Self>) { + println!("AsyncInt::async_drop: {}", self.0); + } +} + +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff +struct SyncInt(i32); + +impl Drop for SyncInt { + fn drop(&mut self) { + println!("SyncInt::drop: {}", self.0); + } +} + +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff +struct SyncThenAsync { + i: i32, + a: AsyncInt, + b: SyncInt, + c: AsyncInt, +} + +impl Drop for SyncThenAsync { + fn drop(&mut self) { + println!("SyncThenAsync::drop: {}", self.i); + } +} + +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff +struct AsyncReference<'a> { + foo: &'a AsyncInt, +} + +impl Drop for AsyncReference<'_> { + fn drop(&mut self) { + println!("AsyncReference::drop: {}", self.foo.0); + } +} +impl AsyncDrop for AsyncReference<'_> { + async fn drop(self: Pin<&mut Self>) { + println!("AsyncReference::async_drop: {}", self.foo.0); + } +} + +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.Int.MentionedItems.after.mir +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.Int.StateTransform.diff +struct Int(i32); + +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff +struct AsyncStruct { + i: i32, + a: AsyncInt, + b: AsyncInt, +} + +impl Drop for AsyncStruct { + fn drop(&mut self) { + println!("AsyncStruct::drop: {}", self.i); + } +} +impl AsyncDrop for AsyncStruct { + async fn drop(self: Pin<&mut Self>) { + println!("AsyncStruct::async_drop: {}", self.i); + } +} + +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir +// EMIT_MIR core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff +enum AsyncEnum { + A(AsyncInt), + B(SyncInt), +} + +impl Drop for AsyncEnum { + fn drop(&mut self) { + let new_self = match self { + AsyncEnum::A(foo) => { + println!("AsyncEnum(A)::drop: {}", foo.0); + AsyncEnum::B(SyncInt(foo.0)) + } + AsyncEnum::B(foo) => { + println!("AsyncEnum(B)::drop: {}", foo.0); + AsyncEnum::A(AsyncInt(foo.0)) + } + }; + mem::forget(mem::replace(&mut *self, new_self)); + } +} +impl AsyncDrop for AsyncEnum { + async fn drop(mut self: Pin<&mut Self>) { + let new_self = match &*self { + AsyncEnum::A(foo) => { + println!("AsyncEnum(A)::async_drop: {}", foo.0); + AsyncEnum::B(SyncInt(foo.0)) + } + AsyncEnum::B(foo) => { + println!("AsyncEnum(B)::async_drop: {}", foo.0); + AsyncEnum::A(AsyncInt(foo.0)) + } + }; + mem::forget(mem::replace(&mut *self, new_self)); + } +} diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff new file mode 100644 index 0000000000000..ec9c6dbc981e3 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff @@ -0,0 +1,123 @@ +- // MIR for `simple::{closure#0}` before ElaborateDrops ++ // MIR for `simple::{closure#0}` after ElaborateDrops + + fn simple::{closure#0}(_1: {async fn body of simple()}, _2: std::future::ResumeTy) -> () + yields () + { + debug _task_context => _2; + let mut _0: (); + let _3: SyncInt; ++ let mut _5: impl std::future::Future; ++ let mut _6: &mut AsyncInt; ++ let mut _7: std::pin::Pin<&mut AsyncInt>; ++ let mut _8: &mut AsyncInt; ++ let mut _9: impl std::future::Future; ++ let mut _10: &mut {async fn body of simple()}; ++ let mut _11: std::pin::Pin<&mut {async fn body of simple()}>; ++ let mut _12: &mut {async fn body of simple()}; + scope 1 { + debug sync_int => _3; + let _4: AsyncInt; + scope 2 { + debug async_int => _4; + } + } + + bb0: { + StorageLive(_3); + _3 = SyncInt(const 0_i32); + StorageLive(_4); + _4 = AsyncInt(const 0_i32); + _0 = const (); +- drop(_4) -> [return: bb1, unwind: bb7, drop: bb4]; ++ _6 = &mut _4; ++ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb13, unwind: bb7]; + } + + bb1: { + StorageDead(_4); + drop(_3) -> [return: bb2, unwind: bb8]; + } + + bb2: { + StorageDead(_3); +- drop(_1) -> [return: bb3, drop: bb6, unwind continue]; ++ _10 = &mut _1; ++ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb16, unwind: bb9]; + } + + bb3: { + return; + } + + bb4: { ++ StorageDead(_5); + StorageDead(_4); +- drop(_3) -> [return: bb5, unwind: bb10]; ++ goto -> bb5; + } + + bb5: { + StorageDead(_3); +- drop(_1) -> [return: bb6, unwind continue]; ++ goto -> bb6; + } + + bb6: { ++ StorageDead(_9); + coroutine_drop; + } + + bb7 (cleanup): { ++ StorageDead(_5); + StorageDead(_4); + drop(_3) -> [return: bb8, unwind terminate(cleanup)]; + } + + bb8 (cleanup): { + StorageDead(_3); + drop(_1) -> [return: bb9, unwind terminate(cleanup)]; + } + + bb9 (cleanup): { ++ StorageDead(_9); + resume; + } + + bb10 (cleanup): { + StorageDead(_3); +- drop(_1) -> [return: bb9, unwind terminate(cleanup)]; ++ goto -> bb9; ++ } ++ ++ bb11: { ++ StorageDead(_5); ++ goto -> bb1; ++ } ++ ++ bb12: { ++ async drop(_4; poll=_5) -> [return: bb11, unwind: bb7, drop: bb4]; ++ } ++ ++ bb13: { ++ _8 = copy (_7.0: &mut AsyncInt); ++ StorageLive(_5); ++ _5 = async_drop_in_place::(move _8) -> [return: bb12, unwind: bb7]; ++ } ++ ++ bb14: { ++ StorageDead(_9); ++ goto -> bb3; ++ } ++ ++ bb15: { ++ async drop(_1; poll=_9) -> [return: bb14, unwind: bb9, drop: bb6]; ++ } ++ ++ bb16: { ++ _12 = copy (_11.0: &mut {async fn body of simple()}); ++ StorageLive(_9); ++ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb15, unwind: bb9]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..72b1f40d7055b --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff @@ -0,0 +1,237 @@ +- // MIR for `simple::{closure#0}` before StateTransform ++ // MIR for `simple::{closure#0}` after StateTransform + +- fn simple::{closure#0}(_1: {async fn body of simple()}, _2: std::future::ResumeTy) -> () +- yields () +- { ++ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: (); ++ field _s1: SyncInt; ++ field _s2: AsyncInt; ++ field _s3: impl Future; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1, _s2, _s3], ++ Suspend1 (4): [_s1, _s2, _s3], ++ } ++ storage_conflicts = BitMatrix(4x4) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3)} ++ } + debug _task_context => _2; +- let mut _0: (); ++ coroutine debug sync_int => _s1; ++ let mut _0: std::task::Poll<()>; + let _3: SyncInt; + let mut _5: impl std::future::Future; + let mut _6: &mut AsyncInt; + let mut _7: std::pin::Pin<&mut AsyncInt>; + let mut _8: &mut AsyncInt; + let mut _9: impl std::future::Future; + let mut _10: &mut {async fn body of simple()}; + let mut _11: std::pin::Pin<&mut {async fn body of simple()}>; + let mut _12: &mut {async fn body of simple()}; ++ let mut _13: std::task::Poll<()>; ++ let mut _14: &mut std::task::Context<'_>; ++ let mut _15: &mut impl std::future::Future; ++ let mut _16: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _17: isize; ++ let mut _18: &mut std::task::Context<'_>; ++ let mut _19: &mut impl std::future::Future; ++ let mut _20: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _21: isize; ++ let mut _22: (); ++ let mut _23: u32; ++ let mut _24: &mut {async fn body of simple()}; + scope 1 { +- debug sync_int => _3; ++ debug sync_int => (((*_24) as variant#4).0: SyncInt); ++ coroutine debug async_int => _s2; + let _4: AsyncInt; + scope 2 { +- debug async_int => _4; ++ debug async_int => (((*_24) as variant#4).1: AsyncInt); + } + } + + bb0: { +- StorageLive(_3); +- _3 = SyncInt(const 0_i32); +- StorageLive(_4); +- _4 = AsyncInt(const 0_i32); +- _0 = const (); +- _6 = &mut _4; +- _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb12, unwind: bb7]; ++ _24 = copy (_1.0: &mut {async fn body of simple()}); ++ _23 = discriminant((*_24)); ++ switchInt(move _23) -> [0: bb25, 1: bb24, 2: bb23, 3: bb21, 4: bb22, otherwise: bb15]; + } + + bb1: { +- StorageDead(_4); +- drop(_3) -> [return: bb2, unwind: bb8]; ++ nop; ++ drop((((*_24) as variant#4).0: SyncInt)) -> [return: bb2, unwind: bb5]; + } + + bb2: { +- StorageDead(_3); +- _10 = &mut _1; +- _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb15, unwind: bb9]; ++ nop; ++ _10 = &mut (*_24); ++ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb12, unwind: bb6]; + } + + bb3: { ++ _0 = Poll::<()>::Ready(move (((*_24) as variant#3).0: ())); ++ discriminant((*_24)) = 1; + return; + } + +- bb4: { +- StorageDead(_5); +- StorageDead(_4); +- goto -> bb5; ++ bb4 (cleanup): { ++ nop; ++ nop; ++ drop((((*_24) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; + } + +- bb5: { +- StorageDead(_3); ++ bb5 (cleanup): { ++ nop; + goto -> bb6; + } + +- bb6: { ++ bb6 (cleanup): { + StorageDead(_9); +- coroutine_drop; ++ goto -> bb20; + } + +- bb7 (cleanup): { +- StorageDead(_5); +- StorageDead(_4); +- drop(_3) -> [return: bb8, unwind terminate(cleanup)]; ++ bb7: { ++ nop; ++ goto -> bb1; + } + +- bb8 (cleanup): { +- StorageDead(_3); +- drop(_1) -> [return: bb9, unwind terminate(cleanup)]; ++ bb8: { ++ _14 = move _2; ++ goto -> bb14; + } + +- bb9 (cleanup): { +- StorageDead(_9); +- resume; ++ bb9: { ++ _8 = copy (_7.0: &mut AsyncInt); ++ nop; ++ (((*_24) as variant#4).2: impl std::future::Future) = async_drop_in_place::(move _8) -> [return: bb8, unwind: bb4]; + } + + bb10: { +- StorageDead(_5); +- goto -> bb1; ++ StorageDead(_9); ++ goto -> bb3; + } + + bb11: { +- async drop(_4; poll=_5) -> [return: bb10, unwind: bb7, drop: bb4]; ++ goto -> bb19; + } + + bb12: { +- _8 = copy (_7.0: &mut AsyncInt); +- StorageLive(_5); +- _5 = async_drop_in_place::(move _8) -> [return: bb11, unwind: bb7]; ++ _12 = copy (_11.0: &mut {async fn body of simple()}); ++ StorageLive(_9); ++ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb11, unwind: bb6]; + } + + bb13: { +- StorageDead(_9); +- goto -> bb3; ++ _0 = Poll::<()>::Pending; ++ discriminant((*_24)) = 3; ++ return; + } + + bb14: { +- async drop(_1; poll=_9) -> [return: bb13, unwind: bb9, drop: bb6]; ++ StorageLive(_16); ++ _15 = &mut (((*_24) as variant#4).2: impl std::future::Future); ++ _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb17, unwind: bb20]; + } + + bb15: { +- _12 = copy (_11.0: &mut {async fn body of simple()}); +- StorageLive(_9); +- _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb14, unwind: bb9]; ++ unreachable; ++ } ++ ++ bb16: { ++ StorageDead(_16); ++ _17 = discriminant(_13); ++ switchInt(move _17) -> [0: bb7, 1: bb13, otherwise: bb15]; ++ } ++ ++ bb17: { ++ _13 = as Future>::poll(move _16, move _14) -> [return: bb16, unwind: bb4]; ++ } ++ ++ bb18: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb18, unwind: bb20]; ++ } ++ ++ bb19: { ++ goto -> bb10; ++ } ++ ++ bb20 (cleanup): { ++ discriminant((*_24)) = 2; ++ resume; ++ } ++ ++ bb21: { ++ _14 = move _2; ++ goto -> bb14; ++ } ++ ++ bb22: { ++ _18 = move _2; ++ goto -> bb18; ++ } ++ ++ bb23: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb23, unwind continue]; ++ } ++ ++ bb24: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb24, unwind continue]; ++ } ++ ++ bb25: { ++ nop; ++ (((*_24) as variant#4).0: SyncInt) = SyncInt(const 0_i32); ++ nop; ++ (((*_24) as variant#4).1: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_24) as variant#3).0: ()) = const (); ++ _6 = &mut (((*_24) as variant#4).1: AsyncInt); ++ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb4]; + } + } + diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir new file mode 100644 index 0000000000000..6c4d92e01d5b1 --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir @@ -0,0 +1,173 @@ +// MIR for `simple::{closure#0}` 0 coroutine_async_drop_expand + +fn simple::{closure#0}(_1: {async fn body of simple()}, _2: &mut Context<'_>) -> () +yields () + { + debug _task_context => _2; + let mut _0: (); + let _3: SyncInt; + let mut _5: impl std::future::Future; + let mut _6: &mut AsyncInt; + let mut _7: std::pin::Pin<&mut AsyncInt>; + let mut _8: &mut AsyncInt; + let mut _9: impl std::future::Future; + let mut _10: &mut {async fn body of simple()}; + let mut _11: std::pin::Pin<&mut {async fn body of simple()}>; + let mut _12: &mut {async fn body of simple()}; + let mut _13: std::task::Poll<()>; + let mut _14: &mut std::task::Context<'_>; + let mut _15: &mut impl std::future::Future; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: isize; + let mut _18: &mut std::task::Context<'_>; + let mut _19: &mut impl std::future::Future; + let mut _20: std::pin::Pin<&mut impl std::future::Future>; + let mut _21: isize; + scope 1 { + debug sync_int => _3; + let _4: AsyncInt; + scope 2 { + debug async_int => _4; + } + } + + bb0: { + StorageLive(_3); + _3 = SyncInt(const 0_i32); + StorageLive(_4); + _4 = AsyncInt(const 0_i32); + _0 = const (); + _6 = &mut _4; + _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb12, unwind: bb7]; + } + + bb1: { + StorageDead(_4); + drop(_3) -> [return: bb2, unwind: bb8]; + } + + bb2: { + StorageDead(_3); + _10 = &mut _1; + _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb15, unwind: bb9]; + } + + bb3: { + return; + } + + bb4: { + StorageDead(_5); + StorageDead(_4); + goto -> bb5; + } + + bb5: { + StorageDead(_3); + goto -> bb6; + } + + bb6: { + StorageDead(_9); + coroutine_drop; + } + + bb7 (cleanup): { + StorageDead(_5); + StorageDead(_4); + drop(_3) -> [return: bb8, unwind terminate(cleanup)]; + } + + bb8 (cleanup): { + StorageDead(_3); + drop(_1) -> [return: bb9, unwind terminate(cleanup)]; + } + + bb9 (cleanup): { + StorageDead(_9); + resume; + } + + bb10: { + StorageDead(_5); + goto -> bb1; + } + + bb11: { + _14 = move _2; + goto -> bb17; + } + + bb12: { + _8 = copy (_7.0: &mut AsyncInt); + StorageLive(_5); + _5 = async_drop_in_place::(move _8) -> [return: bb11, unwind: bb7]; + } + + bb13: { + StorageDead(_9); + goto -> bb3; + } + + bb14: { + drop(_1) -> [return: bb13, unwind: bb9]; + } + + bb15: { + _12 = copy (_11.0: &mut {async fn body of simple()}); + StorageLive(_9); + _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb14, unwind: bb9]; + } + + bb16: { + _14 = yield(const false) -> [resume: bb17, drop: bb22]; + } + + bb17: { + StorageLive(_16); + _15 = &mut _5; + _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb20, unwind continue]; + } + + bb18: { + unreachable; + } + + bb19: { + StorageDead(_16); + _17 = discriminant(_13); + switchInt(move _17) -> [0: bb10, 1: bb16, otherwise: bb18]; + } + + bb20: { + _13 = as Future>::poll(move _16, move _14) -> [return: bb19, unwind: bb7]; + } + + bb21: { + _18 = yield(const false) -> [resume: bb26, drop: bb22]; + } + + bb22: { + StorageLive(_20); + _19 = &mut _5; + _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb25, unwind continue]; + } + + bb23: { + unreachable; + } + + bb24: { + StorageDead(_20); + _21 = discriminant(_13); + switchInt(move _21) -> [0: bb4, 1: bb21, otherwise: bb23]; + } + + bb25: { + _13 = as Future>::poll(move _20, move _18) -> [return: bb24, unwind: bb7]; + } + + bb26: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb26, unwind continue]; + } +} diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir new file mode 100644 index 0000000000000..9b1c0a10a92fa --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir @@ -0,0 +1,136 @@ +// MIR for `simple::{closure#0}` 0 coroutine_drop_async + +fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Context<'_>) -> Poll<()> { + debug _task_context => _2; + let mut _0: std::task::Poll<()>; + let _3: SyncInt; + let mut _5: impl std::future::Future; + let mut _6: &mut AsyncInt; + let mut _7: std::pin::Pin<&mut AsyncInt>; + let mut _8: &mut AsyncInt; + let mut _9: impl std::future::Future; + let mut _10: &mut {async fn body of simple()}; + let mut _11: std::pin::Pin<&mut {async fn body of simple()}>; + let mut _12: &mut {async fn body of simple()}; + let mut _13: std::task::Poll<()>; + let mut _14: &mut std::task::Context<'_>; + let mut _15: &mut impl std::future::Future; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: isize; + let mut _18: &mut std::task::Context<'_>; + let mut _19: &mut impl std::future::Future; + let mut _20: std::pin::Pin<&mut impl std::future::Future>; + let mut _21: isize; + let mut _22: (); + let mut _23: u32; + let mut _24: &mut {async fn body of simple()}; + scope 1 { + debug sync_int => (((*_24) as variant#4).0: SyncInt); + let _4: AsyncInt; + scope 2 { + debug async_int => (((*_24) as variant#4).1: AsyncInt); + } + } + + bb0: { + _24 = copy (_1.0: &mut {async fn body of simple()}); + _23 = discriminant((*_24)); + switchInt(move _23) -> [0: bb13, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19]; + } + + bb1: { + nop; + nop; + goto -> bb2; + } + + bb2: { + nop; + goto -> bb3; + } + + bb3: { + StorageDead(_9); + _0 = Poll::<()>::Ready(const ()); + return; + } + + bb4 (cleanup): { + nop; + nop; + drop((((*_24) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; + } + + bb5 (cleanup): { + nop; + goto -> bb6; + } + + bb6 (cleanup): { + StorageDead(_9); + goto -> bb15; + } + + bb7: { + _0 = Poll::<()>::Pending; + discriminant((*_24)) = 4; + return; + } + + bb8: { + StorageLive(_20); + _19 = &mut (((*_24) as variant#4).2: impl std::future::Future); + _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb11, unwind: bb15]; + } + + bb9: { + unreachable; + } + + bb10: { + StorageDead(_20); + _21 = discriminant(_13); + switchInt(move _21) -> [0: bb1, 1: bb7, otherwise: bb9]; + } + + bb11: { + _13 = as Future>::poll(move _20, move _18) -> [return: bb10, unwind: bb4]; + } + + bb12: { + _0 = Poll::<()>::Ready(const ()); + return; + } + + bb13: { + goto -> bb14; + } + + bb14: { + goto -> bb12; + } + + bb15 (cleanup): { + discriminant((*_24)) = 2; + resume; + } + + bb16: { + _14 = move _2; + goto -> bb8; + } + + bb17: { + _18 = move _2; + goto -> bb8; + } + + bb18: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb18, unwind continue]; + } + + bb19: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} From 836cea4c66609fd4e6669170fc9a85218fba1a6b Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 9 May 2026 18:17:48 +0000 Subject: [PATCH 03/12] Call deref_finder when building bodies instead of after it. This is a natural part of creating the `Body`, so do it together instead of separately. --- compiler/rustc_mir_transform/src/coroutine.rs | 17 ++++++----------- .../rustc_mir_transform/src/coroutine/drop.rs | 9 +++++++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 6d32f1251d057..7eabd387c00ef 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1292,6 +1292,9 @@ fn create_coroutine_resume_function<'tcx>( pm::run_passes_no_validate(tcx, body, &[&abort_unwinding_calls::AbortUnwindingCalls], None); + // Run derefer to fix Derefs that are not in the first place + deref_finder(tcx, body, false); + if let Some(dumper) = MirDumper::new(tcx, "coroutine_resume", body) { dumper.dump_mir(body); } @@ -1638,30 +1641,22 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { // Create a copy of our MIR and use it to create the drop shim for the coroutine if has_async_drops { // If coroutine has async drops, generating async drop shim - let mut drop_shim = + let drop_shim = create_coroutine_drop_shim_async(tcx, &transform, body, drop_clean, can_unwind); - // Run derefer to fix Derefs that are not in the first place - deref_finder(tcx, &mut drop_shim, false); body.coroutine.as_mut().unwrap().coroutine_drop_async = Some(drop_shim); } else { // If coroutine has no async drops, generating sync drop shim - let mut drop_shim = + let drop_shim = create_coroutine_drop_shim(tcx, &transform, coroutine_ty, body, drop_clean); - // Run derefer to fix Derefs that are not in the first place - deref_finder(tcx, &mut drop_shim, false); body.coroutine.as_mut().unwrap().coroutine_drop = Some(drop_shim); // For coroutine with sync drop, generating async proxy for `future_drop_poll` call - let mut proxy_shim = create_coroutine_drop_shim_proxy_async(tcx, body); - deref_finder(tcx, &mut proxy_shim, false); + let proxy_shim = create_coroutine_drop_shim_proxy_async(tcx, body); body.coroutine.as_mut().unwrap().coroutine_drop_proxy_async = Some(proxy_shim); } // Create the Coroutine::resume / Future::poll function create_coroutine_resume_function(tcx, transform, body, can_return, can_unwind); - - // Run derefer to fix Derefs that are not in the first place - deref_finder(tcx, body, false); } fn is_required(&self) -> bool { diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 134d37ba4ef47..3baf6b731f9f2 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -600,6 +600,9 @@ pub(super) fn create_coroutine_drop_shim<'tcx>( // unrelated code from the resume part of the function simplify::remove_dead_blocks(&mut body); + // Run derefer to fix Derefs that are not in the first place + deref_finder(tcx, &mut body, false); + // Update the body's def to become the drop glue. let coroutine_instance = body.source.instance; let drop_glue = tcx.require_lang_item(LangItem::DropGlue, body.span); @@ -703,6 +706,9 @@ pub(super) fn create_coroutine_drop_shim_async<'tcx>( None, ); + // Run derefer to fix Derefs that are not in the first place + deref_finder(tcx, &mut body, false); + if let Some(dumper) = MirDumper::new(tcx, "coroutine_drop_async", &body) { dumper.dump_mir(&body); } @@ -750,6 +756,9 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( }; body.basic_blocks_mut()[call_bb].terminator = Some(Terminator { source_info, kind }); + // Run derefer to fix Derefs that are not in the first place + deref_finder(tcx, &mut body, false); + if let Some(dumper) = MirDumper::new(tcx, "coroutine_drop_proxy_async", &body) { dumper.dump_mir(&body); } From 25b459ee4775fbe0a799b794013dd762fbdde2e4 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 15:50:08 +0000 Subject: [PATCH 04/12] Fix deref separation for async drop shim. We generate a `*(_1.0)` projection in the `needs_sync_drop` case. Ensure that `deref_finder` is called on all paths. --- .../src/shim/async_destructor_ctor.rs | 79 ++++++++++--------- ...losure#0}.SyncInt.MentionedItems.after.mir | 4 +- ...ce-{closure#0}.SyncInt.StateTransform.diff | 27 ++++--- tests/mir-opt/coroutine/async_drop.rs | 2 +- 4 files changed, 59 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 3a0d0ce474d77..c6cb39c57bdc5 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -9,6 +9,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitableExt}; use super::*; +use crate::deref_separator::deref_finder; use crate::patch::MirPatch; pub(super) fn build_async_destructor_ctor_shim<'tcx>( @@ -39,12 +40,12 @@ pub(super) fn build_async_destructor_ctor_shim<'tcx>( } // build_drop_shim analog for async drop glue (for generated coroutine poll function) +#[tracing::instrument(level = "trace", skip(tcx), ret)] pub(super) fn build_async_drop_shim<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, ty: Ty<'tcx>, ) -> Body<'tcx> { - debug!("build_async_drop_shim(def_id={:?}, ty={:?})", def_id, ty); let ty::Coroutine(_, parent_args) = ty.kind() else { bug!(); }; @@ -111,45 +112,47 @@ pub(super) fn build_async_drop_shim<'tcx>( parent_args.as_coroutine().resume_ty(), ))); body.phase = MirPhase::Runtime(RuntimePhase::Initial); - if !needs_async_drop || drop_ty.references_error() { - // Returning noop body for types without `need async drop` - // (or sync Drop in case of !`need async drop` && `need drop`). - // And also for error types. - return body; - } - - let dropee_ptr = Place::from(body.local_decls.push(LocalDecl::new(drop_ptr_ty, span))); - let st_kind = StatementKind::Assign(Box::new(( - dropee_ptr, - Rvalue::Use(Operand::Move(coroutine_layout_dropee), WithRetag::Yes), - ))); - body.basic_blocks_mut()[START_BLOCK].statements.push(Statement::new(source_info, st_kind)); - let dropline = body.basic_blocks.last_index(); - - let patch = { - let mut elaborator = DropShimElaborator { - body: &body, - patch: MirPatch::new(&body), - tcx, - typing_env, - produce_async_drops: true, + // Returning noop body for types without `need async drop` + // (or sync Drop in case of !`need async drop` && `need drop`). + // And also for error types. + if needs_async_drop && !drop_ty.references_error() { + let dropee_ptr = Place::from(body.local_decls.push(LocalDecl::new(drop_ptr_ty, span))); + let st_kind = StatementKind::Assign(Box::new(( + dropee_ptr, + Rvalue::Use(Operand::Move(coroutine_layout_dropee), WithRetag::Yes), + ))); + body.basic_blocks_mut()[START_BLOCK].statements.push(Statement::new(source_info, st_kind)); + + let dropline = body.basic_blocks.last_index(); + + let patch = { + let mut elaborator = DropShimElaborator { + body: &body, + patch: MirPatch::new(&body), + tcx, + typing_env, + produce_async_drops: true, + }; + let dropee = tcx.mk_place_deref(dropee_ptr); + let resume_block = elaborator.patch.resume_block(); + elaborate_drop( + &mut elaborator, + source_info, + dropee, + (), + return_block, + Unwind::To(resume_block), + START_BLOCK, + dropline, + ); + elaborator.patch }; - let dropee = tcx.mk_place_deref(dropee_ptr); - let resume_block = elaborator.patch.resume_block(); - elaborate_drop( - &mut elaborator, - source_info, - dropee, - (), - return_block, - Unwind::To(resume_block), - START_BLOCK, - dropline, - ); - elaborator.patch - }; - patch.apply(&mut body); + patch.apply(&mut body); + } + + // We did not bother respecting deref separation, do it here. + deref_finder(tcx, &mut body, false); body } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir index 21f26a30f75e7..b958b843c6df0 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.MentionedItems.after.mir @@ -4,9 +4,11 @@ fn async_drop_in_place::{closure#0}(_1: {async fn body of async_drop_in_place [return: bb1, unwind continue]; + _3 = no_retag copy (_1.0: &mut SyncInt); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff index aafff3292dd4f..198209a013264 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncInt.StateTransform.diff @@ -15,26 +15,27 @@ + storage_conflicts = BitMatrix(0x0) {} + } + let mut _0: std::task::Poll<()>; -+ let mut _3: (); -+ let mut _4: u32; -+ let mut _5: &mut {async fn body of std::future::async_drop_in_place()}; -+ let mut _6: &mut SyncInt; + let mut _3: &mut SyncInt; ++ let mut _4: (); ++ let mut _5: u32; ++ let mut _6: &mut {async fn body of std::future::async_drop_in_place()}; bb0: { -- drop((*(_1.0: &mut SyncInt))) -> [return: bb1, unwind continue]; -+ _5 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); -+ _4 = discriminant((*_5)); -+ switchInt(move _4) -> [0: bb6, 1: bb4, 2: bb3, otherwise: bb5]; +- _3 = no_retag copy (_1.0: &mut SyncInt); +- drop((*_3)) -> [return: bb1, unwind continue]; ++ _6 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _5 = discriminant((*_6)); ++ switchInt(move _5) -> [0: bb6, 1: bb4, 2: bb3, otherwise: bb5]; } bb1: { -+ _0 = Poll::<()>::Ready(move _3); -+ discriminant((*_5)) = 1; ++ _0 = Poll::<()>::Ready(move _4); ++ discriminant((*_6)) = 1; return; + } + + bb2 (cleanup): { -+ discriminant((*_5)) = 2; ++ discriminant((*_6)) = 2; + resume; + } + @@ -52,8 +53,8 @@ + } + + bb6: { -+ _6 = no_retag copy ((*_5).0: &mut SyncInt); -+ drop((*_6)) -> [return: bb1, unwind: bb2]; ++ _3 = no_retag copy ((*_6).0: &mut SyncInt); ++ drop((*_3)) -> [return: bb1, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.rs b/tests/mir-opt/coroutine/async_drop.rs index 7da1514f042e6..1b4a382f960aa 100644 --- a/tests/mir-opt/coroutine/async_drop.rs +++ b/tests/mir-opt/coroutine/async_drop.rs @@ -1,5 +1,5 @@ //@ skip-filecheck -//@ compile-flags: -Zmir-opt-level=0 -Zvalidate-mir=no +//@ compile-flags: -Zmir-opt-level=0 //@ needs-unwind //@ edition: 2024 From 4b092158605a7f524216524e58ac49e001f48be5 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 15:51:30 +0000 Subject: [PATCH 05/12] Simplify build_adrop_for_coroutine_shim. We have `deref_finder` that introduces locals as needed. This allows to avoid bothering when writing the shim. --- compiler/rustc_mir_transform/src/shim.rs | 34 ----- .../src/shim/async_destructor_ctor.rs | 133 +++++++++--------- 2 files changed, 66 insertions(+), 101 deletions(-) diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 7f92199dec455..1e50be3cd7f02 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -30,40 +30,6 @@ pub(super) fn provide(providers: &mut Providers) { providers.mir_shims = make_shim; } -// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> accesses -struct FixProxyFutureDropVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - replace_to: Local, -} - -impl<'tcx> MutVisitor<'tcx> for FixProxyFutureDropVisitor<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn visit_place( - &mut self, - place: &mut Place<'tcx>, - _context: PlaceContext, - _location: Location, - ) { - if place.local == Local::from_u32(1) { - if place.projection.len() == 1 { - assert!(matches!( - place.projection.first(), - Some(ProjectionElem::Field(FieldIdx::ZERO, _)) - )); - *place = Place::from(self.replace_to); - } else if place.projection.len() == 2 { - assert!(matches!(place.projection[0], ProjectionElem::Field(FieldIdx::ZERO, _))); - assert!(matches!(place.projection[1], ProjectionElem::Deref)); - *place = - Place::from(self.replace_to).project_deeper(&[ProjectionElem::Deref], self.tcx); - } - } - } -} - fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<'tcx> { debug!("make_shim({:?})", instance); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index c6cb39c57bdc5..02f748c21e083 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -12,6 +12,8 @@ use super::*; use crate::deref_separator::deref_finder; use crate::patch::MirPatch; +const SELF_ARG: Local = Local::arg(0); + pub(super) fn build_async_destructor_ctor_shim<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, @@ -76,7 +78,7 @@ pub(super) fn build_async_drop_shim<'tcx>( let source_info = SourceInfo::outermost(span); // The first argument (index 0) which will be local 1 (after the return value). - let coroutine_layout = Place::from(Local::arg(0)); + let coroutine_layout = Place::from(SELF_ARG); let coroutine_layout_dropee = tcx.mk_place_field(coroutine_layout, FieldIdx::new(0), drop_ptr_ty); @@ -199,87 +201,85 @@ fn build_adrop_for_coroutine_shim<'tcx>( let ty::Coroutine(coroutine_def_id, impl_args) = impl_ty.kind() else { bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", instance); }; - let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty); - // taking _1.0 (impl from Pin) - let pin_proxy_layout_local = Local::new(1); let source_info = SourceInfo::outermost(span); - // converting `(_1: Pin<&mut CorLayout>, _2: &mut Context<'_>) -> Poll<()>` - // into `(_1: Pin<&mut ProxyLayout>, _2: &mut Context<'_>) -> Poll<()>` - // let mut _x: &mut CorLayout = &mut *_1.0.0; - // Replace old _1.0 accesses into _x accesses; let body = tcx.optimized_mir(*coroutine_def_id).future_drop_poll().unwrap(); let mut body: Body<'tcx> = EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args).skip_norm_wip(); body.source.instance = instance; body.phase = MirPhase::Runtime(RuntimePhase::Initial); body.var_debug_info.clear(); + + // converting `(_1: Pin<&mut CorLayout>, _2: &mut Context<'_>) -> Poll<()>` + // into `(_1: Pin<&mut ProxyLayout>, _2: &mut Context<'_>) -> Poll<()>` + // let mut _x: &mut CorLayout = &mut *_1.0.0; + // Replace old _1.0 accesses into _x accesses; + let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty); + let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); let args = tcx.mk_args(&[proxy_ref.into()]); let pin_proxy_ref = Ty::new_adt(tcx, pin_adt_ref, args); let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty); - - let proxy_ref_local = body.local_decls.push(LocalDecl::new(proxy_ref, span)); let cor_ref_local = body.local_decls.push(LocalDecl::new(cor_ref, span)); FixProxyFutureDropVisitor { tcx, replace_to: cor_ref_local }.visit_body(&mut body); + // Now changing first arg from Pin<&mut ImplCoroutine> to Pin<&mut ProxyCoroutine> - body.local_decls[pin_proxy_layout_local] = LocalDecl::new(pin_proxy_ref, span); - - { - let mut idx: usize = 0; - // _proxy = _1.0 : Pin<&mut ProxyLayout> ==> &mut ProxyLayout - let proxy_ref_place = Place::from(pin_proxy_layout_local) - .project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx); - body.basic_blocks_mut()[START_BLOCK].statements.insert( - idx, - Statement::new( - source_info, - StatementKind::Assign(Box::new(( - Place::from(proxy_ref_local), - Rvalue::Use(Operand::Copy(proxy_ref_place), WithRetag::Yes), - ))), - ), - ); - idx += 1; - - // _cor_ref_tmp = (*(*_proxy).0).0... - let mut cor_ref_tmp_local = proxy_ref_local; - proxy_ty.find_async_drop_impl_coroutine(tcx, |ty| { - if ty != proxy_ty { - let ty_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty); - let impl_ptr_place = Place::from(cor_ref_tmp_local).project_deeper( - &[PlaceElem::Deref, PlaceElem::Field(FieldIdx::ZERO, ty_ref)], - tcx, - ); - cor_ref_tmp_local = body.local_decls.push(LocalDecl::new(ty_ref, span)); - body.basic_blocks_mut()[START_BLOCK].statements.insert( - idx, - Statement::new( - source_info, - StatementKind::Assign(Box::new(( - Place::from(cor_ref_tmp_local), - Rvalue::Use(Operand::Copy(impl_ptr_place), WithRetag::Yes), - ))), - ), - ); - idx += 1; - } - }); + body.local_decls[SELF_ARG] = LocalDecl::new(pin_proxy_ref, span); - // _cor_ref = cor_ref_tmp - body.basic_blocks_mut()[START_BLOCK].statements.insert( - idx, - Statement::new( - source_info, - StatementKind::Assign(Box::new(( - Place::from(cor_ref_local), - Rvalue::Use(Operand::Move(Place::from(cor_ref_tmp_local)), WithRetag::Yes), - ))), - ), - ); + // Build the projection to assign `cor_ref_local = _1.`. + let mut pin_proxy_to_cor_projection = vec![ + // _1.0 : Pin<&mut ProxyLayout> ==> &mut ProxyLayout + PlaceElem::Field(FieldIdx::ZERO, proxy_ref), + ]; + + // _cor_ref_tmp = (*(*_proxy).0).0... + proxy_ty.find_async_drop_impl_coroutine(tcx, |ty| { + if ty != proxy_ty { + let ty_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty); + pin_proxy_to_cor_projection.push(PlaceElem::Deref); + pin_proxy_to_cor_projection.push(PlaceElem::Field(FieldIdx::ZERO, ty_ref)); + } + }); + + // _cor_ref = cor_ref_tmp + let projected_pin = Place::from(SELF_ARG).project_deeper(&pin_proxy_to_cor_projection, tcx); + body.basic_blocks_mut()[START_BLOCK].statements.insert( + 0, + Statement::new( + source_info, + StatementKind::Assign(Box::new(( + Place::from(cor_ref_local), + Rvalue::Use(Operand::Move(projected_pin), WithRetag::Yes), + ))), + ), + ); + + // We did not bother respecting deref separation, do it here. + deref_finder(tcx, &mut body, false); + + return body; + + /// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> accesses + struct FixProxyFutureDropVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + replace_to: Local, + } + + impl<'tcx> MutVisitor<'tcx> for FixProxyFutureDropVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, _: Location) { + if place.local == SELF_ARG + && let Some((first, rest)) = place.projection.split_first() + { + assert!(matches!(first, ProjectionElem::Field(FieldIdx::ZERO, _))); + *place = Place::from(self.replace_to).project_deeper(rest, self.tcx); + } + } } - body } // When dropping async drop coroutine, we continue its execution. @@ -294,9 +294,8 @@ fn build_adrop_for_adrop_shim<'tcx>( let source_info = SourceInfo::outermost(span); let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty); // taking _1.0 (impl from Pin) - let pin_proxy_layout_local = Local::new(1); - let proxy_ref_place = Place::from(pin_proxy_layout_local) - .project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx); + let proxy_ref_place = + Place::from(SELF_ARG).project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx); let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty); // ret_ty = `Poll<()>` From 210b8b49ef96ff8e83086f0e63386f34d2e7c9ae Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 08:38:32 +0000 Subject: [PATCH 06/12] Avoid modifying succ block in build_async_drop. This makes code generation simpler, as we do not need to verify that successor blocks are only used once. This makes code generation simpler. The resulting MIR increase can easily be simplified by `SimplifyCfg`. --- .../rustc_mir_transform/src/elaborate_drop.rs | 78 +-- .../src/elaborate_drops.rs | 4 - compiler/rustc_mir_transform/src/patch.rs | 5 - compiler/rustc_mir_transform/src/shim.rs | 3 - ...sure#0}.AsyncEnum.MentionedItems.after.mir | 52 +- ...-{closure#0}.AsyncEnum.StateTransform.diff | 50 +- ...osure#0}.AsyncInt.MentionedItems.after.mir | 16 +- ...syncReference_'__.MentionedItems.after.mir | 16 +- ...re#0}.AsyncStruct.MentionedItems.after.mir | 84 +-- ...closure#0}.AsyncStruct.StateTransform.diff | 41 +- ...#0}.SyncThenAsync.MentionedItems.after.mir | 70 +-- ...osure#0}.SyncThenAsync.StateTransform.diff | 82 +-- ...rop.double-{closure#0}.ElaborateDrops.diff | 42 +- ...rop.double-{closure#0}.StateTransform.diff | 159 ++--- ...osure#0}.coroutine_async_drop_expand.0.mir | 124 ++-- ...rate_drops-{closure#0}.ElaborateDrops.diff | 168 +++-- ...rate_drops-{closure#0}.StateTransform.diff | 584 ++++++++++-------- ...rop.simple-{closure#0}.ElaborateDrops.diff | 24 +- ...rop.simple-{closure#0}.StateTransform.diff | 92 +-- ...osure#0}.coroutine_async_drop_expand.0.mir | 66 +- ...losure#0}.[Foo;1].MentionedItems.after.mir | 46 +- 21 files changed, 966 insertions(+), 840 deletions(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index c835ff7dbe070..0c072096f064a 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -96,8 +96,6 @@ pub(crate) trait DropElaborator<'a, 'tcx>: fmt::Debug { fn typing_env(&self) -> ty::TypingEnv<'tcx>; fn allow_async_drops(&self) -> bool; - fn terminator_loc(&self, bb: BasicBlock) -> Location; - // Drop logic /// Returns how `path` should be dropped, given `mode`. @@ -200,19 +198,18 @@ where self.elaborator.tcx() } - // Generates three blocks: - // * #1:pin_obj_bb: call Pin::new_unchecked(&mut obj) - // * #2:call_drop_bb: fut = call obj.() OR call async_drop_in_place(obj) - // * #3:drop_term_bb: drop (obj, fut, ...) - // We keep async drop unexpanded to poll-loop here, to expand it later, at StateTransform - - // into states expand. - // call_destructor_only - to call only AsyncDrop::drop, not full async_drop_in_place glue + /// Generates three blocks: + /// * #1:pin_obj_bb: call Pin::new_unchecked(&mut obj) + /// * #2:call_drop_bb: fut = call obj.() OR call async_drop_in_place(obj) + /// * #3:drop_term_bb: drop (obj, fut, ...) + /// We keep async drop unexpanded to poll-loop here, to expand it later, at StateTransform - + /// into states expand. + /// call_destructor_only - to call only AsyncDrop::drop, not full async_drop_in_place glue #[instrument(level = "debug", skip(self), ret)] fn build_async_drop( &mut self, place: Place<'tcx>, drop_ty: Ty<'tcx>, - bb: Option, succ: BasicBlock, unwind: Unwind, dropline: Option, @@ -221,11 +218,6 @@ where let tcx = self.tcx(); let span = self.source_info.span; - let pin_obj_bb = bb.unwrap_or_else(|| { - // Temporary terminator, will be replaced by patch - self.new_block(unwind, TerminatorKind::Return) - }); - let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only { // Resolving obj.() let trait_ref = @@ -260,8 +252,8 @@ where self.elaborator.body().span, "AsyncDrop type without correct `async fn drop(...)`.", ); - self.elaborator.patch().patch_terminator( - pin_obj_bb, + return self.new_block( + unwind, TerminatorKind::Drop { place, target: succ, @@ -271,7 +263,6 @@ where async_fut: None, }, ); - return pin_obj_bb; }; let drop_fn = Ty::new_fn_def(tcx, drop_fn_def_id, trait_args); let sig = drop_fn.fn_sig(tcx); @@ -291,10 +282,7 @@ where // #1:pin_obj_bb >>> obj_ref = &mut obj let obj_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, drop_ty); let obj_ref_place = Place::from(self.new_temp(obj_ref_ty)); - - let term_loc = self.elaborator.terminator_loc(pin_obj_bb); - self.elaborator.patch().add_assign( - term_loc, + let assign_obj_ref_place = self.assign( obj_ref_place, Rvalue::Ref( tcx.lifetimes.re_erased, @@ -318,10 +306,8 @@ where })); // Create an intermediate block that does StorageDead(fut) then jumps to succ. - // This is necessary because `succ` may differ from `self.succ` (e.g. when - // build_async_drop is called from drop_loop, `succ` is the loop header). - // Placing StorageDead directly at `self.succ` would miss the loop-back edge, - // causing StorageLive(fut) to fire again without a preceding StorageDead. + // This is necessary because we do not want to modify statements + // in existing blocks, in case those are used somewhere else in MIR. let succ_with_dead = self.new_block_with_statements( unwind, vec![Statement::new(self.source_info, StatementKind::StorageDead(fut.local))], @@ -394,8 +380,9 @@ where } // #1:pin_obj_bb >>> call Pin::new_unchecked(&mut obj) - self.elaborator.patch().patch_terminator( - pin_obj_bb, + self.new_block_with_statements( + unwind, + vec![assign_obj_ref_place], TerminatorKind::Call { func: pin_obj_new_unchecked_fn, args: [dummy_spanned(Operand::Move(obj_ref_place))].into(), @@ -405,8 +392,7 @@ where call_source: CallSource::Misc, fn_span: span, }, - ); - pin_obj_bb + ) } fn build_drop(&mut self, bb: BasicBlock) { @@ -414,15 +400,17 @@ where if !self.elaborator.patch_ref().block(self.elaborator.body(), bb).is_cleanup && self.check_if_can_async_drop(drop_ty, false) { - self.build_async_drop( + let async_drop_bb = self.build_async_drop( self.place, drop_ty, - Some(bb), self.succ, self.unwind, self.dropline, false, ); + self.elaborator + .patch() + .patch_terminator(bb, TerminatorKind::Goto { target: async_drop_bb }); } else { self.elaborator.patch().patch_terminator( bb, @@ -1012,7 +1000,7 @@ where ) -> BasicBlock { let ty = self.place_ty(self.place); if !unwind.is_cleanup() && self.check_if_can_async_drop(ty, true) { - self.build_async_drop(self.place, ty, None, succ, unwind, dropline, true) + self.build_async_drop(self.place, ty, succ, unwind, dropline, true) } else { self.destructor_call_block_sync(succ, unwind) } @@ -1074,15 +1062,11 @@ where let place = tcx.mk_place_deref(ptr); if !unwind.is_cleanup() && self.check_if_can_async_drop(ety, false) { - self.build_async_drop( - place, - ety, - Some(drop_block), - loop_block, - unwind, - dropline, - false, - ); + let async_drop_bb = + self.build_async_drop(place, ety, loop_block, unwind, dropline, false); + self.elaborator + .patch() + .patch_terminator(drop_block, TerminatorKind::Goto { target: async_drop_bb }); } else { self.elaborator.patch().patch_terminator( drop_block, @@ -1338,15 +1322,7 @@ where fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { let drop_ty = self.place_ty(self.place); if !unwind.is_cleanup() && self.check_if_can_async_drop(drop_ty, false) { - self.build_async_drop( - self.place, - drop_ty, - None, - self.succ, - unwind, - self.dropline, - false, - ) + self.build_async_drop(self.place, drop_ty, self.succ, unwind, self.dropline, false) } else { self.new_block( unwind, diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 3787276919cf5..11fd15190e7c8 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -162,10 +162,6 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> { true } - fn terminator_loc(&self, bb: BasicBlock) -> Location { - self.patch.terminator_loc(self.body, bb) - } - #[instrument(level = "debug", skip(self), ret)] fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle { let ((maybe_init, maybe_uninit), multipart) = match mode { diff --git a/compiler/rustc_mir_transform/src/patch.rs b/compiler/rustc_mir_transform/src/patch.rs index 015bae56cf57e..da1077707baff 100644 --- a/compiler/rustc_mir_transform/src/patch.rs +++ b/compiler/rustc_mir_transform/src/patch.rs @@ -166,11 +166,6 @@ impl<'tcx> MirPatch<'tcx> { } } - pub(crate) fn terminator_loc(&self, body: &Body<'tcx>, bb: BasicBlock) -> Location { - let offset = self.block(body, bb).statements.len(); - Location { block: bb, statement_index: offset } - } - /// Queues the addition of a new temporary with additional local info. pub(crate) fn new_local_with_info( &mut self, diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 1e50be3cd7f02..49c899b3e8fe7 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -429,9 +429,6 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { self.typing_env } - fn terminator_loc(&self, bb: BasicBlock) -> Location { - self.patch.terminator_loc(self.body, bb) - } fn allow_async_drops(&self) -> bool { self.produce_async_drops } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir index f53de21edb0ed..f0aac6ca9b377 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir @@ -22,7 +22,7 @@ yields () bb0: { _3 = move (_1.0: &mut AsyncEnum); - goto -> bb21; + goto -> bb24; } bb1: { @@ -49,43 +49,43 @@ yields () } bb6: { - _5 = &mut (((*_3) as A).0: AsyncInt); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; + StorageDead(_4); + goto -> bb1; } bb7: { - StorageDead(_4); - goto -> bb1; + async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2]; } bb8: { - async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2]; + _7 = copy (_6.0: &mut AsyncInt); + StorageLive(_4); + _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb2]; } bb9: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb2]; + _5 = &mut (((*_3) as A).0: AsyncInt); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; } bb10: { - _9 = &mut (((*_3) as A).0: AsyncInt); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb2]; + StorageDead(_8); + goto -> bb3; } bb11: { - StorageDead(_8); - goto -> bb3; + async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb10, unwind: bb2, drop: bb1]; } bb12: { - async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb11, unwind: bb2, drop: bb1]; + _11 = copy (_10.0: &mut AsyncInt); + StorageLive(_8); + _8 = async_drop_in_place::(move _11) -> [return: bb11, unwind: bb2]; } bb13: { - _11 = copy (_10.0: &mut AsyncInt); - StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb12, unwind: bb2]; + _9 = &mut (((*_3) as A).0: AsyncInt); + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb12, unwind: bb2]; } bb14 (cleanup): { @@ -106,7 +106,7 @@ yields () bb18: { _12 = discriminant((*_3)); - switchInt(move _12) -> [0: bb10, otherwise: bb17]; + switchInt(move _12) -> [0: bb13, otherwise: bb17]; } bb19 (cleanup): { @@ -118,25 +118,25 @@ yields () bb20: { StorageDead(_15); _14 = discriminant((*_3)); - switchInt(move _14) -> [0: bb6, otherwise: bb16]; + switchInt(move _14) -> [0: bb9, otherwise: bb16]; } bb21: { - _16 = &mut (*_3); - _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb24, unwind: bb19]; + StorageDead(_15); + goto -> bb18; } bb22: { - StorageDead(_15); - goto -> bb18; + async drop((*_3); poll=_15) -> [return: bb21, unwind: bb19, drop: bb20]; } bb23: { - async drop((*_3); poll=_15) -> [return: bb22, unwind: bb19, drop: bb20]; + StorageLive(_15); + _15 = ::drop(move _17) -> [return: bb22, unwind: bb19]; } bb24: { - StorageLive(_15); - _15 = ::drop(move _17) -> [return: bb23, unwind: bb19]; + _16 = &mut (*_3); + _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb23, unwind: bb19]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff index 0c8f627414c80..876f9a12ed288 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff @@ -106,51 +106,52 @@ } bb4: { -- _5 = &mut (((*_3) as A).0: AsyncInt); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; -+ _45 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); -+ _9 = &mut (((*_45) as A).0: AsyncInt); -+ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb7, unwind: bb2]; - } - - bb5: { - StorageDead(_4); + nop; goto -> bb1; } - bb6: { -- async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb5, unwind: bb2]; + bb5: { +- async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb4, unwind: bb2]; + _24 = move _2; + goto -> bb16; } - bb7: { + bb6: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb6, unwind: bb2]; +- _4 = async_drop_in_place::(move _7) -> [return: bb5, unwind: bb2]; + _11 = copy (_10.0: &mut AsyncInt); + nop; -+ (((*_43) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _11) -> [return: bb6, unwind: bb2]; ++ (((*_43) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _11) -> [return: bb5, unwind: bb2]; + } + + bb7: { +- _5 = &mut (((*_3) as A).0: AsyncInt); +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; ++ _45 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); ++ _9 = &mut (((*_45) as A).0: AsyncInt); ++ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb6, unwind: bb2]; } - bb8: { -- _9 = &mut (((*_3) as A).0: AsyncInt); -- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb11, unwind: bb2]; +- StorageDead(_8); +- goto -> bb1; + bb8 (cleanup): { + _46 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + drop((((*_46) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb9: { -- StorageDead(_8); -- goto -> bb1; +- async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb8, unwind: bb2, drop: bb1]; + _47 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + drop((((*_47) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; } - bb10: { -- async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb9, unwind: bb2, drop: bb1]; +- _11 = copy (_10.0: &mut AsyncInt); +- StorageLive(_8); +- _8 = async_drop_in_place::(move _11) -> [return: bb9, unwind: bb2]; + bb10 (cleanup): { + nop; + _48 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); @@ -159,13 +160,12 @@ } bb11: { -- _11 = copy (_10.0: &mut AsyncInt); -- StorageLive(_8); -- _8 = async_drop_in_place::(move _11) -> [return: bb10, unwind: bb2]; +- _9 = &mut (((*_3) as A).0: AsyncInt); +- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb10, unwind: bb2]; + nop; + _49 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + _12 = discriminant((*_49)); -+ switchInt(move _12) -> [0: bb4, otherwise: bb9]; ++ switchInt(move _12) -> [0: bb7, otherwise: bb9]; } - bb12 (cleanup): { @@ -199,7 +199,7 @@ bb16: { - StorageDead(_15); - _14 = discriminant((*_3)); -- switchInt(move _14) -> [0: bb4, otherwise: bb13]; +- switchInt(move _14) -> [0: bb7, otherwise: bb13]; + StorageLive(_26); + _25 = &mut (((*_43) as variant#5).0: impl std::future::Future); + _26 = Pin::<&mut impl Future>::new_unchecked(move _25) -> [return: bb19, unwind: bb26]; @@ -208,7 +208,7 @@ bb17: { - StorageDead(_15); - _12 = discriminant((*_3)); -- switchInt(move _12) -> [0: bb8, otherwise: bb14]; +- switchInt(move _12) -> [0: bb11, otherwise: bb14]; + unreachable; } @@ -216,7 +216,7 @@ - async drop((*_3); poll=_15) -> [return: bb17, unwind: bb15, drop: bb16]; + StorageDead(_26); + _27 = discriminant(_23); -+ switchInt(move _27) -> [0: bb5, 1: bb15, otherwise: bb17]; ++ switchInt(move _27) -> [0: bb4, 1: bb15, otherwise: bb17]; } bb19: { diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir index 5c41d70197194..356e8bb2d0bb0 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir @@ -11,7 +11,7 @@ yields () bb0: { _3 = move (_1.0: &mut AsyncInt); - goto -> bb4; + goto -> bb7; } bb1: { @@ -29,21 +29,21 @@ yields () } bb4: { - _5 = &mut (*_3); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; + StorageDead(_4); + goto -> bb3; } bb5: { - StorageDead(_4); - goto -> bb3; + async drop((*_3); poll=_4) -> [return: bb4, unwind: bb2, drop: bb1]; } bb6: { - async drop((*_3); poll=_4) -> [return: bb5, unwind: bb2, drop: bb1]; + StorageLive(_4); + _4 = ::drop(move _6) -> [return: bb5, unwind: bb2]; } bb7: { - StorageLive(_4); - _4 = ::drop(move _6) -> [return: bb6, unwind: bb2]; + _5 = &mut (*_3); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir index ec5530e75e1cc..f6ef2e1fe13de 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir @@ -11,7 +11,7 @@ yields () bb0: { _3 = move (_1.0: &mut AsyncReference<'_>); - goto -> bb4; + goto -> bb7; } bb1: { @@ -29,21 +29,21 @@ yields () } bb4: { - _5 = &mut (*_3); - _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; + StorageDead(_4); + goto -> bb3; } bb5: { - StorageDead(_4); - goto -> bb3; + async drop((*_3); poll=_4) -> [return: bb4, unwind: bb2, drop: bb1]; } bb6: { - async drop((*_3); poll=_4) -> [return: bb5, unwind: bb2, drop: bb1]; + StorageLive(_4); + _4 = as AsyncDrop>::drop(move _6) -> [return: bb5, unwind: bb2]; } bb7: { - StorageLive(_4); - _4 = as AsyncDrop>::drop(move _6) -> [return: bb6, unwind: bb2]; + _5 = &mut (*_3); + _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir index 1c091c3916e6f..3599dfe0b7a7a 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir @@ -27,7 +27,7 @@ yields () bb0: { _3 = move (_1.0: &mut AsyncStruct); - goto -> bb22; + goto -> bb25; } bb1: { @@ -57,103 +57,103 @@ yields () } bb6: { - _5 = &mut ((*_3).2: AsyncInt); - StorageDead(_16); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; + StorageDead(_4); + goto -> bb1; } bb7: { - StorageDead(_4); - goto -> bb1; + async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2]; } bb8: { - async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2]; + _7 = copy (_6.0: &mut AsyncInt); + StorageLive(_4); + _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb2]; } bb9: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb2]; + StorageDead(_16); + _5 = &mut ((*_3).2: AsyncInt); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; } bb10: { - _9 = &mut ((*_3).1: AsyncInt); - StorageDead(_20); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb4]; + StorageDead(_8); + goto -> bb9; } bb11: { - StorageDead(_8); - goto -> bb6; + async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb10, unwind: bb4]; } bb12: { - async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb11, unwind: bb4]; + _11 = copy (_10.0: &mut AsyncInt); + StorageLive(_8); + _8 = async_drop_in_place::(move _11) -> [return: bb11, unwind: bb4]; } bb13: { - _11 = copy (_10.0: &mut AsyncInt); - StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb12, unwind: bb4]; + StorageDead(_20); + _9 = &mut ((*_3).1: AsyncInt); + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb12, unwind: bb4]; } bb14: { - _13 = &mut ((*_3).2: AsyncInt); - _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb17, unwind: bb2]; + StorageDead(_12); + goto -> bb3; } bb15: { - StorageDead(_12); - goto -> bb3; + async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb14, unwind: bb2, drop: bb1]; } bb16: { - async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb15, unwind: bb2, drop: bb1]; + _15 = copy (_14.0: &mut AsyncInt); + StorageLive(_12); + _12 = async_drop_in_place::(move _15) -> [return: bb15, unwind: bb2]; } bb17: { - _15 = copy (_14.0: &mut AsyncInt); - StorageLive(_12); - _12 = async_drop_in_place::(move _15) -> [return: bb16, unwind: bb2]; + _13 = &mut ((*_3).2: AsyncInt); + _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb16, unwind: bb2]; } bb18: { - _17 = &mut ((*_3).1: AsyncInt); - _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb21, unwind: bb4]; + StorageDead(_16); + goto -> bb17; } bb19: { - StorageDead(_16); - goto -> bb14; + async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb18, unwind: bb4, drop: bb9]; } bb20: { - async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb19, unwind: bb4, drop: bb6]; + _19 = copy (_18.0: &mut AsyncInt); + StorageLive(_16); + _16 = async_drop_in_place::(move _19) -> [return: bb19, unwind: bb4]; } bb21: { - _19 = copy (_18.0: &mut AsyncInt); - StorageLive(_16); - _16 = async_drop_in_place::(move _19) -> [return: bb20, unwind: bb4]; + _17 = &mut ((*_3).1: AsyncInt); + _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb20, unwind: bb4]; } bb22: { - _21 = &mut (*_3); - _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb25, unwind: bb5]; + StorageDead(_20); + goto -> bb21; } bb23: { - StorageDead(_20); - goto -> bb18; + async drop((*_3); poll=_20) -> [return: bb22, unwind: bb5, drop: bb13]; } bb24: { - async drop((*_3); poll=_20) -> [return: bb23, unwind: bb5, drop: bb10]; + StorageLive(_20); + _20 = ::drop(move _22) -> [return: bb23, unwind: bb5]; } bb25: { - StorageLive(_20); - _20 = ::drop(move _22) -> [return: bb24, unwind: bb5]; + _21 = &mut (*_3); + _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb24, unwind: bb5]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff index 658a6efa16a2c..5d84cfbe57f7e 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff @@ -140,31 +140,30 @@ } bb5: { -- _5 = &mut ((*_3).2: AsyncInt); -- StorageDead(_16); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; +- StorageDead(_4); + nop; -+ goto -> bb1; + goto -> bb1; } bb6: { -- StorageDead(_4); -- goto -> bb1; +- async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb5, unwind: bb2]; + _34 = move _2; + goto -> bb17; } bb7: { -- async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2]; +- _7 = copy (_6.0: &mut AsyncInt); +- StorageLive(_4); +- _4 = async_drop_in_place::(move _7) -> [return: bb6, unwind: bb2]; + _15 = copy (_14.0: &mut AsyncInt); + nop; + (((*_62) as variant#6).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb6, unwind: bb2]; } bb8: { -- _7 = copy (_6.0: &mut AsyncInt); -- StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb2]; +- StorageDead(_16); +- _5 = &mut ((*_3).2: AsyncInt); +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; + nop; + _65 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); + _13 = &mut ((*_65).2: AsyncInt); @@ -172,23 +171,23 @@ } bb9: { -- _9 = &mut ((*_3).1: AsyncInt); -- StorageDead(_20); -- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb12, unwind: bb3]; +- StorageDead(_8); +- goto -> bb8; + _43 = move _2; + goto -> bb23; } bb10: { -- StorageDead(_8); -- goto -> bb5; +- async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb9, unwind: bb3]; + _19 = copy (_18.0: &mut AsyncInt); + nop; + (((*_62) as variant#8).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb9, unwind: bb3]; } bb11: { -- async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb10, unwind: bb3]; +- _11 = copy (_10.0: &mut AsyncInt); +- StorageLive(_8); +- _8 = async_drop_in_place::(move _11) -> [return: bb10, unwind: bb3]; + nop; + _66 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); + _17 = &mut ((*_66).1: AsyncInt); @@ -196,9 +195,9 @@ } bb12: { -- _11 = copy (_10.0: &mut AsyncInt); -- StorageLive(_8); -- _8 = async_drop_in_place::(move _11) -> [return: bb11, unwind: bb3]; +- StorageDead(_20); +- _9 = &mut ((*_3).1: AsyncInt); +- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb11, unwind: bb3]; + _52 = move _2; + goto -> bb28; } @@ -232,7 +231,7 @@ } bb17: { -- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb16, unwind: bb3, drop: bb5]; +- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb16, unwind: bb3, drop: bb8]; + StorageLive(_36); + _35 = &mut (((*_62) as variant#6).0: impl std::future::Future); + _36 = Pin::<&mut impl Future>::new_unchecked(move _35) -> [return: bb20, unwind: bb32]; @@ -255,7 +254,7 @@ } bb20: { -- async drop((*_3); poll=_20) -> [return: bb19, unwind: bb4, drop: bb9]; +- async drop((*_3); poll=_20) -> [return: bb19, unwind: bb4, drop: bb12]; + _33 = as Future>::poll(move _36, move _34) -> [return: bb19, unwind: bb2]; } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir index 89cfec6966226..132e0ab0c7f13 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir @@ -59,96 +59,96 @@ yields () } bb7: { - _5 = &mut ((*_3).3: AsyncInt); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb10, unwind: bb2]; + StorageDead(_4); + goto -> bb1; } bb8: { - StorageDead(_4); - goto -> bb1; + async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2]; } bb9: { - async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb8, unwind: bb2]; + _7 = copy (_6.0: &mut AsyncInt); + StorageLive(_4); + _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb2]; } bb10: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb9, unwind: bb2]; + _5 = &mut ((*_3).3: AsyncInt); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; } bb11: { StorageDead(_16); - drop(((*_3).2: SyncInt)) -> [return: bb7, unwind: bb4]; + drop(((*_3).2: SyncInt)) -> [return: bb10, unwind: bb4]; } bb12: { - _9 = &mut ((*_3).1: AsyncInt); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb15, unwind: bb5]; + StorageDead(_8); + goto -> bb11; } bb13: { - StorageDead(_8); - goto -> bb11; + async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb12, unwind: bb5]; } bb14: { - async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb13, unwind: bb5]; + _11 = copy (_10.0: &mut AsyncInt); + StorageLive(_8); + _8 = async_drop_in_place::(move _11) -> [return: bb13, unwind: bb5]; } bb15: { - _11 = copy (_10.0: &mut AsyncInt); - StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb14, unwind: bb5]; + _9 = &mut ((*_3).1: AsyncInt); + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb14, unwind: bb5]; } bb16: { - _13 = &mut ((*_3).3: AsyncInt); - _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb19, unwind: bb2]; + StorageDead(_12); + goto -> bb3; } bb17: { - StorageDead(_12); - goto -> bb3; + async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb16, unwind: bb2, drop: bb1]; } bb18: { - async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb17, unwind: bb2, drop: bb1]; + _15 = copy (_14.0: &mut AsyncInt); + StorageLive(_12); + _12 = async_drop_in_place::(move _15) -> [return: bb17, unwind: bb2]; } bb19: { - _15 = copy (_14.0: &mut AsyncInt); - StorageLive(_12); - _12 = async_drop_in_place::(move _15) -> [return: bb18, unwind: bb2]; + _13 = &mut ((*_3).3: AsyncInt); + _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb18, unwind: bb2]; } bb20: { - drop(((*_3).2: SyncInt)) -> [return: bb16, unwind: bb4]; + drop(((*_3).2: SyncInt)) -> [return: bb19, unwind: bb4]; } bb21: { - _17 = &mut ((*_3).1: AsyncInt); - _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb24, unwind: bb5]; + StorageDead(_16); + goto -> bb20; } bb22: { - StorageDead(_16); - goto -> bb20; + async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb21, unwind: bb5, drop: bb11]; } bb23: { - async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb22, unwind: bb5, drop: bb11]; + _19 = copy (_18.0: &mut AsyncInt); + StorageLive(_16); + _16 = async_drop_in_place::(move _19) -> [return: bb22, unwind: bb5]; } bb24: { - _19 = copy (_18.0: &mut AsyncInt); - StorageLive(_16); - _16 = async_drop_in_place::(move _19) -> [return: bb23, unwind: bb5]; + _17 = &mut ((*_3).1: AsyncInt); + _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb23, unwind: bb5]; } bb25: { _20 = &mut (*_3); - _21 = ::drop(move _20) -> [return: bb21, unwind: bb6]; + _21 = ::drop(move _20) -> [return: bb24, unwind: bb6]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff index ebb03e7fe474a..8b01104dd2256 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff @@ -80,7 +80,7 @@ bb0: { - _3 = move (_1.0: &mut SyncThenAsync); - _20 = &mut (*_3); -- _21 = ::drop(move _20) -> [return: bb15, unwind: bb5]; +- _21 = ::drop(move _20) -> [return: bb18, unwind: bb5]; + _47 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); + _46 = discriminant((*_47)); + switchInt(move _46) -> [0: bb34, 1: bb33, 2: bb32, 3: bb27, 4: bb28, 5: bb29, 6: bb30, 7: bb31, otherwise: bb17]; @@ -125,99 +125,99 @@ } bb6: { -- _5 = &mut ((*_3).3: AsyncInt); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; -+ _51 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ _13 = &mut ((*_51).3: AsyncInt); -+ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb9, unwind: bb2]; - } - - bb7: { - StorageDead(_4); + nop; goto -> bb1; } - bb8: { -- async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2]; + bb7: { +- async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2]; + _28 = move _2; + goto -> bb16; } - bb9: { + bb8: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb2]; +- _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb2]; + _15 = copy (_14.0: &mut AsyncInt); + nop; -+ (((*_47) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb8, unwind: bb2]; ++ (((*_47) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb7, unwind: bb2]; + } + + bb9: { +- _5 = &mut ((*_3).3: AsyncInt); +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; ++ _51 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ _13 = &mut ((*_51).3: AsyncInt); ++ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb8, unwind: bb2]; } bb10: { - StorageDead(_16); -- drop(((*_3).2: SyncInt)) -> [return: bb6, unwind: bb3]; +- drop(((*_3).2: SyncInt)) -> [return: bb9, unwind: bb3]; ++ nop; + _52 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ _17 = &mut ((*_52).1: AsyncInt); -+ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb13, unwind: bb4]; ++ drop(((*_52).2: SyncInt)) -> [return: bb9, unwind: bb3]; } bb11: { -- _13 = &mut ((*_3).3: AsyncInt); -- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb14, unwind: bb2]; -+ nop; -+ _53 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_53).2: SyncInt)) -> [return: bb6, unwind: bb3]; - } - - bb12: { - StorageDead(_12); - goto -> bb1; + _37 = move _2; + goto -> bb22; } - bb13: { -- async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb12, unwind: bb2, drop: bb1]; + bb12: { +- async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb11, unwind: bb2, drop: bb1]; + _19 = copy (_18.0: &mut AsyncInt); + nop; -+ (((*_47) as variant#7).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb12, unwind: bb4]; ++ (((*_47) as variant#7).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb11, unwind: bb4]; } - bb14: { + bb13: { - _15 = copy (_14.0: &mut AsyncInt); - StorageLive(_12); -- _12 = async_drop_in_place::(move _15) -> [return: bb13, unwind: bb2]; +- _12 = async_drop_in_place::(move _15) -> [return: bb12, unwind: bb2]; ++ _53 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); ++ _17 = &mut ((*_53).1: AsyncInt); ++ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb12, unwind: bb4]; + } + + bb14: { +- _13 = &mut ((*_3).3: AsyncInt); +- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb13, unwind: bb2]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb26]; } bb15: { -- _17 = &mut ((*_3).1: AsyncInt); -- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb18, unwind: bb4]; +- StorageDead(_16); +- drop(((*_3).2: SyncInt)) -> [return: bb14, unwind: bb3]; + _0 = Poll::<()>::Pending; + discriminant((*_47)) = 4; + return; } bb16: { -- StorageDead(_16); -- drop(((*_3).2: SyncInt)) -> [return: bb11, unwind: bb3]; +- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb15, unwind: bb4, drop: bb10]; + StorageLive(_30); + _29 = &mut (((*_47) as variant#5).0: impl std::future::Future); + _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb19, unwind: bb26]; } bb17: { -- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb16, unwind: bb4, drop: bb10]; +- _19 = copy (_18.0: &mut AsyncInt); +- StorageLive(_16); +- _16 = async_drop_in_place::(move _19) -> [return: bb16, unwind: bb4]; + unreachable; } bb18: { -- _19 = copy (_18.0: &mut AsyncInt); -- StorageLive(_16); -- _16 = async_drop_in_place::(move _19) -> [return: bb17, unwind: bb4]; +- _17 = &mut ((*_3).1: AsyncInt); +- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb17, unwind: bb4]; + StorageDead(_30); + _31 = discriminant(_27); -+ switchInt(move _31) -> [0: bb7, 1: bb15, otherwise: bb17]; ++ switchInt(move _31) -> [0: bb6, 1: bb15, otherwise: bb17]; + } + + bb19: { @@ -243,7 +243,7 @@ + bb23: { + StorageDead(_39); + _40 = discriminant(_36); -+ switchInt(move _40) -> [0: bb11, 1: bb21, otherwise: bb17]; ++ switchInt(move _40) -> [0: bb10, 1: bb21, otherwise: bb17]; + } + + bb24: { @@ -297,7 +297,7 @@ + (((*_47) as variant#7).0: &mut SyncThenAsync) = move ((*_47).0: &mut SyncThenAsync); + _54 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); + _20 = &mut (*_54); -+ _21 = ::drop(move _20) -> [return: bb10, unwind: bb5]; ++ _21 = ::drop(move _20) -> [return: bb13, unwind: bb5]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff index 005d204e75fa8..5d4d1f65cb552 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff @@ -40,15 +40,13 @@ _5 = AsyncInt(const 0_i32); _0 = const (); - drop(_5) -> [return: bb1, unwind: bb9, drop: bb5]; -+ _7 = &mut _5; -+ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb17, unwind: bb9]; ++ goto -> bb18; } bb1: { StorageDead(_5); - drop(_4) -> [return: bb2, unwind: bb10, drop: bb6]; -+ _11 = &mut _4; -+ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb20, unwind: bb10]; ++ goto -> bb22; } bb2: { @@ -59,8 +57,7 @@ bb3: { StorageDead(_3); - drop(_1) -> [return: bb4, drop: bb8, unwind continue]; -+ _15 = &mut _1; -+ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb23, unwind: bb12]; ++ goto -> bb26; } bb4: { @@ -142,33 +139,48 @@ + } + + bb18: { -+ StorageDead(_10); -+ goto -> bb2; ++ _7 = &mut _5; ++ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb17, unwind: bb9]; + } + + bb19: { -+ async drop(_4; poll=_10) -> [return: bb18, unwind: bb10, drop: bb6]; ++ StorageDead(_10); ++ goto -> bb2; + } + + bb20: { ++ async drop(_4; poll=_10) -> [return: bb19, unwind: bb10, drop: bb6]; ++ } ++ ++ bb21: { + _13 = copy (_12.0: &mut AsyncInt); + StorageLive(_10); -+ _10 = async_drop_in_place::(move _13) -> [return: bb19, unwind: bb10]; ++ _10 = async_drop_in_place::(move _13) -> [return: bb20, unwind: bb10]; + } + -+ bb21: { ++ bb22: { ++ _11 = &mut _4; ++ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb21, unwind: bb10]; ++ } ++ ++ bb23: { + StorageDead(_14); + goto -> bb4; + } + -+ bb22: { -+ async drop(_1; poll=_14) -> [return: bb21, unwind: bb12, drop: bb8]; ++ bb24: { ++ async drop(_1; poll=_14) -> [return: bb23, unwind: bb12, drop: bb8]; + } + -+ bb23: { ++ bb25: { + _17 = copy (_16.0: &mut {async fn body of double()}); + StorageLive(_14); -+ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb22, unwind: bb12]; ++ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb24, unwind: bb12]; ++ } ++ ++ bb26: { ++ _15 = &mut _1; ++ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb25, unwind: bb12]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff index 0495100fd3e51..30816c938635d 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff @@ -86,20 +86,17 @@ - StorageLive(_5); - _5 = AsyncInt(const 0_i32); - _0 = const (); -- _7 = &mut _5; -- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb9]; +- goto -> bb16; + _38 = copy (_1.0: &mut {async fn body of double()}); + _37 = discriminant((*_38)); -+ switchInt(move _37) -> [0: bb37, 1: bb36, 2: bb35, 3: bb31, 4: bb32, 5: bb33, 6: bb34, otherwise: bb20]; ++ switchInt(move _37) -> [0: bb40, 1: bb39, 2: bb38, 3: bb34, 4: bb35, 5: bb36, 6: bb37, otherwise: bb23]; } bb1: { - StorageDead(_5); -- _11 = &mut _4; -- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb18, unwind: bb10]; +- goto -> bb20; + nop; -+ _11 = &mut (((*_38) as variant#6).1: AsyncInt); -+ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb14, unwind: bb6]; ++ goto -> bb16; } bb2: { @@ -111,11 +108,9 @@ bb3: { - StorageDead(_3); -- _15 = &mut _1; -- _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb21, unwind: bb12]; +- goto -> bb24; + nop; -+ _15 = &mut (*_38); -+ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb17, unwind: bb8]; ++ goto -> bb20; } bb4: { @@ -155,7 +150,7 @@ + bb8 (cleanup): { StorageDead(_14); - coroutine_drop; -+ goto -> bb30; ++ goto -> bb33; } - bb9 (cleanup): { @@ -173,7 +168,7 @@ - drop(_3) -> [return: bb11, unwind terminate(cleanup)]; + bb10: { + _19 = move _2; -+ goto -> bb19; ++ goto -> bb22; } - bb11 (cleanup): { @@ -189,148 +184,169 @@ - StorageDead(_14); - resume; + bb12: { -+ nop; -+ goto -> bb2; ++ _7 = &mut (((*_38) as variant#4).2: AsyncInt); ++ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb11, unwind: bb5]; } bb13: { - StorageDead(_6); - goto -> bb1; -+ _28 = move _2; -+ goto -> bb25; ++ nop; ++ goto -> bb2; } bb14: { - async drop(_5; poll=_6) -> [return: bb13, unwind: bb9, drop: bb5]; -+ _13 = copy (_12.0: &mut AsyncInt); -+ nop; -+ (((*_38) as variant#6).2: impl std::future::Future) = async_drop_in_place::(move _13) -> [return: bb13, unwind: bb6]; ++ _28 = move _2; ++ goto -> bb28; } bb15: { - _9 = copy (_8.0: &mut AsyncInt); - StorageLive(_6); - _6 = async_drop_in_place::(move _9) -> [return: bb14, unwind: bb9]; -+ StorageDead(_14); -+ goto -> bb4; ++ _13 = copy (_12.0: &mut AsyncInt); ++ nop; ++ (((*_38) as variant#6).2: impl std::future::Future) = async_drop_in_place::(move _13) -> [return: bb14, unwind: bb6]; } bb16: { -- StorageDead(_10); -- goto -> bb2; -+ goto -> bb29; +- _7 = &mut _5; +- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb9]; ++ _11 = &mut (((*_38) as variant#6).1: AsyncInt); ++ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb15, unwind: bb6]; } bb17: { -- async drop(_4; poll=_10) -> [return: bb16, unwind: bb10, drop: bb6]; -+ _17 = copy (_16.0: &mut {async fn body of double()}); -+ StorageLive(_14); -+ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb16, unwind: bb8]; +- StorageDead(_10); +- goto -> bb2; ++ StorageDead(_14); ++ goto -> bb4; } bb18: { +- async drop(_4; poll=_10) -> [return: bb17, unwind: bb10, drop: bb6]; ++ goto -> bb32; + } + + bb19: { - _13 = copy (_12.0: &mut AsyncInt); - StorageLive(_10); -- _10 = async_drop_in_place::(move _13) -> [return: bb17, unwind: bb10]; +- _10 = async_drop_in_place::(move _13) -> [return: bb18, unwind: bb10]; ++ _17 = copy (_16.0: &mut {async fn body of double()}); ++ StorageLive(_14); ++ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb18, unwind: bb8]; + } + + bb20: { +- _11 = &mut _4; +- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb19, unwind: bb10]; ++ _15 = &mut (*_38); ++ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb19, unwind: bb8]; + } + + bb21: { +- StorageDead(_14); +- goto -> bb4; + _0 = Poll::<()>::Pending; + discriminant((*_38)) = 3; + return; } - bb19: { -- StorageDead(_14); -- goto -> bb4; + bb22: { +- async drop(_1; poll=_14) -> [return: bb21, unwind: bb12, drop: bb8]; + StorageLive(_21); + _20 = &mut (((*_38) as variant#4).3: impl std::future::Future); -+ _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb22, unwind: bb30]; ++ _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb25, unwind: bb33]; } - bb20: { -- async drop(_1; poll=_14) -> [return: bb19, unwind: bb12, drop: bb8]; + bb23: { +- _17 = copy (_16.0: &mut {async fn body of double()}); +- StorageLive(_14); +- _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb22, unwind: bb12]; + unreachable; } - bb21: { -- _17 = copy (_16.0: &mut {async fn body of double()}); -- StorageLive(_14); -- _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb20, unwind: bb12]; + bb24: { +- _15 = &mut _1; +- _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb23, unwind: bb12]; + StorageDead(_21); + _22 = discriminant(_18); -+ switchInt(move _22) -> [0: bb9, 1: bb18, otherwise: bb20]; ++ switchInt(move _22) -> [0: bb9, 1: bb21, otherwise: bb23]; + } + -+ bb22: { -+ _18 = as Future>::poll(move _21, move _19) -> [return: bb21, unwind: bb5]; ++ bb25: { ++ _18 = as Future>::poll(move _21, move _19) -> [return: bb24, unwind: bb5]; + } + -+ bb23: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb23, unwind: bb30]; ++ bb26: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb26, unwind: bb33]; + } + -+ bb24: { ++ bb27: { + _0 = Poll::<()>::Pending; + discriminant((*_38)) = 5; + return; + } + -+ bb25: { ++ bb28: { + StorageLive(_30); + _29 = &mut (((*_38) as variant#6).2: impl std::future::Future); -+ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb27, unwind: bb30]; ++ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb30, unwind: bb33]; + } + -+ bb26: { ++ bb29: { + StorageDead(_30); + _31 = discriminant(_27); -+ switchInt(move _31) -> [0: bb12, 1: bb24, otherwise: bb20]; ++ switchInt(move _31) -> [0: bb13, 1: bb27, otherwise: bb23]; + } + -+ bb27: { -+ _27 = as Future>::poll(move _30, move _28) -> [return: bb26, unwind: bb6]; ++ bb30: { ++ _27 = as Future>::poll(move _30, move _28) -> [return: bb29, unwind: bb6]; + } + -+ bb28: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb28, unwind: bb30]; ++ bb31: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb31, unwind: bb33]; + } + -+ bb29: { -+ goto -> bb15; ++ bb32: { ++ goto -> bb17; + } + -+ bb30 (cleanup): { ++ bb33 (cleanup): { + discriminant((*_38)) = 2; + resume; + } + -+ bb31: { ++ bb34: { + _19 = move _2; -+ goto -> bb19; ++ goto -> bb22; + } + -+ bb32: { ++ bb35: { + _23 = move _2; -+ goto -> bb23; ++ goto -> bb26; + } + -+ bb33: { ++ bb36: { + _28 = move _2; -+ goto -> bb25; ++ goto -> bb28; + } + -+ bb34: { ++ bb37: { + _32 = move _2; -+ goto -> bb28; ++ goto -> bb31; + } + -+ bb35: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb35, unwind continue]; ++ bb38: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb38, unwind continue]; + } + -+ bb36: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb36, unwind continue]; ++ bb39: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb39, unwind continue]; + } + -+ bb37: { ++ bb40: { + nop; + (((*_38) as variant#6).0: SyncInt) = SyncInt(const 0_i32); + nop; @@ -338,8 +354,7 @@ + nop; + (((*_38) as variant#4).2: AsyncInt) = AsyncInt(const 0_i32); + (((*_38) as variant#5).0: ()) = const (); -+ _7 = &mut (((*_38) as variant#4).2: AsyncInt); -+ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb11, unwind: bb5]; ++ goto -> bb12; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir index 64bf0bc38833b..7cd28072f1f97 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir @@ -56,14 +56,12 @@ yields () StorageLive(_5); _5 = AsyncInt(const 0_i32); _0 = const (); - _7 = &mut _5; - _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb9]; + goto -> bb16; } bb1: { StorageDead(_5); - _11 = &mut _4; - _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb18, unwind: bb10]; + goto -> bb20; } bb2: { @@ -73,8 +71,7 @@ yields () bb3: { StorageDead(_3); - _15 = &mut _1; - _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb21, unwind: bb12]; + goto -> bb24; } bb4: { @@ -132,7 +129,7 @@ yields () bb14: { _19 = move _2; - goto -> bb23; + goto -> bb26; } bb15: { @@ -142,137 +139,152 @@ yields () } bb16: { + _7 = &mut _5; + _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb9]; + } + + bb17: { StorageDead(_10); goto -> bb2; } - bb17: { + bb18: { _28 = move _2; - goto -> bb34; + goto -> bb37; } - bb18: { + bb19: { _13 = copy (_12.0: &mut AsyncInt); StorageLive(_10); - _10 = async_drop_in_place::(move _13) -> [return: bb17, unwind: bb10]; + _10 = async_drop_in_place::(move _13) -> [return: bb18, unwind: bb10]; } - bb19: { + bb20: { + _11 = &mut _4; + _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb19, unwind: bb10]; + } + + bb21: { StorageDead(_14); goto -> bb4; } - bb20: { - drop(_1) -> [return: bb19, unwind: bb12]; + bb22: { + drop(_1) -> [return: bb21, unwind: bb12]; } - bb21: { + bb23: { _17 = copy (_16.0: &mut {async fn body of double()}); StorageLive(_14); - _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb20, unwind: bb12]; + _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb22, unwind: bb12]; } - bb22: { - _19 = yield(const false) -> [resume: bb23, drop: bb28]; + bb24: { + _15 = &mut _1; + _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb23, unwind: bb12]; } - bb23: { + bb25: { + _19 = yield(const false) -> [resume: bb26, drop: bb31]; + } + + bb26: { StorageLive(_21); _20 = &mut _6; - _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb26, unwind continue]; + _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb29, unwind continue]; } - bb24: { + bb27: { unreachable; } - bb25: { + bb28: { StorageDead(_21); _22 = discriminant(_18); - switchInt(move _22) -> [0: bb13, 1: bb22, otherwise: bb24]; + switchInt(move _22) -> [0: bb13, 1: bb25, otherwise: bb27]; } - bb26: { - _18 = as Future>::poll(move _21, move _19) -> [return: bb25, unwind: bb9]; + bb29: { + _18 = as Future>::poll(move _21, move _19) -> [return: bb28, unwind: bb9]; } - bb27: { - _23 = yield(const false) -> [resume: bb32, drop: bb28]; + bb30: { + _23 = yield(const false) -> [resume: bb35, drop: bb31]; } - bb28: { + bb31: { StorageLive(_25); _24 = &mut _6; - _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb31, unwind continue]; + _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb34, unwind continue]; } - bb29: { + bb32: { unreachable; } - bb30: { + bb33: { StorageDead(_25); _26 = discriminant(_18); - switchInt(move _26) -> [0: bb5, 1: bb27, otherwise: bb29]; + switchInt(move _26) -> [0: bb5, 1: bb30, otherwise: bb32]; } - bb31: { - _18 = as Future>::poll(move _25, move _23) -> [return: bb30, unwind: bb9]; + bb34: { + _18 = as Future>::poll(move _25, move _23) -> [return: bb33, unwind: bb9]; } - bb32: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb32, unwind continue]; + bb35: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb35, unwind continue]; } - bb33: { - _28 = yield(const false) -> [resume: bb34, drop: bb39]; + bb36: { + _28 = yield(const false) -> [resume: bb37, drop: bb42]; } - bb34: { + bb37: { StorageLive(_30); _29 = &mut _10; - _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb37, unwind continue]; + _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb40, unwind continue]; } - bb35: { + bb38: { unreachable; } - bb36: { + bb39: { StorageDead(_30); _31 = discriminant(_27); - switchInt(move _31) -> [0: bb16, 1: bb33, otherwise: bb35]; + switchInt(move _31) -> [0: bb17, 1: bb36, otherwise: bb38]; } - bb37: { - _27 = as Future>::poll(move _30, move _28) -> [return: bb36, unwind: bb10]; + bb40: { + _27 = as Future>::poll(move _30, move _28) -> [return: bb39, unwind: bb10]; } - bb38: { - _32 = yield(const false) -> [resume: bb43, drop: bb39]; + bb41: { + _32 = yield(const false) -> [resume: bb46, drop: bb42]; } - bb39: { + bb42: { StorageLive(_34); _33 = &mut _10; - _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb42, unwind continue]; + _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb45, unwind continue]; } - bb40: { + bb43: { unreachable; } - bb41: { + bb44: { StorageDead(_34); _35 = discriminant(_27); - switchInt(move _35) -> [0: bb6, 1: bb38, otherwise: bb40]; + switchInt(move _35) -> [0: bb6, 1: bb41, otherwise: bb43]; } - bb42: { - _27 = as Future>::poll(move _34, move _32) -> [return: bb41, unwind: bb10]; + bb45: { + _27 = as Future>::poll(move _34, move _32) -> [return: bb44, unwind: bb10]; } - bb43: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb43, unwind continue]; + bb46: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb46, unwind continue]; } } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff index 936543ef54f7e..8505963eb373e 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff @@ -215,8 +215,7 @@ _26 = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; _0 = const (); - drop(_26) -> [return: bb10, unwind: bb44, drop: bb23]; -+ _28 = &mut _26; -+ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb85, unwind: bb44]; ++ goto -> bb86; } bb10: { @@ -228,8 +227,7 @@ bb11: { StorageDead(_25); - drop(_24) -> [return: bb12, unwind: bb46, drop: bb25]; -+ _32 = &mut _24; -+ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb88, unwind: bb46]; ++ goto -> bb90; } bb12: { @@ -241,51 +239,44 @@ bb13: { StorageDead(_23); - drop(_20) -> [return: bb14, unwind: bb48, drop: bb27]; -+ _36 = &mut _20; -+ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb91, unwind: bb48]; ++ goto -> bb94; } bb14: { StorageDead(_20); - drop(_19) -> [return: bb15, unwind: bb49, drop: bb28]; -+ _40 = &mut _19; -+ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb94, unwind: bb49]; ++ goto -> bb98; } bb15: { StorageDead(_19); StorageDead(_17); - drop(_15) -> [return: bb16, unwind: bb54, drop: bb30]; -+ _44 = &mut _15; -+ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb97, unwind: bb54]; ++ goto -> bb102; } bb16: { StorageDead(_15); - drop(_11) -> [return: bb17, unwind: bb58, drop: bb34]; -+ _48 = &mut _11; -+ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb100, unwind: bb58]; ++ goto -> bb106; } bb17: { StorageDead(_11); - drop(_8) -> [return: bb18, unwind: bb61, drop: bb37]; -+ _52 = &mut _8; -+ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb103, unwind: bb61]; ++ goto -> bb110; } bb18: { StorageDead(_8); - drop(_5) -> [return: bb19, unwind: bb64, drop: bb40]; -+ _56 = &mut _5; -+ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb106, unwind: bb64]; ++ goto -> bb114; } bb19: { StorageDead(_5); - drop(_4) -> [return: bb20, unwind: bb65, drop: bb41]; -+ _60 = &mut _4; -+ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb109, unwind: bb65]; ++ goto -> bb118; } bb20: { @@ -296,8 +287,7 @@ bb21: { StorageDead(_3); - drop(_1) -> [return: bb22, drop: bb43, unwind continue]; -+ _64 = &mut _1; -+ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb112, unwind: bb67]; ++ goto -> bb122; } bb22: { @@ -674,138 +664,188 @@ + } + + bb86: { -+ StorageDead(_31); -+ goto -> bb12; ++ _28 = &mut _26; ++ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb85, unwind: bb44]; + } + + bb87: { -+ async drop(_24; poll=_31) -> [return: bb86, unwind: bb46, drop: bb25]; ++ StorageDead(_31); ++ goto -> bb12; + } + + bb88: { ++ async drop(_24; poll=_31) -> [return: bb87, unwind: bb46, drop: bb25]; ++ } ++ ++ bb89: { + _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); + StorageLive(_31); -+ _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb87, unwind: bb46]; ++ _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb88, unwind: bb46]; + } + -+ bb89: { ++ bb90: { ++ _32 = &mut _24; ++ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb89, unwind: bb46]; ++ } ++ ++ bb91: { + StorageDead(_35); + goto -> bb14; + } + -+ bb90: { -+ async drop(_20; poll=_35) -> [return: bb89, unwind: bb48, drop: bb27]; ++ bb92: { ++ async drop(_20; poll=_35) -> [return: bb91, unwind: bb48, drop: bb27]; + } + -+ bb91: { ++ bb93: { + _38 = copy (_37.0: &mut AsyncReference<'_>); + StorageLive(_35); -+ _35 = async_drop_in_place::>(move _38) -> [return: bb90, unwind: bb48]; ++ _35 = async_drop_in_place::>(move _38) -> [return: bb92, unwind: bb48]; + } + -+ bb92: { ++ bb94: { ++ _36 = &mut _20; ++ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb93, unwind: bb48]; ++ } ++ ++ bb95: { + StorageDead(_39); + goto -> bb15; + } + -+ bb93: { -+ async drop(_19; poll=_39) -> [return: bb92, unwind: bb49, drop: bb28]; ++ bb96: { ++ async drop(_19; poll=_39) -> [return: bb95, unwind: bb49, drop: bb28]; + } + -+ bb94: { ++ bb97: { + _42 = copy (_41.0: &mut AsyncInt); + StorageLive(_39); -+ _39 = async_drop_in_place::(move _42) -> [return: bb93, unwind: bb49]; ++ _39 = async_drop_in_place::(move _42) -> [return: bb96, unwind: bb49]; + } + -+ bb95: { ++ bb98: { ++ _40 = &mut _19; ++ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb97, unwind: bb49]; ++ } ++ ++ bb99: { + StorageDead(_43); + goto -> bb16; + } + -+ bb96: { -+ async drop(_15; poll=_43) -> [return: bb95, unwind: bb54, drop: bb30]; ++ bb100: { ++ async drop(_15; poll=_43) -> [return: bb99, unwind: bb54, drop: bb30]; + } + -+ bb97: { ++ bb101: { + _46 = copy (_45.0: &mut AsyncEnum); + StorageLive(_43); -+ _43 = async_drop_in_place::(move _46) -> [return: bb96, unwind: bb54]; ++ _43 = async_drop_in_place::(move _46) -> [return: bb100, unwind: bb54]; + } + -+ bb98: { ++ bb102: { ++ _44 = &mut _15; ++ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb101, unwind: bb54]; ++ } ++ ++ bb103: { + StorageDead(_47); + goto -> bb17; + } + -+ bb99: { -+ async drop(_11; poll=_47) -> [return: bb98, unwind: bb58, drop: bb34]; ++ bb104: { ++ async drop(_11; poll=_47) -> [return: bb103, unwind: bb58, drop: bb34]; + } + -+ bb100: { ++ bb105: { + _50 = copy (_49.0: &mut SyncThenAsync); + StorageLive(_47); -+ _47 = async_drop_in_place::(move _50) -> [return: bb99, unwind: bb58]; ++ _47 = async_drop_in_place::(move _50) -> [return: bb104, unwind: bb58]; + } + -+ bb101: { ++ bb106: { ++ _48 = &mut _11; ++ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb105, unwind: bb58]; ++ } ++ ++ bb107: { + StorageDead(_51); + goto -> bb18; + } + -+ bb102: { -+ async drop(_8; poll=_51) -> [return: bb101, unwind: bb61, drop: bb37]; ++ bb108: { ++ async drop(_8; poll=_51) -> [return: bb107, unwind: bb61, drop: bb37]; + } + -+ bb103: { ++ bb109: { + _54 = copy (_53.0: &mut AsyncStruct); + StorageLive(_51); -+ _51 = async_drop_in_place::(move _54) -> [return: bb102, unwind: bb61]; ++ _51 = async_drop_in_place::(move _54) -> [return: bb108, unwind: bb61]; + } + -+ bb104: { ++ bb110: { ++ _52 = &mut _8; ++ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb109, unwind: bb61]; ++ } ++ ++ bb111: { + StorageDead(_55); + goto -> bb19; + } + -+ bb105: { -+ async drop(_5; poll=_55) -> [return: bb104, unwind: bb64, drop: bb40]; ++ bb112: { ++ async drop(_5; poll=_55) -> [return: bb111, unwind: bb64, drop: bb40]; + } + -+ bb106: { ++ bb113: { + _58 = copy (_57.0: &mut [AsyncInt; 2]); + StorageLive(_55); -+ _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb105, unwind: bb64]; ++ _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb112, unwind: bb64]; + } + -+ bb107: { ++ bb114: { ++ _56 = &mut _5; ++ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb113, unwind: bb64]; ++ } ++ ++ bb115: { + StorageDead(_59); + goto -> bb20; + } + -+ bb108: { -+ async drop(_4; poll=_59) -> [return: bb107, unwind: bb65, drop: bb41]; ++ bb116: { ++ async drop(_4; poll=_59) -> [return: bb115, unwind: bb65, drop: bb41]; + } + -+ bb109: { ++ bb117: { + _62 = copy (_61.0: &mut AsyncInt); + StorageLive(_59); -+ _59 = async_drop_in_place::(move _62) -> [return: bb108, unwind: bb65]; ++ _59 = async_drop_in_place::(move _62) -> [return: bb116, unwind: bb65]; + } + -+ bb110: { ++ bb118: { ++ _60 = &mut _4; ++ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb117, unwind: bb65]; ++ } ++ ++ bb119: { + StorageDead(_63); + goto -> bb22; + } + -+ bb111: { -+ async drop(_1; poll=_63) -> [return: bb110, unwind: bb67, drop: bb43]; ++ bb120: { ++ async drop(_1; poll=_63) -> [return: bb119, unwind: bb67, drop: bb43]; + } + -+ bb112: { ++ bb121: { + _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); + StorageLive(_63); -+ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb111, unwind: bb67]; ++ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb120, unwind: bb67]; ++ } ++ ++ bb122: { ++ _64 = &mut _1; ++ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb121, unwind: bb67]; } } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff index a1fc27c9783b2..f2e670df1964f 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff @@ -276,7 +276,7 @@ - goto -> bb1; + _150 = copy (_1.0: &mut {async fn body of elaborate_drops()}); + _149 = discriminant((*_150)); -+ switchInt(move _149) -> [0: bb137, 1: bb136, 2: bb135, 3: bb117, 4: bb118, 5: bb119, 6: bb120, 7: bb121, 8: bb122, 9: bb123, 10: bb124, 11: bb125, 12: bb126, 13: bb127, 14: bb128, 15: bb129, 16: bb130, 17: bb131, 18: bb132, 19: bb133, 20: bb134, otherwise: bb71]; ++ switchInt(move _149) -> [0: bb147, 1: bb146, 2: bb145, 3: bb127, 4: bb128, 5: bb129, 6: bb130, 7: bb131, 8: bb132, 9: bb133, 10: bb134, 11: bb135, 12: bb136, 13: bb137, 14: bb138, 15: bb139, 16: bb140, 17: bb141, 18: bb142, 19: bb143, 20: bb144, otherwise: bb81]; } bb1: { @@ -375,13 +375,11 @@ - StorageLive(_26); - _26 = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; - _0 = const (); -- _28 = &mut _26; -- _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb54, unwind: bb36]; +- goto -> bb55; + nop; + (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}) = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; + (((*_150) as variant#19).0: ()) = const (); -+ _28 = &mut (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); -+ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb41, unwind: bb23]; ++ goto -> bb42; } bb10: { @@ -392,10 +390,8 @@ bb11: { StorageDead(_25); -- _32 = &mut _24; -- _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb57, unwind: bb38]; -+ _32 = &mut (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); -+ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb44, unwind: bb25]; +- goto -> bb59; ++ goto -> bb46; } bb12: { @@ -406,65 +402,51 @@ bb13: { StorageDead(_23); -- _36 = &mut _20; -- _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb60, unwind: bb40]; -+ _36 = &mut (((*_150) as variant#8).7: AsyncReference<'_>); -+ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb47, unwind: bb27]; +- goto -> bb63; ++ goto -> bb50; } bb14: { - StorageDead(_20); -- _40 = &mut _19; -- _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb63, unwind: bb41]; +- goto -> bb67; + nop; -+ _40 = &mut (((*_150) as variant#10).6: AsyncInt); -+ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb50, unwind: bb28]; ++ goto -> bb54; } bb15: { - StorageDead(_19); + nop; StorageDead(_17); -- _44 = &mut _15; -- _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb66, unwind: bb45]; -+ _44 = &mut (((*_150) as variant#12).5: AsyncEnum); -+ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb53, unwind: bb32]; +- goto -> bb71; ++ goto -> bb58; } bb16: { - StorageDead(_15); -- _48 = &mut _11; -- _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb69, unwind: bb46]; +- goto -> bb75; + nop; -+ _48 = &mut (((*_150) as variant#14).4: SyncThenAsync); -+ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb56, unwind: bb33]; ++ goto -> bb62; } bb17: { - StorageDead(_11); -- _52 = &mut _8; -- _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb72, unwind: bb47]; +- goto -> bb79; + nop; -+ _52 = &mut (((*_150) as variant#16).3: AsyncStruct); -+ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb59, unwind: bb34]; ++ goto -> bb66; } bb18: { - StorageDead(_8); -- _56 = &mut _5; -- _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb75, unwind: bb48]; +- goto -> bb83; + nop; -+ _56 = &mut (((*_150) as variant#18).2: [AsyncInt; 2]); -+ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb62, unwind: bb35]; ++ goto -> bb70; } bb19: { - StorageDead(_5); -- _60 = &mut _4; -- _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb78, unwind: bb49]; +- goto -> bb87; + nop; -+ _60 = &mut (((*_150) as variant#20).1: AsyncInt); -+ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb65, unwind: bb36]; ++ goto -> bb74; } bb20: { @@ -476,11 +458,9 @@ bb21: { - StorageDead(_3); -- _64 = &mut _1; -- _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb81, unwind: bb51]; +- goto -> bb91; + nop; -+ _64 = &mut (*_150); -+ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb68, unwind: bb38]; ++ goto -> bb78; } bb22: { @@ -625,7 +605,7 @@ - StorageDead(_24); - goto -> bb39; + StorageDead(_63); -+ goto -> bb116; ++ goto -> bb126; } - bb39 (cleanup): { @@ -642,7 +622,7 @@ - drop(_19) -> [return: bb41, unwind terminate(cleanup)]; + bb40: { + _68 = move _2; -+ goto -> bb70; ++ goto -> bb80; } - bb41 (cleanup): { @@ -658,25 +638,24 @@ - bb42 (cleanup): { - goto -> bb43; + bb42: { -+ nop; -+ goto -> bb12; ++ _28 = &mut (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb41, unwind: bb23]; } - bb43 (cleanup): { - StorageDead(_18); - goto -> bb44; + bb43: { -+ _77 = move _2; -+ goto -> bb76; ++ nop; ++ goto -> bb12; } - bb44 (cleanup): { - StorageDead(_17); - drop(_15) -> [return: bb45, unwind terminate(cleanup)]; + bb44: { -+ _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); -+ nop; -+ (((*_150) as variant#6).9: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb43, unwind: bb25]; ++ _77 = move _2; ++ goto -> bb86; } - bb45 (cleanup): { @@ -684,8 +663,9 @@ - StorageDead(_15); - drop(_11) -> [return: bb46, unwind terminate(cleanup)]; + bb45: { ++ _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); + nop; -+ goto -> bb14; ++ (((*_150) as variant#6).9: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb44, unwind: bb25]; } - bb46 (cleanup): { @@ -693,8 +673,8 @@ - StorageDead(_11); - drop(_8) -> [return: bb47, unwind terminate(cleanup)]; + bb46: { -+ _86 = move _2; -+ goto -> bb81; ++ _32 = &mut (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); ++ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb45, unwind: bb25]; } - bb47 (cleanup): { @@ -702,9 +682,8 @@ - StorageDead(_8); - drop(_5) -> [return: bb48, unwind terminate(cleanup)]; + bb47: { -+ _38 = copy (_37.0: &mut AsyncReference<'_>); + nop; -+ (((*_150) as variant#8).8: impl std::future::Future) = async_drop_in_place::>(move _38) -> [return: bb46, unwind: bb27]; ++ goto -> bb14; } - bb48 (cleanup): { @@ -712,8 +691,8 @@ - StorageDead(_5); - drop(_4) -> [return: bb49, unwind terminate(cleanup)]; + bb48: { -+ nop; -+ goto -> bb15; ++ _86 = move _2; ++ goto -> bb91; } - bb49 (cleanup): { @@ -721,17 +700,17 @@ - StorageDead(_4); - drop(_3) -> [return: bb50, unwind terminate(cleanup)]; + bb49: { -+ _95 = move _2; -+ goto -> bb86; ++ _38 = copy (_37.0: &mut AsyncReference<'_>); ++ nop; ++ (((*_150) as variant#8).8: impl std::future::Future) = async_drop_in_place::>(move _38) -> [return: bb48, unwind: bb27]; } - bb50 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb51, unwind terminate(cleanup)]; + bb50: { -+ _42 = copy (_41.0: &mut AsyncInt); -+ nop; -+ (((*_150) as variant#10).7: impl std::future::Future) = async_drop_in_place::(move _42) -> [return: bb49, unwind: bb28]; ++ _36 = &mut (((*_150) as variant#8).7: AsyncReference<'_>); ++ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb49, unwind: bb27]; } - bb51 (cleanup): { @@ -739,136 +718,207 @@ - resume; + bb51: { + nop; -+ goto -> bb16; ++ goto -> bb15; } bb52: { - StorageDead(_27); - goto -> bb10; -+ _104 = move _2; -+ goto -> bb91; ++ _95 = move _2; ++ goto -> bb96; } bb53: { - async drop(_26; poll=_27) -> [return: bb52, unwind: bb36, drop: bb23]; -+ _46 = copy (_45.0: &mut AsyncEnum); ++ _42 = copy (_41.0: &mut AsyncInt); + nop; -+ (((*_150) as variant#12).6: impl std::future::Future) = async_drop_in_place::(move _46) -> [return: bb52, unwind: bb32]; ++ (((*_150) as variant#10).7: impl std::future::Future) = async_drop_in_place::(move _42) -> [return: bb52, unwind: bb28]; } bb54: { - _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); - StorageLive(_27); - _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb53, unwind: bb36]; -+ nop; -+ goto -> bb17; ++ _40 = &mut (((*_150) as variant#10).6: AsyncInt); ++ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb53, unwind: bb28]; } bb55: { +- _28 = &mut _26; +- _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb54, unwind: bb36]; ++ nop; ++ goto -> bb16; + } + + bb56: { - StorageDead(_31); - goto -> bb12; -+ _113 = move _2; -+ goto -> bb96; ++ _104 = move _2; ++ goto -> bb101; } - bb56: { -- async drop(_24; poll=_31) -> [return: bb55, unwind: bb38, drop: bb25]; -+ _50 = copy (_49.0: &mut SyncThenAsync); + bb57: { +- async drop(_24; poll=_31) -> [return: bb56, unwind: bb38, drop: bb25]; ++ _46 = copy (_45.0: &mut AsyncEnum); + nop; -+ (((*_150) as variant#14).5: impl std::future::Future) = async_drop_in_place::(move _50) -> [return: bb55, unwind: bb33]; ++ (((*_150) as variant#12).6: impl std::future::Future) = async_drop_in_place::(move _46) -> [return: bb56, unwind: bb32]; } - bb57: { + bb58: { - _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); - StorageLive(_31); -- _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb56, unwind: bb38]; +- _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb57, unwind: bb38]; ++ _44 = &mut (((*_150) as variant#12).5: AsyncEnum); ++ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb57, unwind: bb32]; + } + + bb59: { +- _32 = &mut _24; +- _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb58, unwind: bb38]; + nop; -+ goto -> bb18; ++ goto -> bb17; } - bb58: { + bb60: { - StorageDead(_35); - goto -> bb14; -+ _122 = move _2; -+ goto -> bb101; ++ _113 = move _2; ++ goto -> bb106; } - bb59: { -- async drop(_20; poll=_35) -> [return: bb58, unwind: bb40, drop: bb27]; -+ _54 = copy (_53.0: &mut AsyncStruct); + bb61: { +- async drop(_20; poll=_35) -> [return: bb60, unwind: bb40, drop: bb27]; ++ _50 = copy (_49.0: &mut SyncThenAsync); + nop; -+ (((*_150) as variant#16).4: impl std::future::Future) = async_drop_in_place::(move _54) -> [return: bb58, unwind: bb34]; ++ (((*_150) as variant#14).5: impl std::future::Future) = async_drop_in_place::(move _50) -> [return: bb60, unwind: bb33]; } - bb60: { + bb62: { - _38 = copy (_37.0: &mut AsyncReference<'_>); - StorageLive(_35); -- _35 = async_drop_in_place::>(move _38) -> [return: bb59, unwind: bb40]; +- _35 = async_drop_in_place::>(move _38) -> [return: bb61, unwind: bb40]; ++ _48 = &mut (((*_150) as variant#14).4: SyncThenAsync); ++ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb61, unwind: bb33]; + } + + bb63: { +- _36 = &mut _20; +- _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb62, unwind: bb40]; + nop; -+ goto -> bb19; ++ goto -> bb18; } - bb61: { + bb64: { - StorageDead(_39); - goto -> bb15; -+ _131 = move _2; -+ goto -> bb106; ++ _122 = move _2; ++ goto -> bb111; } - bb62: { -- async drop(_19; poll=_39) -> [return: bb61, unwind: bb41, drop: bb28]; -+ _58 = copy (_57.0: &mut [AsyncInt; 2]); + bb65: { +- async drop(_19; poll=_39) -> [return: bb64, unwind: bb41, drop: bb28]; ++ _54 = copy (_53.0: &mut AsyncStruct); + nop; -+ (((*_150) as variant#18).3: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb61, unwind: bb35]; ++ (((*_150) as variant#16).4: impl std::future::Future) = async_drop_in_place::(move _54) -> [return: bb64, unwind: bb34]; } - bb63: { + bb66: { - _42 = copy (_41.0: &mut AsyncInt); - StorageLive(_39); -- _39 = async_drop_in_place::(move _42) -> [return: bb62, unwind: bb41]; +- _39 = async_drop_in_place::(move _42) -> [return: bb65, unwind: bb41]; ++ _52 = &mut (((*_150) as variant#16).3: AsyncStruct); ++ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb65, unwind: bb34]; + } + + bb67: { +- _40 = &mut _19; +- _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb66, unwind: bb41]; + nop; -+ goto -> bb20; ++ goto -> bb19; } - bb64: { + bb68: { - StorageDead(_43); - goto -> bb16; -+ _140 = move _2; -+ goto -> bb111; ++ _131 = move _2; ++ goto -> bb116; } - bb65: { -- async drop(_15; poll=_43) -> [return: bb64, unwind: bb45, drop: bb29]; -+ _62 = copy (_61.0: &mut AsyncInt); + bb69: { +- async drop(_15; poll=_43) -> [return: bb68, unwind: bb45, drop: bb29]; ++ _58 = copy (_57.0: &mut [AsyncInt; 2]); + nop; -+ (((*_150) as variant#20).2: impl std::future::Future) = async_drop_in_place::(move _62) -> [return: bb64, unwind: bb36]; ++ (((*_150) as variant#18).3: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb68, unwind: bb35]; } - bb66: { + bb70: { - _46 = copy (_45.0: &mut AsyncEnum); - StorageLive(_43); -- _43 = async_drop_in_place::(move _46) -> [return: bb65, unwind: bb45]; -+ StorageDead(_63); -+ goto -> bb22; +- _43 = async_drop_in_place::(move _46) -> [return: bb69, unwind: bb45]; ++ _56 = &mut (((*_150) as variant#18).2: [AsyncInt; 2]); ++ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb69, unwind: bb35]; } - bb67: { + bb71: { +- _44 = &mut _15; +- _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb70, unwind: bb45]; ++ nop; ++ goto -> bb20; + } + + bb72: { - StorageDead(_47); - goto -> bb17; -+ goto -> bb115; ++ _140 = move _2; ++ goto -> bb121; } - bb68: { -- async drop(_11; poll=_47) -> [return: bb67, unwind: bb46, drop: bb30]; -+ _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); -+ StorageLive(_63); -+ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb67, unwind: bb38]; + bb73: { +- async drop(_11; poll=_47) -> [return: bb72, unwind: bb46, drop: bb30]; ++ _62 = copy (_61.0: &mut AsyncInt); ++ nop; ++ (((*_150) as variant#20).2: impl std::future::Future) = async_drop_in_place::(move _62) -> [return: bb72, unwind: bb36]; } - bb69: { + bb74: { - _50 = copy (_49.0: &mut SyncThenAsync); - StorageLive(_47); -- _47 = async_drop_in_place::(move _50) -> [return: bb68, unwind: bb46]; +- _47 = async_drop_in_place::(move _50) -> [return: bb73, unwind: bb46]; ++ _60 = &mut (((*_150) as variant#20).1: AsyncInt); ++ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb73, unwind: bb36]; + } + + bb75: { +- _48 = &mut _11; +- _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb74, unwind: bb46]; ++ StorageDead(_63); ++ goto -> bb22; + } + + bb76: { +- StorageDead(_51); +- goto -> bb18; ++ goto -> bb125; + } + + bb77: { +- async drop(_8; poll=_51) -> [return: bb76, unwind: bb47, drop: bb31]; ++ _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); ++ StorageLive(_63); ++ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb76, unwind: bb38]; + } + + bb78: { +- _54 = copy (_53.0: &mut AsyncStruct); +- StorageLive(_51); +- _51 = async_drop_in_place::(move _54) -> [return: bb77, unwind: bb47]; ++ _64 = &mut (*_150); ++ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb77, unwind: bb38]; + } + + bb79: { +- _52 = &mut _8; +- _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb78, unwind: bb47]; + _0 = Poll::<()>::Pending; + StorageDead(_17); + StorageDead(_23); @@ -877,43 +927,42 @@ + return; } - bb70: { -- StorageDead(_51); -- goto -> bb18; + bb80: { +- StorageDead(_55); +- goto -> bb19; + StorageLive(_70); + _69 = &mut (((*_150) as variant#4).10: impl std::future::Future); -+ _70 = Pin::<&mut impl Future>::new_unchecked(move _69) -> [return: bb73, unwind: bb116]; ++ _70 = Pin::<&mut impl Future>::new_unchecked(move _69) -> [return: bb83, unwind: bb126]; } - bb71: { -- async drop(_8; poll=_51) -> [return: bb70, unwind: bb47, drop: bb31]; + bb81: { +- async drop(_5; poll=_55) -> [return: bb80, unwind: bb48, drop: bb32]; + unreachable; } - bb72: { -- _54 = copy (_53.0: &mut AsyncStruct); -- StorageLive(_51); -- _51 = async_drop_in_place::(move _54) -> [return: bb71, unwind: bb47]; + bb82: { +- _58 = copy (_57.0: &mut [AsyncInt; 2]); +- StorageLive(_55); +- _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb81, unwind: bb48]; + StorageDead(_70); + _71 = discriminant(_67); -+ switchInt(move _71) -> [0: bb39, 1: bb69, otherwise: bb71]; ++ switchInt(move _71) -> [0: bb39, 1: bb79, otherwise: bb81]; } - bb73: { -- StorageDead(_55); -- goto -> bb19; -+ _67 = as Future>::poll(move _70, move _68) -> [return: bb72, unwind: bb23]; + bb83: { +- _56 = &mut _5; +- _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb82, unwind: bb48]; ++ _67 = as Future>::poll(move _70, move _68) -> [return: bb82, unwind: bb23]; } - bb74: { -- async drop(_5; poll=_55) -> [return: bb73, unwind: bb48, drop: bb32]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb74, unwind: bb116]; + bb84: { +- StorageDead(_59); +- goto -> bb20; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb84, unwind: bb126]; } - bb75: { -- _58 = copy (_57.0: &mut [AsyncInt; 2]); -- StorageLive(_55); -- _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb74, unwind: bb48]; + bb85: { +- async drop(_4; poll=_59) -> [return: bb84, unwind: bb49, drop: bb33]; + _0 = Poll::<()>::Pending; + StorageDead(_17); + StorageDead(_23); @@ -921,344 +970,345 @@ + return; } - bb76: { -- StorageDead(_59); -- goto -> bb20; + bb86: { +- _62 = copy (_61.0: &mut AsyncInt); +- StorageLive(_59); +- _59 = async_drop_in_place::(move _62) -> [return: bb85, unwind: bb49]; + StorageLive(_79); + _78 = &mut (((*_150) as variant#6).9: impl std::future::Future); -+ _79 = Pin::<&mut impl Future>::new_unchecked(move _78) -> [return: bb78, unwind: bb116]; ++ _79 = Pin::<&mut impl Future>::new_unchecked(move _78) -> [return: bb88, unwind: bb126]; } - bb77: { -- async drop(_4; poll=_59) -> [return: bb76, unwind: bb49, drop: bb33]; + bb87: { +- _60 = &mut _4; +- _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb86, unwind: bb49]; + StorageDead(_79); + _80 = discriminant(_76); -+ switchInt(move _80) -> [0: bb42, 1: bb75, otherwise: bb71]; - } - - bb78: { -- _62 = copy (_61.0: &mut AsyncInt); -- StorageLive(_59); -- _59 = async_drop_in_place::(move _62) -> [return: bb77, unwind: bb49]; -+ _76 = as Future>::poll(move _79, move _77) -> [return: bb77, unwind: bb25]; ++ switchInt(move _80) -> [0: bb43, 1: bb85, otherwise: bb81]; } - bb79: { + bb88: { - StorageDead(_63); - goto -> bb22; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb79, unwind: bb116]; ++ _76 = as Future>::poll(move _79, move _77) -> [return: bb87, unwind: bb25]; } - bb80: { -- async drop(_1; poll=_63) -> [return: bb79, unwind: bb51, drop: bb35]; + bb89: { +- async drop(_1; poll=_63) -> [return: bb88, unwind: bb51, drop: bb35]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb89, unwind: bb126]; + } + + bb90: { +- _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); +- StorageLive(_63); +- _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb89, unwind: bb51]; + _0 = Poll::<()>::Pending; + StorageDead(_17); + discriminant((*_150)) = 7; + return; } - bb81: { -- _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); -- StorageLive(_63); -- _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb80, unwind: bb51]; + bb91: { +- _64 = &mut _1; +- _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb90, unwind: bb51]; + StorageLive(_88); + _87 = &mut (((*_150) as variant#8).8: impl std::future::Future); -+ _88 = Pin::<&mut impl Future>::new_unchecked(move _87) -> [return: bb83, unwind: bb116]; ++ _88 = Pin::<&mut impl Future>::new_unchecked(move _87) -> [return: bb93, unwind: bb126]; + } + -+ bb82: { ++ bb92: { + StorageDead(_88); + _89 = discriminant(_85); -+ switchInt(move _89) -> [0: bb45, 1: bb80, otherwise: bb71]; ++ switchInt(move _89) -> [0: bb47, 1: bb90, otherwise: bb81]; + } + -+ bb83: { -+ _85 = as Future>::poll(move _88, move _86) -> [return: bb82, unwind: bb27]; ++ bb93: { ++ _85 = as Future>::poll(move _88, move _86) -> [return: bb92, unwind: bb27]; + } + -+ bb84: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb84, unwind: bb116]; ++ bb94: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb94, unwind: bb126]; + } + -+ bb85: { ++ bb95: { + _0 = Poll::<()>::Pending; + StorageDead(_17); + discriminant((*_150)) = 9; + return; + } + -+ bb86: { ++ bb96: { + StorageLive(_97); + _96 = &mut (((*_150) as variant#10).7: impl std::future::Future); -+ _97 = Pin::<&mut impl Future>::new_unchecked(move _96) -> [return: bb88, unwind: bb116]; ++ _97 = Pin::<&mut impl Future>::new_unchecked(move _96) -> [return: bb98, unwind: bb126]; + } + -+ bb87: { ++ bb97: { + StorageDead(_97); + _98 = discriminant(_94); -+ switchInt(move _98) -> [0: bb48, 1: bb85, otherwise: bb71]; ++ switchInt(move _98) -> [0: bb51, 1: bb95, otherwise: bb81]; + } + -+ bb88: { -+ _94 = as Future>::poll(move _97, move _95) -> [return: bb87, unwind: bb28]; ++ bb98: { ++ _94 = as Future>::poll(move _97, move _95) -> [return: bb97, unwind: bb28]; + } + -+ bb89: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb89, unwind: bb116]; ++ bb99: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb99, unwind: bb126]; + } + -+ bb90: { ++ bb100: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 11; + return; + } + -+ bb91: { ++ bb101: { + StorageLive(_106); + _105 = &mut (((*_150) as variant#12).6: impl std::future::Future); -+ _106 = Pin::<&mut impl Future>::new_unchecked(move _105) -> [return: bb93, unwind: bb116]; ++ _106 = Pin::<&mut impl Future>::new_unchecked(move _105) -> [return: bb103, unwind: bb126]; + } + -+ bb92: { ++ bb102: { + StorageDead(_106); + _107 = discriminant(_103); -+ switchInt(move _107) -> [0: bb51, 1: bb90, otherwise: bb71]; ++ switchInt(move _107) -> [0: bb55, 1: bb100, otherwise: bb81]; + } + -+ bb93: { -+ _103 = as Future>::poll(move _106, move _104) -> [return: bb92, unwind: bb32]; ++ bb103: { ++ _103 = as Future>::poll(move _106, move _104) -> [return: bb102, unwind: bb32]; + } + -+ bb94: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb94, unwind: bb116]; ++ bb104: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb104, unwind: bb126]; + } + -+ bb95: { ++ bb105: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 13; + return; + } + -+ bb96: { ++ bb106: { + StorageLive(_115); + _114 = &mut (((*_150) as variant#14).5: impl std::future::Future); -+ _115 = Pin::<&mut impl Future>::new_unchecked(move _114) -> [return: bb98, unwind: bb116]; ++ _115 = Pin::<&mut impl Future>::new_unchecked(move _114) -> [return: bb108, unwind: bb126]; + } + -+ bb97: { ++ bb107: { + StorageDead(_115); + _116 = discriminant(_112); -+ switchInt(move _116) -> [0: bb54, 1: bb95, otherwise: bb71]; ++ switchInt(move _116) -> [0: bb59, 1: bb105, otherwise: bb81]; + } + -+ bb98: { -+ _112 = as Future>::poll(move _115, move _113) -> [return: bb97, unwind: bb33]; ++ bb108: { ++ _112 = as Future>::poll(move _115, move _113) -> [return: bb107, unwind: bb33]; + } + -+ bb99: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb99, unwind: bb116]; ++ bb109: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb109, unwind: bb126]; + } + -+ bb100: { ++ bb110: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 15; + return; + } + -+ bb101: { ++ bb111: { + StorageLive(_124); + _123 = &mut (((*_150) as variant#16).4: impl std::future::Future); -+ _124 = Pin::<&mut impl Future>::new_unchecked(move _123) -> [return: bb103, unwind: bb116]; ++ _124 = Pin::<&mut impl Future>::new_unchecked(move _123) -> [return: bb113, unwind: bb126]; + } + -+ bb102: { ++ bb112: { + StorageDead(_124); + _125 = discriminant(_121); -+ switchInt(move _125) -> [0: bb57, 1: bb100, otherwise: bb71]; ++ switchInt(move _125) -> [0: bb63, 1: bb110, otherwise: bb81]; + } + -+ bb103: { -+ _121 = as Future>::poll(move _124, move _122) -> [return: bb102, unwind: bb34]; ++ bb113: { ++ _121 = as Future>::poll(move _124, move _122) -> [return: bb112, unwind: bb34]; + } + -+ bb104: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb104, unwind: bb116]; ++ bb114: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb114, unwind: bb126]; + } + -+ bb105: { ++ bb115: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 17; + return; + } + -+ bb106: { ++ bb116: { + StorageLive(_133); + _132 = &mut (((*_150) as variant#18).3: impl std::future::Future); -+ _133 = Pin::<&mut impl Future>::new_unchecked(move _132) -> [return: bb108, unwind: bb116]; ++ _133 = Pin::<&mut impl Future>::new_unchecked(move _132) -> [return: bb118, unwind: bb126]; + } + -+ bb107: { ++ bb117: { + StorageDead(_133); + _134 = discriminant(_130); -+ switchInt(move _134) -> [0: bb60, 1: bb105, otherwise: bb71]; ++ switchInt(move _134) -> [0: bb67, 1: bb115, otherwise: bb81]; + } + -+ bb108: { -+ _130 = as Future>::poll(move _133, move _131) -> [return: bb107, unwind: bb35]; ++ bb118: { ++ _130 = as Future>::poll(move _133, move _131) -> [return: bb117, unwind: bb35]; + } + -+ bb109: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb109, unwind: bb116]; ++ bb119: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb119, unwind: bb126]; + } + -+ bb110: { ++ bb120: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 19; + return; + } + -+ bb111: { ++ bb121: { + StorageLive(_142); + _141 = &mut (((*_150) as variant#20).2: impl std::future::Future); -+ _142 = Pin::<&mut impl Future>::new_unchecked(move _141) -> [return: bb113, unwind: bb116]; ++ _142 = Pin::<&mut impl Future>::new_unchecked(move _141) -> [return: bb123, unwind: bb126]; + } + -+ bb112: { ++ bb122: { + StorageDead(_142); + _143 = discriminant(_139); -+ switchInt(move _143) -> [0: bb63, 1: bb110, otherwise: bb71]; ++ switchInt(move _143) -> [0: bb71, 1: bb120, otherwise: bb81]; + } + -+ bb113: { -+ _139 = as Future>::poll(move _142, move _140) -> [return: bb112, unwind: bb36]; ++ bb123: { ++ _139 = as Future>::poll(move _142, move _140) -> [return: bb122, unwind: bb36]; + } + -+ bb114: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb114, unwind: bb116]; ++ bb124: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb124, unwind: bb126]; + } + -+ bb115: { -+ goto -> bb66; ++ bb125: { ++ goto -> bb75; + } + -+ bb116 (cleanup): { ++ bb126 (cleanup): { + discriminant((*_150)) = 2; + resume; + } + -+ bb117: { ++ bb127: { + StorageLive(_17); + StorageLive(_23); + StorageLive(_25); + _68 = move _2; -+ goto -> bb70; ++ goto -> bb80; + } + -+ bb118: { ++ bb128: { + StorageLive(_17); + StorageLive(_23); + StorageLive(_25); + _72 = move _2; -+ goto -> bb74; ++ goto -> bb84; + } + -+ bb119: { ++ bb129: { + StorageLive(_17); + StorageLive(_23); + _77 = move _2; -+ goto -> bb76; ++ goto -> bb86; + } + -+ bb120: { ++ bb130: { + StorageLive(_17); + StorageLive(_23); + _81 = move _2; -+ goto -> bb79; ++ goto -> bb89; + } + -+ bb121: { ++ bb131: { + StorageLive(_17); + _86 = move _2; -+ goto -> bb81; ++ goto -> bb91; + } + -+ bb122: { ++ bb132: { + StorageLive(_17); + _90 = move _2; -+ goto -> bb84; ++ goto -> bb94; + } + -+ bb123: { ++ bb133: { + StorageLive(_17); + _95 = move _2; -+ goto -> bb86; ++ goto -> bb96; + } + -+ bb124: { ++ bb134: { + StorageLive(_17); + _99 = move _2; -+ goto -> bb89; ++ goto -> bb99; + } + -+ bb125: { ++ bb135: { + _104 = move _2; -+ goto -> bb91; ++ goto -> bb101; + } + -+ bb126: { ++ bb136: { + _108 = move _2; -+ goto -> bb94; ++ goto -> bb104; + } + -+ bb127: { ++ bb137: { + _113 = move _2; -+ goto -> bb96; ++ goto -> bb106; + } + -+ bb128: { ++ bb138: { + _117 = move _2; -+ goto -> bb99; ++ goto -> bb109; + } + -+ bb129: { ++ bb139: { + _122 = move _2; -+ goto -> bb101; ++ goto -> bb111; + } + -+ bb130: { ++ bb140: { + _126 = move _2; -+ goto -> bb104; ++ goto -> bb114; + } + -+ bb131: { ++ bb141: { + _131 = move _2; -+ goto -> bb106; ++ goto -> bb116; + } + -+ bb132: { ++ bb142: { + _135 = move _2; -+ goto -> bb109; ++ goto -> bb119; + } + -+ bb133: { ++ bb143: { + _140 = move _2; -+ goto -> bb111; ++ goto -> bb121; + } + -+ bb134: { ++ bb144: { + _144 = move _2; -+ goto -> bb114; ++ goto -> bb124; + } + -+ bb135: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb135, unwind continue]; ++ bb145: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb145, unwind continue]; + } + -+ bb136: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb136, unwind continue]; ++ bb146: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb146, unwind continue]; + } + -+ bb137: { ++ bb147: { + nop; + (((*_150) as variant#20).0: SyncInt) = SyncInt(const 0_i32); + nop; diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff index ec9c6dbc981e3..8155d7c7239b6 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff @@ -30,8 +30,7 @@ _4 = AsyncInt(const 0_i32); _0 = const (); - drop(_4) -> [return: bb1, unwind: bb7, drop: bb4]; -+ _6 = &mut _4; -+ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb13, unwind: bb7]; ++ goto -> bb14; } bb1: { @@ -42,8 +41,7 @@ bb2: { StorageDead(_3); - drop(_1) -> [return: bb3, drop: bb6, unwind continue]; -+ _10 = &mut _1; -+ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb16, unwind: bb9]; ++ goto -> bb18; } bb3: { @@ -106,18 +104,28 @@ + } + + bb14: { -+ StorageDead(_9); -+ goto -> bb3; ++ _6 = &mut _4; ++ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb13, unwind: bb7]; + } + + bb15: { -+ async drop(_1; poll=_9) -> [return: bb14, unwind: bb9, drop: bb6]; ++ StorageDead(_9); ++ goto -> bb3; + } + + bb16: { ++ async drop(_1; poll=_9) -> [return: bb15, unwind: bb9, drop: bb6]; ++ } ++ ++ bb17: { + _12 = copy (_11.0: &mut {async fn body of simple()}); + StorageLive(_9); -+ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb15, unwind: bb9]; ++ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb16, unwind: bb9]; ++ } ++ ++ bb18: { ++ _10 = &mut _1; ++ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb17, unwind: bb9]; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff index 72b1f40d7055b..e7d5e3e9ab3d4 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff @@ -61,11 +61,10 @@ - StorageLive(_4); - _4 = AsyncInt(const 0_i32); - _0 = const (); -- _6 = &mut _4; -- _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb12, unwind: bb7]; +- goto -> bb13; + _24 = copy (_1.0: &mut {async fn body of simple()}); + _23 = discriminant((*_24)); -+ switchInt(move _23) -> [0: bb25, 1: bb24, 2: bb23, 3: bb21, 4: bb22, otherwise: bb15]; ++ switchInt(move _23) -> [0: bb27, 1: bb26, 2: bb25, 3: bb23, 4: bb24, otherwise: bb17]; } bb1: { @@ -77,11 +76,9 @@ bb2: { - StorageDead(_3); -- _10 = &mut _1; -- _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb15, unwind: bb9]; +- goto -> bb17; + nop; -+ _10 = &mut (*_24); -+ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb12, unwind: bb6]; ++ goto -> bb14; } bb3: { @@ -111,7 +108,7 @@ + bb6 (cleanup): { StorageDead(_9); - coroutine_drop; -+ goto -> bb20; ++ goto -> bb22; } - bb7 (cleanup): { @@ -128,7 +125,7 @@ - drop(_1) -> [return: bb9, unwind terminate(cleanup)]; + bb8: { + _14 = move _2; -+ goto -> bb14; ++ goto -> bb16; } - bb9 (cleanup): { @@ -143,95 +140,108 @@ bb10: { - StorageDead(_5); - goto -> bb1; -+ StorageDead(_9); -+ goto -> bb3; ++ _6 = &mut (((*_24) as variant#4).1: AsyncInt); ++ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb4]; } bb11: { - async drop(_4; poll=_5) -> [return: bb10, unwind: bb7, drop: bb4]; -+ goto -> bb19; ++ StorageDead(_9); ++ goto -> bb3; } bb12: { - _8 = copy (_7.0: &mut AsyncInt); - StorageLive(_5); - _5 = async_drop_in_place::(move _8) -> [return: bb11, unwind: bb7]; ++ goto -> bb21; + } + + bb13: { +- _6 = &mut _4; +- _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb12, unwind: bb7]; + _12 = copy (_11.0: &mut {async fn body of simple()}); + StorageLive(_9); -+ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb11, unwind: bb6]; ++ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb12, unwind: bb6]; } - bb13: { + bb14: { - StorageDead(_9); - goto -> bb3; ++ _10 = &mut (*_24); ++ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb13, unwind: bb6]; + } + + bb15: { +- async drop(_1; poll=_9) -> [return: bb14, unwind: bb9, drop: bb6]; + _0 = Poll::<()>::Pending; + discriminant((*_24)) = 3; + return; } - bb14: { -- async drop(_1; poll=_9) -> [return: bb13, unwind: bb9, drop: bb6]; + bb16: { +- _12 = copy (_11.0: &mut {async fn body of simple()}); +- StorageLive(_9); +- _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb15, unwind: bb9]; + StorageLive(_16); + _15 = &mut (((*_24) as variant#4).2: impl std::future::Future); -+ _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb17, unwind: bb20]; ++ _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb19, unwind: bb22]; } - bb15: { -- _12 = copy (_11.0: &mut {async fn body of simple()}); -- StorageLive(_9); -- _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb14, unwind: bb9]; + bb17: { +- _10 = &mut _1; +- _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb16, unwind: bb9]; + unreachable; + } + -+ bb16: { ++ bb18: { + StorageDead(_16); + _17 = discriminant(_13); -+ switchInt(move _17) -> [0: bb7, 1: bb13, otherwise: bb15]; ++ switchInt(move _17) -> [0: bb7, 1: bb15, otherwise: bb17]; + } + -+ bb17: { -+ _13 = as Future>::poll(move _16, move _14) -> [return: bb16, unwind: bb4]; ++ bb19: { ++ _13 = as Future>::poll(move _16, move _14) -> [return: bb18, unwind: bb4]; + } + -+ bb18: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb18, unwind: bb20]; ++ bb20: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb20, unwind: bb22]; + } + -+ bb19: { -+ goto -> bb10; ++ bb21: { ++ goto -> bb11; + } + -+ bb20 (cleanup): { ++ bb22 (cleanup): { + discriminant((*_24)) = 2; + resume; + } + -+ bb21: { ++ bb23: { + _14 = move _2; -+ goto -> bb14; ++ goto -> bb16; + } + -+ bb22: { ++ bb24: { + _18 = move _2; -+ goto -> bb18; ++ goto -> bb20; + } + -+ bb23: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb23, unwind continue]; ++ bb25: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb25, unwind continue]; + } + -+ bb24: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb24, unwind continue]; ++ bb26: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb26, unwind continue]; + } + -+ bb25: { ++ bb27: { + nop; + (((*_24) as variant#4).0: SyncInt) = SyncInt(const 0_i32); + nop; + (((*_24) as variant#4).1: AsyncInt) = AsyncInt(const 0_i32); + (((*_24) as variant#3).0: ()) = const (); -+ _6 = &mut (((*_24) as variant#4).1: AsyncInt); -+ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb4]; ++ goto -> bb10; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir index 6c4d92e01d5b1..5c528fd0bbadb 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir @@ -37,8 +37,7 @@ yields () StorageLive(_4); _4 = AsyncInt(const 0_i32); _0 = const (); - _6 = &mut _4; - _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb12, unwind: bb7]; + goto -> bb13; } bb1: { @@ -48,8 +47,7 @@ yields () bb2: { StorageDead(_3); - _10 = &mut _1; - _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb15, unwind: bb9]; + goto -> bb17; } bb3: { @@ -95,7 +93,7 @@ yields () bb11: { _14 = move _2; - goto -> bb17; + goto -> bb19; } bb12: { @@ -105,69 +103,79 @@ yields () } bb13: { - StorageDead(_9); - goto -> bb3; + _6 = &mut _4; + _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb12, unwind: bb7]; } bb14: { - drop(_1) -> [return: bb13, unwind: bb9]; + StorageDead(_9); + goto -> bb3; } bb15: { - _12 = copy (_11.0: &mut {async fn body of simple()}); - StorageLive(_9); - _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb14, unwind: bb9]; + drop(_1) -> [return: bb14, unwind: bb9]; } bb16: { - _14 = yield(const false) -> [resume: bb17, drop: bb22]; + _12 = copy (_11.0: &mut {async fn body of simple()}); + StorageLive(_9); + _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb15, unwind: bb9]; } bb17: { - StorageLive(_16); - _15 = &mut _5; - _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb20, unwind continue]; + _10 = &mut _1; + _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb16, unwind: bb9]; } bb18: { - unreachable; + _14 = yield(const false) -> [resume: bb19, drop: bb24]; } bb19: { - StorageDead(_16); - _17 = discriminant(_13); - switchInt(move _17) -> [0: bb10, 1: bb16, otherwise: bb18]; + StorageLive(_16); + _15 = &mut _5; + _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb22, unwind continue]; } bb20: { - _13 = as Future>::poll(move _16, move _14) -> [return: bb19, unwind: bb7]; + unreachable; } bb21: { - _18 = yield(const false) -> [resume: bb26, drop: bb22]; + StorageDead(_16); + _17 = discriminant(_13); + switchInt(move _17) -> [0: bb10, 1: bb18, otherwise: bb20]; } bb22: { + _13 = as Future>::poll(move _16, move _14) -> [return: bb21, unwind: bb7]; + } + + bb23: { + _18 = yield(const false) -> [resume: bb28, drop: bb24]; + } + + bb24: { StorageLive(_20); _19 = &mut _5; - _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb25, unwind continue]; + _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb27, unwind continue]; } - bb23: { + bb25: { unreachable; } - bb24: { + bb26: { StorageDead(_20); _21 = discriminant(_13); - switchInt(move _21) -> [0: bb4, 1: bb21, otherwise: bb23]; + switchInt(move _21) -> [0: bb4, 1: bb23, otherwise: bb25]; } - bb25: { - _13 = as Future>::poll(move _20, move _18) -> [return: bb24, unwind: bb7]; + bb27: { + _13 = as Future>::poll(move _20, move _18) -> [return: bb26, unwind: bb7]; } - bb26: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb26, unwind continue]; + bb28: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb28, unwind continue]; } } diff --git a/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir index d83a51141bd40..a70704181ee35 100644 --- a/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir @@ -26,7 +26,7 @@ yields () bb0: { _3 = move (_1.0: &mut [Foo; 1]); - goto -> bb17; + goto -> bb19; } bb1: { @@ -53,8 +53,7 @@ yields () bb5: { _10 = &raw mut (*_5)[_7]; _7 = Add(move _7, const 1_usize); - _13 = &mut (*_10); - _14 = Pin::<&mut Foo>::new_unchecked(move _13) -> [return: bb9, unwind: bb4]; + goto -> bb10; } bb6: { @@ -79,45 +78,54 @@ yields () } bb10: { - _16 = &raw mut (*_5)[_7]; - _7 = Add(move _7, const 1_usize); - _19 = &mut (*_16); - _20 = Pin::<&mut Foo>::new_unchecked(move _19) -> [return: bb14, unwind: bb4]; + _13 = &mut (*_10); + _14 = Pin::<&mut Foo>::new_unchecked(move _13) -> [return: bb9, unwind: bb4]; } bb11: { - _17 = Eq(copy _7, copy _6); - switchInt(move _17) -> [0: bb10, otherwise: bb1]; + _16 = &raw mut (*_5)[_7]; + _7 = Add(move _7, const 1_usize); + goto -> bb16; } bb12: { - StorageDead(_18); - goto -> bb11; + _17 = Eq(copy _7, copy _6); + switchInt(move _17) -> [0: bb11, otherwise: bb1]; } bb13: { - async drop((*_16); poll=_18) -> [return: bb12, unwind: bb4, drop: bb6]; + StorageDead(_18); + goto -> bb12; } bb14: { + async drop((*_16); poll=_18) -> [return: bb13, unwind: bb4, drop: bb6]; + } + + bb15: { _21 = copy (_20.0: &mut Foo); StorageLive(_18); - _18 = async_drop_in_place::(move _21) -> [return: bb13, unwind: bb4]; + _18 = async_drop_in_place::(move _21) -> [return: bb14, unwind: bb4]; } - bb15: { + bb16: { + _19 = &mut (*_16); + _20 = Pin::<&mut Foo>::new_unchecked(move _19) -> [return: bb15, unwind: bb4]; + } + + bb17: { _6 = PtrMetadata(copy _5); _7 = const 0_usize; - goto -> bb11; + goto -> bb12; } - bb16: { - goto -> bb15; + bb18: { + goto -> bb17; } - bb17: { + bb19: { _4 = &raw mut (*_3); _5 = move _4 as *mut [Foo] (PointerCoercion(Unsize, Implicit)); - goto -> bb16; + goto -> bb18; } } From a352c54ea861aa138ff3c8b4b15be35f1f24dff7 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 08:38:53 +0000 Subject: [PATCH 07/12] Avoid modifying existing blocks. Same rationale as previous commit. --- .../rustc_mir_transform/src/elaborate_drop.rs | 53 +- ...sure#0}.AsyncEnum.MentionedItems.after.mir | 92 ++- ...-{closure#0}.AsyncEnum.StateTransform.diff | 192 ++--- ...osure#0}.AsyncInt.MentionedItems.after.mir | 24 +- ...e-{closure#0}.AsyncInt.StateTransform.diff | 79 +- ...syncReference_'__.MentionedItems.after.mir | 24 +- ...#0}.AsyncReference_'__.StateTransform.diff | 79 +- ...re#0}.AsyncStruct.MentionedItems.after.mir | 122 +-- ...closure#0}.AsyncStruct.StateTransform.diff | 255 +++--- ...#0}.SyncThenAsync.MentionedItems.after.mir | 106 ++- ...osure#0}.SyncThenAsync.StateTransform.diff | 175 ++-- ...rop.double-{closure#0}.ElaborateDrops.diff | 80 +- ...rop.double-{closure#0}.StateTransform.diff | 215 ++--- ...osure#0}.coroutine_async_drop_expand.0.mir | 160 ++-- ...ble-{closure#0}.coroutine_drop_async.0.mir | 92 ++- ...rate_drops-{closure#0}.ElaborateDrops.diff | 276 ++++--- ...rate_drops-{closure#0}.StateTransform.diff | 756 ++++++++++-------- ...rop.simple-{closure#0}.ElaborateDrops.diff | 52 +- ...rop.simple-{closure#0}.StateTransform.diff | 139 ++-- ...osure#0}.coroutine_async_drop_expand.0.mir | 92 ++- ...ple-{closure#0}.coroutine_drop_async.0.mir | 58 +- ...#0}.coroutine_drop_async.0.panic-abort.mir | 44 +- ...0}.coroutine_drop_async.0.panic-unwind.mir | 66 +- ...losure#0}.[Foo;1].MentionedItems.after.mir | 68 +- 24 files changed, 1883 insertions(+), 1416 deletions(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 0c072096f064a..2d9f91e843095 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -277,7 +277,7 @@ where (sig.output(), drop_fn_def_id, trait_args) }; - let fut = Place::from(self.new_temp(fut_ty)); + let fut = self.new_temp(fut_ty); // #1:pin_obj_bb >>> obj_ref = &mut obj let obj_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, drop_ty); @@ -310,9 +310,23 @@ where // in existing blocks, in case those are used somewhere else in MIR. let succ_with_dead = self.new_block_with_statements( unwind, - vec![Statement::new(self.source_info, StatementKind::StorageDead(fut.local))], + vec![self.storage_dead(fut)], TerminatorKind::Goto { target: succ }, ); + let dropline_with_dead = dropline.map(|target| { + self.new_block_with_statements( + unwind, + vec![self.storage_dead(fut)], + TerminatorKind::Goto { target }, + ) + }); + let unwind_with_dead = unwind.map(|target| { + self.new_block_with_statements( + Unwind::InCleanup, + vec![self.storage_dead(fut)], + TerminatorKind::Goto { target }, + ) + }); // #3:drop_term_bb let drop_term_bb = self.new_block( @@ -320,10 +334,10 @@ where TerminatorKind::Drop { place, target: succ_with_dead, - unwind: unwind.into_action(), + unwind: unwind_with_dead.into_action(), replace: false, - drop: dropline, - async_fut: Some(fut.local), + drop: dropline_with_dead, + async_fut: Some(fut), }, ); @@ -348,8 +362,7 @@ where obj_ref_place }; - call_statements - .push(Statement::new(self.source_info, StatementKind::StorageLive(fut.local))); + call_statements.push(self.storage_live(fut)); let call_drop_bb = self.new_block_with_statements( unwind, @@ -357,27 +370,13 @@ where TerminatorKind::Call { func: Operand::function_handle(tcx, drop_fn_def_id, trait_args, span), args: [Spanned { node: Operand::Move(drop_arg), span: DUMMY_SP }].into(), - destination: fut, + destination: fut.into(), target: Some(drop_term_bb), - unwind: unwind.into_action(), + unwind: unwind_with_dead.into_action(), call_source: CallSource::Misc, fn_span: self.source_info.span, }, ); - // StorageDead(fut) in unwind block (at the begin) - if let Unwind::To(block) = unwind { - self.elaborator.patch().add_statement( - Location { block, statement_index: 0 }, - StatementKind::StorageDead(fut.local), - ); - } - // StorageDead(fut) in dropline block (at the begin) - if let Some(block) = dropline { - self.elaborator.patch().add_statement( - Location { block, statement_index: 0 }, - StatementKind::StorageDead(fut.local), - ); - } // #1:pin_obj_bb >>> call Pin::new_unchecked(&mut obj) self.new_block_with_statements( @@ -1404,4 +1403,12 @@ where fn assign(&self, lhs: Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> { Statement::new(self.source_info, StatementKind::Assign(Box::new((lhs, rhs)))) } + + fn storage_live(&self, local: Local) -> Statement<'tcx> { + Statement::new(self.source_info, StatementKind::StorageLive(local)) + } + + fn storage_dead(&self, local: Local) -> Statement<'tcx> { + Statement::new(self.source_info, StatementKind::StorageDead(local)) + } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir index f0aac6ca9b377..84cf65da840e4 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir @@ -22,17 +22,14 @@ yields () bb0: { _3 = move (_1.0: &mut AsyncEnum); - goto -> bb24; + goto -> bb29; } bb1: { - StorageDead(_8); return; } bb2 (cleanup): { - StorageDead(_4); - StorageDead(_8); resume; } @@ -53,90 +50,113 @@ yields () goto -> bb1; } - bb7: { - async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2]; + bb7 (cleanup): { + StorageDead(_4); + goto -> bb2; } bb8: { + async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb6, unwind: bb7]; + } + + bb9: { _7 = copy (_6.0: &mut AsyncInt); StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb2]; + _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb7]; } - bb9: { + bb10: { _5 = &mut (((*_3) as A).0: AsyncInt); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; } - bb10: { + bb11: { StorageDead(_8); goto -> bb3; } - bb11: { - async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb10, unwind: bb2, drop: bb1]; + bb12: { + StorageDead(_8); + goto -> bb1; } - bb12: { + bb13 (cleanup): { + StorageDead(_8); + goto -> bb2; + } + + bb14: { + async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb11, unwind: bb13, drop: bb12]; + } + + bb15: { _11 = copy (_10.0: &mut AsyncInt); StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb11, unwind: bb2]; + _8 = async_drop_in_place::(move _11) -> [return: bb14, unwind: bb13]; } - bb13: { + bb16: { _9 = &mut (((*_3) as A).0: AsyncInt); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb12, unwind: bb2]; + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb15, unwind: bb2]; } - bb14 (cleanup): { + bb17 (cleanup): { drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } - bb15 (cleanup): { + bb18 (cleanup): { drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } - bb16: { + bb19: { drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; } - bb17: { + bb20: { drop((((*_3) as B).0: SyncInt)) -> [return: bb3, unwind: bb2]; } - bb18: { + bb21: { _12 = discriminant((*_3)); - switchInt(move _12) -> [0: bb13, otherwise: bb17]; + switchInt(move _12) -> [0: bb16, otherwise: bb20]; } - bb19 (cleanup): { - StorageDead(_15); + bb22 (cleanup): { _13 = discriminant((*_3)); - switchInt(move _13) -> [0: bb4, otherwise: bb14]; + switchInt(move _13) -> [0: bb4, otherwise: bb17]; } - bb20: { - StorageDead(_15); + bb23: { _14 = discriminant((*_3)); - switchInt(move _14) -> [0: bb9, otherwise: bb16]; + switchInt(move _14) -> [0: bb10, otherwise: bb19]; } - bb21: { + bb24: { StorageDead(_15); - goto -> bb18; + goto -> bb21; } - bb22: { - async drop((*_3); poll=_15) -> [return: bb21, unwind: bb19, drop: bb20]; + bb25: { + StorageDead(_15); + goto -> bb23; } - bb23: { + bb26 (cleanup): { + StorageDead(_15); + goto -> bb22; + } + + bb27: { + async drop((*_3); poll=_15) -> [return: bb24, unwind: bb26, drop: bb25]; + } + + bb28: { StorageLive(_15); - _15 = ::drop(move _17) -> [return: bb22, unwind: bb19]; + _15 = ::drop(move _17) -> [return: bb27, unwind: bb26]; } - bb24: { + bb29: { _16 = &mut (*_3); - _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb23, unwind: bb19]; + _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb28, unwind: bb22]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff index 876f9a12ed288..9ae4219b3357b 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff @@ -76,27 +76,21 @@ bb0: { - _3 = move (_1.0: &mut AsyncEnum); - _16 = &mut (*_3); -- _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb19, unwind: bb15]; +- _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb23, unwind: bb18]; + _43 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); + _42 = discriminant((*_43)); -+ switchInt(move _42) -> [0: bb34, 1: bb33, 2: bb32, 3: bb27, 4: bb28, 5: bb29, 6: bb30, 7: bb31, otherwise: bb17]; ++ switchInt(move _42) -> [0: bb36, 1: bb35, 2: bb34, 3: bb29, 4: bb30, 5: bb31, 6: bb32, 7: bb33, otherwise: bb19]; } bb1: { -- StorageDead(_8); -+ nop; + _0 = Poll::<()>::Ready(move _41); + discriminant((*_43)) = 1; return; } bb2 (cleanup): { -- StorageDead(_4); -- StorageDead(_8); - resume; -+ nop; -+ nop; -+ goto -> bb26; ++ goto -> bb28; } bb3 (cleanup): { @@ -111,194 +105,210 @@ goto -> bb1; } - bb5: { -- async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb4, unwind: bb2]; -+ _24 = move _2; -+ goto -> bb16; + bb5 (cleanup): { +- StorageDead(_4); ++ nop; + goto -> bb2; } bb6: { +- async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb4, unwind: bb5]; ++ _24 = move _2; ++ goto -> bb18; + } + + bb7: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb5, unwind: bb2]; +- _4 = async_drop_in_place::(move _7) -> [return: bb6, unwind: bb5]; + _11 = copy (_10.0: &mut AsyncInt); + nop; -+ (((*_43) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _11) -> [return: bb5, unwind: bb2]; ++ (((*_43) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _11) -> [return: bb6, unwind: bb5]; } - bb7: { + bb8: { - _5 = &mut (((*_3) as A).0: AsyncInt); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; + _45 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + _9 = &mut (((*_45) as A).0: AsyncInt); -+ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb6, unwind: bb2]; ++ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb7, unwind: bb2]; } -- bb8: { +- bb9: { - StorageDead(_8); - goto -> bb1; -+ bb8 (cleanup): { ++ bb9 (cleanup): { + _46 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + drop((((*_46) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } - bb9: { -- async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb8, unwind: bb2, drop: bb1]; + bb10: { +- StorageDead(_8); +- goto -> bb1; + _47 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + drop((((*_47) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; } -- bb10: { -- _11 = copy (_10.0: &mut AsyncInt); -- StorageLive(_8); -- _8 = async_drop_in_place::(move _11) -> [return: bb9, unwind: bb2]; -+ bb10 (cleanup): { -+ nop; + bb11 (cleanup): { +- StorageDead(_8); +- goto -> bb2; + _48 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + _13 = discriminant((*_48)); -+ switchInt(move _13) -> [0: bb3, otherwise: bb8]; ++ switchInt(move _13) -> [0: bb3, otherwise: bb9]; } - bb11: { -- _9 = &mut (((*_3) as A).0: AsyncInt); -- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb10, unwind: bb2]; + bb12: { +- async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb9, unwind: bb11, drop: bb10]; + nop; + _49 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + _12 = discriminant((*_49)); -+ switchInt(move _12) -> [0: bb7, otherwise: bb9]; ++ switchInt(move _12) -> [0: bb8, otherwise: bb10]; } -- bb12 (cleanup): { -- drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ bb12: { +- bb13: { +- _11 = copy (_10.0: &mut AsyncInt); +- StorageLive(_8); +- _8 = async_drop_in_place::(move _11) -> [return: bb12, unwind: bb11]; ++ bb13 (cleanup): { ++ nop; ++ goto -> bb11; + } + + bb14: { +- _9 = &mut (((*_3) as A).0: AsyncInt); +- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb2]; + _33 = move _2; -+ goto -> bb22; ++ goto -> bb24; } - bb13: { -- drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; +- bb15 (cleanup): { +- drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ bb15: { + nop; -+ (((*_43) as variant#7).1: impl std::future::Future) = ::drop(move _17) -> [return: bb12, unwind: bb10]; ++ (((*_43) as variant#7).1: impl std::future::Future) = ::drop(move _17) -> [return: bb14, unwind: bb13]; } - bb14: { + bb16: { - drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb26]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb16, unwind: bb28]; } -- bb15 (cleanup): { -- StorageDead(_15); -- _13 = discriminant((*_3)); -- switchInt(move _13) -> [0: bb3, otherwise: bb12]; -+ bb15: { + bb17: { +- drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; + _0 = Poll::<()>::Pending; + discriminant((*_43)) = 4; + return; } - bb16: { -- StorageDead(_15); -- _14 = discriminant((*_3)); -- switchInt(move _14) -> [0: bb7, otherwise: bb13]; +- bb18 (cleanup): { +- _13 = discriminant((*_3)); +- switchInt(move _13) -> [0: bb3, otherwise: bb15]; ++ bb18: { + StorageLive(_26); + _25 = &mut (((*_43) as variant#5).0: impl std::future::Future); -+ _26 = Pin::<&mut impl Future>::new_unchecked(move _25) -> [return: bb19, unwind: bb26]; ++ _26 = Pin::<&mut impl Future>::new_unchecked(move _25) -> [return: bb21, unwind: bb28]; } - bb17: { + bb19: { - StorageDead(_15); - _12 = discriminant((*_3)); -- switchInt(move _12) -> [0: bb11, otherwise: bb14]; +- switchInt(move _12) -> [0: bb14, otherwise: bb17]; + unreachable; } - bb18: { -- async drop((*_3); poll=_15) -> [return: bb17, unwind: bb15, drop: bb16]; + bb20: { +- StorageDead(_15); +- _14 = discriminant((*_3)); +- switchInt(move _14) -> [0: bb8, otherwise: bb16]; + StorageDead(_26); + _27 = discriminant(_23); -+ switchInt(move _27) -> [0: bb4, 1: bb15, otherwise: bb17]; ++ switchInt(move _27) -> [0: bb4, 1: bb17, otherwise: bb19]; } - bb19: { -- StorageLive(_15); -- _15 = ::drop(move _17) -> [return: bb18, unwind: bb15]; -+ _23 = as Future>::poll(move _26, move _24) -> [return: bb18, unwind: bb2]; -+ } -+ -+ bb20: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb20, unwind: bb26]; -+ } -+ +- bb21 (cleanup): { +- StorageDead(_15); +- goto -> bb18; + bb21: { ++ _23 = as Future>::poll(move _26, move _24) -> [return: bb20, unwind: bb5]; + } + + bb22: { +- async drop((*_3); poll=_15) -> [return: bb19, unwind: bb21, drop: bb20]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb28]; + } + + bb23: { +- StorageLive(_15); +- _15 = ::drop(move _17) -> [return: bb22, unwind: bb21]; + _0 = Poll::<()>::Pending; + discriminant((*_43)) = 6; + return; + } + -+ bb22: { ++ bb24: { + StorageLive(_35); + _34 = &mut (((*_43) as variant#7).1: impl std::future::Future); -+ _35 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb24, unwind: bb26]; ++ _35 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb26, unwind: bb28]; + } + -+ bb23: { ++ bb25: { + StorageDead(_35); + _36 = discriminant(_32); -+ switchInt(move _36) -> [0: bb11, 1: bb21, otherwise: bb17]; ++ switchInt(move _36) -> [0: bb12, 1: bb23, otherwise: bb19]; + } + -+ bb24: { -+ _32 = as Future>::poll(move _35, move _33) -> [return: bb23, unwind: bb10]; ++ bb26: { ++ _32 = as Future>::poll(move _35, move _33) -> [return: bb25, unwind: bb13]; + } + -+ bb25: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb25, unwind: bb26]; ++ bb27: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb27, unwind: bb28]; + } + -+ bb26 (cleanup): { ++ bb28 (cleanup): { + discriminant((*_43)) = 2; + resume; + } + -+ bb27: { ++ bb29: { + _19 = move _2; -+ goto -> bb14; ++ goto -> bb16; + } + -+ bb28: { ++ bb30: { + _24 = move _2; -+ goto -> bb16; ++ goto -> bb18; + } + -+ bb29: { ++ bb31: { + _28 = move _2; -+ goto -> bb20; ++ goto -> bb22; + } + -+ bb30: { ++ bb32: { + _33 = move _2; -+ goto -> bb22; ++ goto -> bb24; + } + -+ bb31: { ++ bb33: { + _37 = move _2; -+ goto -> bb25; ++ goto -> bb27; + } + -+ bb32: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb32, unwind continue]; ++ bb34: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb34, unwind continue]; + } + -+ bb33: { ++ bb35: { + _0 = Poll::<()>::Ready(const ()); + return; + } + -+ bb34: { ++ bb36: { + (((*_43) as variant#7).0: &mut AsyncEnum) = move ((*_43).0: &mut AsyncEnum); + _50 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); + _16 = &mut (*_50); -+ _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb13, unwind: bb10]; ++ _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb15, unwind: bb11]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir index 356e8bb2d0bb0..96a9f2ca080d1 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir @@ -11,16 +11,14 @@ yields () bb0: { _3 = move (_1.0: &mut AsyncInt); - goto -> bb7; + goto -> bb9; } bb1: { - StorageDead(_4); return; } bb2 (cleanup): { - StorageDead(_4); resume; } @@ -34,16 +32,26 @@ yields () } bb5: { - async drop((*_3); poll=_4) -> [return: bb4, unwind: bb2, drop: bb1]; + StorageDead(_4); + goto -> bb1; } - bb6: { - StorageLive(_4); - _4 = ::drop(move _6) -> [return: bb5, unwind: bb2]; + bb6 (cleanup): { + StorageDead(_4); + goto -> bb2; } bb7: { + async drop((*_3); poll=_4) -> [return: bb4, unwind: bb6, drop: bb5]; + } + + bb8: { + StorageLive(_4); + _4 = ::drop(move _6) -> [return: bb7, unwind: bb6]; + } + + bb9: { _5 = &mut (*_3); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff index 0df9e00cef41c..9eb5aa10bc77c 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff @@ -38,25 +38,21 @@ bb0: { - _3 = move (_1.0: &mut AsyncInt); - _5 = &mut (*_3); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb5, unwind: bb2]; +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; + _18 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); + _17 = discriminant((*_18)); -+ switchInt(move _17) -> [0: bb17, 1: bb16, 2: bb15, 3: bb13, 4: bb14, otherwise: bb8]; ++ switchInt(move _17) -> [0: bb18, 1: bb17, 2: bb16, 3: bb14, 4: bb15, otherwise: bb9]; } bb1: { -- StorageDead(_4); -+ nop; + _0 = Poll::<()>::Ready(move _16); + discriminant((*_18)) = 1; return; } bb2 (cleanup): { -- StorageDead(_4); - resume; -+ nop; -+ goto -> bb12; ++ goto -> bb13; } bb3: { @@ -65,77 +61,88 @@ goto -> bb1; } - bb4: { -- async drop((*_3); poll=_4) -> [return: bb3, unwind: bb2, drop: bb1]; +- bb4: { +- StorageDead(_4); +- goto -> bb1; ++ bb4 (cleanup): { ++ nop; ++ goto -> bb2; + } + +- bb5 (cleanup): { +- StorageDead(_4); +- goto -> bb2; ++ bb5: { + _8 = move _2; -+ goto -> bb7; ++ goto -> bb8; } - bb5: { -- StorageLive(_4); -- _4 = ::drop(move _6) -> [return: bb4, unwind: bb2]; + bb6: { +- async drop((*_3); poll=_4) -> [return: bb3, unwind: bb5, drop: bb4]; + nop; -+ (((*_18) as variant#4).0: impl std::future::Future) = ::drop(move _6) -> [return: bb4, unwind: bb2]; -+ } -+ -+ bb6: { ++ (((*_18) as variant#4).0: impl std::future::Future) = ::drop(move _6) -> [return: bb5, unwind: bb4]; + } + + bb7: { +- StorageLive(_4); +- _4 = ::drop(move _6) -> [return: bb6, unwind: bb5]; + _0 = Poll::<()>::Pending; + discriminant((*_18)) = 3; + return; + } + -+ bb7: { ++ bb8: { + StorageLive(_10); + _9 = &mut (((*_18) as variant#4).0: impl std::future::Future); -+ _10 = Pin::<&mut impl Future>::new_unchecked(move _9) -> [return: bb10, unwind: bb12]; ++ _10 = Pin::<&mut impl Future>::new_unchecked(move _9) -> [return: bb11, unwind: bb13]; + } + -+ bb8: { ++ bb9: { + unreachable; + } + -+ bb9: { ++ bb10: { + StorageDead(_10); + _11 = discriminant(_7); -+ switchInt(move _11) -> [0: bb3, 1: bb6, otherwise: bb8]; ++ switchInt(move _11) -> [0: bb3, 1: bb7, otherwise: bb9]; + } + -+ bb10: { -+ _7 = as Future>::poll(move _10, move _8) -> [return: bb9, unwind: bb2]; ++ bb11: { ++ _7 = as Future>::poll(move _10, move _8) -> [return: bb10, unwind: bb4]; + } + -+ bb11: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb11, unwind: bb12]; ++ bb12: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb12, unwind: bb13]; + } + -+ bb12 (cleanup): { ++ bb13 (cleanup): { + discriminant((*_18)) = 2; + resume; + } + -+ bb13: { ++ bb14: { + _8 = move _2; -+ goto -> bb7; ++ goto -> bb8; + } + -+ bb14: { ++ bb15: { + _12 = move _2; -+ goto -> bb11; ++ goto -> bb12; + } + -+ bb15: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb15, unwind continue]; ++ bb16: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb16, unwind continue]; + } + -+ bb16: { ++ bb17: { + _0 = Poll::<()>::Ready(const ()); + return; + } + -+ bb17: { ++ bb18: { + _3 = move ((*_18).0: &mut AsyncInt); + _5 = &mut (*_3); -+ _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb5, unwind: bb2]; ++ _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir index f6ef2e1fe13de..2d1f4e53b0447 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir @@ -11,16 +11,14 @@ yields () bb0: { _3 = move (_1.0: &mut AsyncReference<'_>); - goto -> bb7; + goto -> bb9; } bb1: { - StorageDead(_4); return; } bb2 (cleanup): { - StorageDead(_4); resume; } @@ -34,16 +32,26 @@ yields () } bb5: { - async drop((*_3); poll=_4) -> [return: bb4, unwind: bb2, drop: bb1]; + StorageDead(_4); + goto -> bb1; } - bb6: { - StorageLive(_4); - _4 = as AsyncDrop>::drop(move _6) -> [return: bb5, unwind: bb2]; + bb6 (cleanup): { + StorageDead(_4); + goto -> bb2; } bb7: { + async drop((*_3); poll=_4) -> [return: bb4, unwind: bb6, drop: bb5]; + } + + bb8: { + StorageLive(_4); + _4 = as AsyncDrop>::drop(move _6) -> [return: bb7, unwind: bb6]; + } + + bb9: { _5 = &mut (*_3); - _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; + _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff index a4919a71d921c..e2caa694c3657 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff @@ -38,25 +38,21 @@ bb0: { - _3 = move (_1.0: &mut AsyncReference<'_>); - _5 = &mut (*_3); -- _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb5, unwind: bb2]; +- _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; + _18 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place>()}); + _17 = discriminant((*_18)); -+ switchInt(move _17) -> [0: bb17, 1: bb16, 2: bb15, 3: bb13, 4: bb14, otherwise: bb8]; ++ switchInt(move _17) -> [0: bb18, 1: bb17, 2: bb16, 3: bb14, 4: bb15, otherwise: bb9]; } bb1: { -- StorageDead(_4); -+ nop; + _0 = Poll::<()>::Ready(move _16); + discriminant((*_18)) = 1; return; } bb2 (cleanup): { -- StorageDead(_4); - resume; -+ nop; -+ goto -> bb12; ++ goto -> bb13; } bb3: { @@ -65,77 +61,88 @@ goto -> bb1; } - bb4: { -- async drop((*_3); poll=_4) -> [return: bb3, unwind: bb2, drop: bb1]; +- bb4: { +- StorageDead(_4); +- goto -> bb1; ++ bb4 (cleanup): { ++ nop; ++ goto -> bb2; + } + +- bb5 (cleanup): { +- StorageDead(_4); +- goto -> bb2; ++ bb5: { + _8 = move _2; -+ goto -> bb7; ++ goto -> bb8; } - bb5: { -- StorageLive(_4); -- _4 = as AsyncDrop>::drop(move _6) -> [return: bb4, unwind: bb2]; + bb6: { +- async drop((*_3); poll=_4) -> [return: bb3, unwind: bb5, drop: bb4]; + nop; -+ (((*_18) as variant#4).0: impl std::future::Future) = as AsyncDrop>::drop(move _6) -> [return: bb4, unwind: bb2]; -+ } -+ -+ bb6: { ++ (((*_18) as variant#4).0: impl std::future::Future) = as AsyncDrop>::drop(move _6) -> [return: bb5, unwind: bb4]; + } + + bb7: { +- StorageLive(_4); +- _4 = as AsyncDrop>::drop(move _6) -> [return: bb6, unwind: bb5]; + _0 = Poll::<()>::Pending; + discriminant((*_18)) = 3; + return; + } + -+ bb7: { ++ bb8: { + StorageLive(_10); + _9 = &mut (((*_18) as variant#4).0: impl std::future::Future); -+ _10 = Pin::<&mut impl Future>::new_unchecked(move _9) -> [return: bb10, unwind: bb12]; ++ _10 = Pin::<&mut impl Future>::new_unchecked(move _9) -> [return: bb11, unwind: bb13]; + } + -+ bb8: { ++ bb9: { + unreachable; + } + -+ bb9: { ++ bb10: { + StorageDead(_10); + _11 = discriminant(_7); -+ switchInt(move _11) -> [0: bb3, 1: bb6, otherwise: bb8]; ++ switchInt(move _11) -> [0: bb3, 1: bb7, otherwise: bb9]; + } + -+ bb10: { -+ _7 = as Future>::poll(move _10, move _8) -> [return: bb9, unwind: bb2]; ++ bb11: { ++ _7 = as Future>::poll(move _10, move _8) -> [return: bb10, unwind: bb4]; + } + -+ bb11: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb11, unwind: bb12]; ++ bb12: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb12, unwind: bb13]; + } + -+ bb12 (cleanup): { ++ bb13 (cleanup): { + discriminant((*_18)) = 2; + resume; + } + -+ bb13: { ++ bb14: { + _8 = move _2; -+ goto -> bb7; ++ goto -> bb8; + } + -+ bb14: { ++ bb15: { + _12 = move _2; -+ goto -> bb11; ++ goto -> bb12; + } + -+ bb15: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb15, unwind continue]; ++ bb16: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb16, unwind continue]; + } + -+ bb16: { ++ bb17: { + _0 = Poll::<()>::Ready(const ()); + return; + } + -+ bb17: { ++ bb18: { + _3 = move ((*_18).0: &mut AsyncReference<'_>); + _5 = &mut (*_3); -+ _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb5, unwind: bb2]; ++ _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir index 3599dfe0b7a7a..48b90196a89ac 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir @@ -27,17 +27,14 @@ yields () bb0: { _3 = move (_1.0: &mut AsyncStruct); - goto -> bb25; + goto -> bb33; } bb1: { - StorageDead(_12); return; } bb2 (cleanup): { - StorageDead(_4); - StorageDead(_12); resume; } @@ -46,13 +43,10 @@ yields () } bb4 (cleanup): { - StorageDead(_8); - StorageDead(_16); drop(((*_3).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb5 (cleanup): { - StorageDead(_20); drop(((*_3).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; } @@ -61,99 +55,137 @@ yields () goto -> bb1; } - bb7: { - async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2]; + bb7 (cleanup): { + StorageDead(_4); + goto -> bb2; } bb8: { + async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb6, unwind: bb7]; + } + + bb9: { _7 = copy (_6.0: &mut AsyncInt); StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb2]; + _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb7]; } - bb9: { - StorageDead(_16); + bb10: { _5 = &mut ((*_3).2: AsyncInt); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; } - bb10: { + bb11: { StorageDead(_8); - goto -> bb9; + goto -> bb10; } - bb11: { - async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb10, unwind: bb4]; + bb12 (cleanup): { + StorageDead(_8); + goto -> bb4; + } + + bb13: { + async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb11, unwind: bb12]; } - bb12: { + bb14: { _11 = copy (_10.0: &mut AsyncInt); StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb11, unwind: bb4]; + _8 = async_drop_in_place::(move _11) -> [return: bb13, unwind: bb12]; } - bb13: { - StorageDead(_20); + bb15: { _9 = &mut ((*_3).1: AsyncInt); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb12, unwind: bb4]; + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb14, unwind: bb4]; } - bb14: { + bb16: { StorageDead(_12); goto -> bb3; } - bb15: { - async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb14, unwind: bb2, drop: bb1]; + bb17: { + StorageDead(_12); + goto -> bb1; } - bb16: { + bb18 (cleanup): { + StorageDead(_12); + goto -> bb2; + } + + bb19: { + async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb16, unwind: bb18, drop: bb17]; + } + + bb20: { _15 = copy (_14.0: &mut AsyncInt); StorageLive(_12); - _12 = async_drop_in_place::(move _15) -> [return: bb15, unwind: bb2]; + _12 = async_drop_in_place::(move _15) -> [return: bb19, unwind: bb18]; } - bb17: { + bb21: { _13 = &mut ((*_3).2: AsyncInt); - _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb16, unwind: bb2]; + _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb20, unwind: bb2]; } - bb18: { + bb22: { StorageDead(_16); - goto -> bb17; + goto -> bb21; } - bb19: { - async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb18, unwind: bb4, drop: bb9]; + bb23: { + StorageDead(_16); + goto -> bb10; } - bb20: { + bb24 (cleanup): { + StorageDead(_16); + goto -> bb4; + } + + bb25: { + async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb22, unwind: bb24, drop: bb23]; + } + + bb26: { _19 = copy (_18.0: &mut AsyncInt); StorageLive(_16); - _16 = async_drop_in_place::(move _19) -> [return: bb19, unwind: bb4]; + _16 = async_drop_in_place::(move _19) -> [return: bb25, unwind: bb24]; } - bb21: { + bb27: { _17 = &mut ((*_3).1: AsyncInt); - _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb20, unwind: bb4]; + _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb26, unwind: bb4]; } - bb22: { + bb28: { StorageDead(_20); - goto -> bb21; + goto -> bb27; } - bb23: { - async drop((*_3); poll=_20) -> [return: bb22, unwind: bb5, drop: bb13]; + bb29: { + StorageDead(_20); + goto -> bb15; + } + + bb30 (cleanup): { + StorageDead(_20); + goto -> bb5; } - bb24: { + bb31: { + async drop((*_3); poll=_20) -> [return: bb28, unwind: bb30, drop: bb29]; + } + + bb32: { StorageLive(_20); - _20 = ::drop(move _22) -> [return: bb23, unwind: bb5]; + _20 = ::drop(move _22) -> [return: bb31, unwind: bb30]; } - bb25: { + bb33: { _21 = &mut (*_3); - _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb24, unwind: bb5]; + _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb32, unwind: bb5]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff index 5d84cfbe57f7e..7a4181d058848 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff @@ -98,43 +98,31 @@ bb0: { - _3 = move (_1.0: &mut AsyncStruct); - _21 = &mut (*_3); -- _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb21, unwind: bb4]; +- _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb28, unwind: bb4]; + _62 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); + _61 = discriminant((*_62)); -+ switchInt(move _61) -> [0: bb43, 1: bb42, 2: bb41, 3: bb33, 4: bb34, 5: bb35, 6: bb36, 7: bb37, 8: bb38, 9: bb39, 10: bb40, otherwise: bb18]; ++ switchInt(move _61) -> [0: bb46, 1: bb45, 2: bb44, 3: bb36, 4: bb37, 5: bb38, 6: bb39, 7: bb40, 8: bb41, 9: bb42, 10: bb43, otherwise: bb21]; } bb1: { -- StorageDead(_12); -+ nop; + _0 = Poll::<()>::Ready(move _60); + discriminant((*_62)) = 1; return; } bb2 (cleanup): { -- StorageDead(_4); -- StorageDead(_12); - resume; -+ nop; -+ nop; -+ goto -> bb32; ++ goto -> bb35; } bb3 (cleanup): { -- StorageDead(_8); -- StorageDead(_16); - drop(((*_3).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ nop; -+ nop; + _63 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); + drop(((*_63).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb4 (cleanup): { -- StorageDead(_20); - drop(((*_3).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; -+ nop; + _64 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); + drop(((*_64).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; } @@ -145,236 +133,269 @@ goto -> bb1; } - bb6: { -- async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb5, unwind: bb2]; -+ _34 = move _2; -+ goto -> bb17; + bb6 (cleanup): { +- StorageDead(_4); ++ nop; + goto -> bb2; } bb7: { +- async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb5, unwind: bb6]; ++ _34 = move _2; ++ goto -> bb20; + } + + bb8: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb6, unwind: bb2]; +- _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb6]; + _15 = copy (_14.0: &mut AsyncInt); + nop; -+ (((*_62) as variant#6).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb6, unwind: bb2]; ++ (((*_62) as variant#6).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb7, unwind: bb6]; } - bb8: { -- StorageDead(_16); + bb9: { - _5 = &mut ((*_3).2: AsyncInt); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; + nop; + _65 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); + _13 = &mut ((*_65).2: AsyncInt); -+ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb7, unwind: bb2]; ++ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb8, unwind: bb2]; } - bb9: { +- bb10: { - StorageDead(_8); -- goto -> bb8; +- goto -> bb9; ++ bb10 (cleanup): { ++ nop; ++ goto -> bb3; + } + +- bb11 (cleanup): { +- StorageDead(_8); +- goto -> bb3; ++ bb11: { + _43 = move _2; -+ goto -> bb23; ++ goto -> bb26; } - bb10: { -- async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb9, unwind: bb3]; + bb12: { +- async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb10, unwind: bb11]; + _19 = copy (_18.0: &mut AsyncInt); + nop; -+ (((*_62) as variant#8).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb9, unwind: bb3]; ++ (((*_62) as variant#8).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb11, unwind: bb10]; } - bb11: { + bb13: { - _11 = copy (_10.0: &mut AsyncInt); - StorageLive(_8); -- _8 = async_drop_in_place::(move _11) -> [return: bb10, unwind: bb3]; +- _8 = async_drop_in_place::(move _11) -> [return: bb12, unwind: bb11]; + nop; + _66 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); + _17 = &mut ((*_66).1: AsyncInt); -+ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb10, unwind: bb3]; ++ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb12, unwind: bb3]; } - bb12: { -- StorageDead(_20); -- _9 = &mut ((*_3).1: AsyncInt); -- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb11, unwind: bb3]; -+ _52 = move _2; -+ goto -> bb28; +- bb14: { +- StorageDead(_12); +- goto -> bb1; ++ bb14 (cleanup): { ++ nop; ++ goto -> bb4; } - bb13: { + bb15: { - StorageDead(_12); - goto -> bb1; ++ _52 = move _2; ++ goto -> bb31; + } + +- bb16 (cleanup): { +- StorageDead(_12); +- goto -> bb2; ++ bb16: { + nop; -+ (((*_62) as variant#10).1: impl std::future::Future) = ::drop(move _22) -> [return: bb12, unwind: bb4]; ++ (((*_62) as variant#10).1: impl std::future::Future) = ::drop(move _22) -> [return: bb15, unwind: bb14]; } - bb14: { -- async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb13, unwind: bb2, drop: bb1]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb32]; + bb17: { +- async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb14, unwind: bb16, drop: bb15]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb17, unwind: bb35]; } - bb15: { + bb18: { - _15 = copy (_14.0: &mut AsyncInt); - StorageLive(_12); -- _12 = async_drop_in_place::(move _15) -> [return: bb14, unwind: bb2]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb15, unwind: bb32]; +- _12 = async_drop_in_place::(move _15) -> [return: bb17, unwind: bb16]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb18, unwind: bb35]; } - bb16: { + bb19: { - StorageDead(_16); - _13 = &mut ((*_3).2: AsyncInt); -- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb15, unwind: bb2]; +- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb18, unwind: bb2]; + _0 = Poll::<()>::Pending; + discriminant((*_62)) = 5; + return; } - bb17: { -- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb16, unwind: bb3, drop: bb8]; + bb20: { +- StorageDead(_16); +- goto -> bb9; + StorageLive(_36); + _35 = &mut (((*_62) as variant#6).0: impl std::future::Future); -+ _36 = Pin::<&mut impl Future>::new_unchecked(move _35) -> [return: bb20, unwind: bb32]; ++ _36 = Pin::<&mut impl Future>::new_unchecked(move _35) -> [return: bb23, unwind: bb35]; } - bb18: { -- _19 = copy (_18.0: &mut AsyncInt); -- StorageLive(_16); -- _16 = async_drop_in_place::(move _19) -> [return: bb17, unwind: bb3]; +- bb21 (cleanup): { +- StorageDead(_16); +- goto -> bb3; ++ bb21: { + unreachable; } - bb19: { -- StorageDead(_20); -- _17 = &mut ((*_3).1: AsyncInt); -- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb18, unwind: bb3]; + bb22: { +- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb19, unwind: bb21, drop: bb20]; + StorageDead(_36); + _37 = discriminant(_33); -+ switchInt(move _37) -> [0: bb5, 1: bb16, otherwise: bb18]; ++ switchInt(move _37) -> [0: bb5, 1: bb19, otherwise: bb21]; } - bb20: { -- async drop((*_3); poll=_20) -> [return: bb19, unwind: bb4, drop: bb12]; -+ _33 = as Future>::poll(move _36, move _34) -> [return: bb19, unwind: bb2]; + bb23: { +- _19 = copy (_18.0: &mut AsyncInt); +- StorageLive(_16); +- _16 = async_drop_in_place::(move _19) -> [return: bb22, unwind: bb21]; ++ _33 = as Future>::poll(move _36, move _34) -> [return: bb22, unwind: bb6]; } - bb21: { -- StorageLive(_20); -- _20 = ::drop(move _22) -> [return: bb20, unwind: bb4]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb21, unwind: bb32]; -+ } -+ -+ bb22: { + bb24: { +- StorageDead(_20); +- _17 = &mut ((*_3).1: AsyncInt); +- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb23, unwind: bb3]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb24, unwind: bb35]; + } + + bb25: { +- StorageDead(_20); +- _9 = &mut ((*_3).1: AsyncInt); +- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb3]; + _0 = Poll::<()>::Pending; + discriminant((*_62)) = 7; + return; -+ } -+ -+ bb23: { + } + +- bb26 (cleanup): { +- StorageDead(_20); +- goto -> bb4; ++ bb26: { + StorageLive(_45); + _44 = &mut (((*_62) as variant#8).1: impl std::future::Future); -+ _45 = Pin::<&mut impl Future>::new_unchecked(move _44) -> [return: bb25, unwind: bb32]; -+ } -+ -+ bb24: { ++ _45 = Pin::<&mut impl Future>::new_unchecked(move _44) -> [return: bb28, unwind: bb35]; + } + + bb27: { +- async drop((*_3); poll=_20) -> [return: bb24, unwind: bb26, drop: bb25]; + StorageDead(_45); + _46 = discriminant(_42); -+ switchInt(move _46) -> [0: bb8, 1: bb22, otherwise: bb18]; -+ } -+ -+ bb25: { -+ _42 = as Future>::poll(move _45, move _43) -> [return: bb24, unwind: bb3]; ++ switchInt(move _46) -> [0: bb9, 1: bb25, otherwise: bb21]; + } + + bb28: { +- StorageLive(_20); +- _20 = ::drop(move _22) -> [return: bb27, unwind: bb26]; ++ _42 = as Future>::poll(move _45, move _43) -> [return: bb27, unwind: bb10]; + } + -+ bb26: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb26, unwind: bb32]; ++ bb29: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb29, unwind: bb35]; + } + -+ bb27: { ++ bb30: { + _0 = Poll::<()>::Pending; + discriminant((*_62)) = 9; + return; + } + -+ bb28: { ++ bb31: { + StorageLive(_54); + _53 = &mut (((*_62) as variant#10).1: impl std::future::Future); -+ _54 = Pin::<&mut impl Future>::new_unchecked(move _53) -> [return: bb30, unwind: bb32]; ++ _54 = Pin::<&mut impl Future>::new_unchecked(move _53) -> [return: bb33, unwind: bb35]; + } + -+ bb29: { ++ bb32: { + StorageDead(_54); + _55 = discriminant(_51); -+ switchInt(move _55) -> [0: bb11, 1: bb27, otherwise: bb18]; ++ switchInt(move _55) -> [0: bb13, 1: bb30, otherwise: bb21]; + } + -+ bb30: { -+ _51 = as Future>::poll(move _54, move _52) -> [return: bb29, unwind: bb4]; ++ bb33: { ++ _51 = as Future>::poll(move _54, move _52) -> [return: bb32, unwind: bb14]; + } + -+ bb31: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb31, unwind: bb32]; ++ bb34: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb34, unwind: bb35]; + } + -+ bb32 (cleanup): { ++ bb35 (cleanup): { + discriminant((*_62)) = 2; + resume; + } + -+ bb33: { ++ bb36: { + _24 = move _2; -+ goto -> bb14; ++ goto -> bb17; + } + -+ bb34: { ++ bb37: { + _29 = move _2; -+ goto -> bb15; ++ goto -> bb18; + } + -+ bb35: { ++ bb38: { + _34 = move _2; -+ goto -> bb17; ++ goto -> bb20; + } + -+ bb36: { ++ bb39: { + _38 = move _2; -+ goto -> bb21; ++ goto -> bb24; + } + -+ bb37: { ++ bb40: { + _43 = move _2; -+ goto -> bb23; ++ goto -> bb26; + } + -+ bb38: { ++ bb41: { + _47 = move _2; -+ goto -> bb26; ++ goto -> bb29; + } + -+ bb39: { ++ bb42: { + _52 = move _2; -+ goto -> bb28; ++ goto -> bb31; + } + -+ bb40: { ++ bb43: { + _56 = move _2; -+ goto -> bb31; ++ goto -> bb34; + } + -+ bb41: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb41, unwind continue]; ++ bb44: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb44, unwind continue]; + } + -+ bb42: { ++ bb45: { + _0 = Poll::<()>::Ready(const ()); + return; + } + -+ bb43: { ++ bb46: { + (((*_62) as variant#10).0: &mut AsyncStruct) = move ((*_62).0: &mut AsyncStruct); + _67 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); + _21 = &mut (*_67); -+ _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb13, unwind: bb4]; ++ _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb16, unwind: bb4]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir index 132e0ab0c7f13..e2ad09cb99404 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir @@ -26,17 +26,14 @@ yields () bb0: { _3 = move (_1.0: &mut SyncThenAsync); - goto -> bb25; + goto -> bb31; } bb1: { - StorageDead(_12); return; } bb2 (cleanup): { - StorageDead(_4); - StorageDead(_12); resume; } @@ -49,8 +46,6 @@ yields () } bb5 (cleanup): { - StorageDead(_8); - StorageDead(_16); drop(((*_3).2: SyncInt)) -> [return: bb4, unwind terminate(cleanup)]; } @@ -63,92 +58,121 @@ yields () goto -> bb1; } - bb8: { - async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2]; + bb8 (cleanup): { + StorageDead(_4); + goto -> bb2; } bb9: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb2]; + async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb7, unwind: bb8]; } bb10: { - _5 = &mut ((*_3).3: AsyncInt); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; + _7 = copy (_6.0: &mut AsyncInt); + StorageLive(_4); + _4 = async_drop_in_place::(move _7) -> [return: bb9, unwind: bb8]; } bb11: { - StorageDead(_16); - drop(((*_3).2: SyncInt)) -> [return: bb10, unwind: bb4]; + _5 = &mut ((*_3).3: AsyncInt); + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb10, unwind: bb2]; } bb12: { - StorageDead(_8); - goto -> bb11; + drop(((*_3).2: SyncInt)) -> [return: bb11, unwind: bb4]; } bb13: { - async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb12, unwind: bb5]; + StorageDead(_8); + goto -> bb12; + } + + bb14 (cleanup): { + StorageDead(_8); + goto -> bb5; + } + + bb15: { + async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb13, unwind: bb14]; } - bb14: { + bb16: { _11 = copy (_10.0: &mut AsyncInt); StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb13, unwind: bb5]; + _8 = async_drop_in_place::(move _11) -> [return: bb15, unwind: bb14]; } - bb15: { + bb17: { _9 = &mut ((*_3).1: AsyncInt); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb14, unwind: bb5]; + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb16, unwind: bb5]; } - bb16: { + bb18: { StorageDead(_12); goto -> bb3; } - bb17: { - async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb16, unwind: bb2, drop: bb1]; + bb19: { + StorageDead(_12); + goto -> bb1; } - bb18: { + bb20 (cleanup): { + StorageDead(_12); + goto -> bb2; + } + + bb21: { + async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb18, unwind: bb20, drop: bb19]; + } + + bb22: { _15 = copy (_14.0: &mut AsyncInt); StorageLive(_12); - _12 = async_drop_in_place::(move _15) -> [return: bb17, unwind: bb2]; + _12 = async_drop_in_place::(move _15) -> [return: bb21, unwind: bb20]; } - bb19: { + bb23: { _13 = &mut ((*_3).3: AsyncInt); - _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb18, unwind: bb2]; + _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb22, unwind: bb2]; } - bb20: { - drop(((*_3).2: SyncInt)) -> [return: bb19, unwind: bb4]; + bb24: { + drop(((*_3).2: SyncInt)) -> [return: bb23, unwind: bb4]; } - bb21: { + bb25: { StorageDead(_16); - goto -> bb20; + goto -> bb24; } - bb22: { - async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb21, unwind: bb5, drop: bb11]; + bb26: { + StorageDead(_16); + goto -> bb12; } - bb23: { + bb27 (cleanup): { + StorageDead(_16); + goto -> bb5; + } + + bb28: { + async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb25, unwind: bb27, drop: bb26]; + } + + bb29: { _19 = copy (_18.0: &mut AsyncInt); StorageLive(_16); - _16 = async_drop_in_place::(move _19) -> [return: bb22, unwind: bb5]; + _16 = async_drop_in_place::(move _19) -> [return: bb28, unwind: bb27]; } - bb24: { + bb30: { _17 = &mut ((*_3).1: AsyncInt); - _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb23, unwind: bb5]; + _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb29, unwind: bb5]; } - bb25: { + bb31: { _20 = &mut (*_3); - _21 = ::drop(move _20) -> [return: bb24, unwind: bb6]; + _21 = ::drop(move _20) -> [return: bb30, unwind: bb6]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff index 8b01104dd2256..eaf4fcd886013 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff @@ -80,27 +80,21 @@ bb0: { - _3 = move (_1.0: &mut SyncThenAsync); - _20 = &mut (*_3); -- _21 = ::drop(move _20) -> [return: bb18, unwind: bb5]; +- _21 = ::drop(move _20) -> [return: bb22, unwind: bb5]; + _47 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); + _46 = discriminant((*_47)); -+ switchInt(move _46) -> [0: bb34, 1: bb33, 2: bb32, 3: bb27, 4: bb28, 5: bb29, 6: bb30, 7: bb31, otherwise: bb17]; ++ switchInt(move _46) -> [0: bb36, 1: bb35, 2: bb34, 3: bb29, 4: bb30, 5: bb31, 6: bb32, 7: bb33, otherwise: bb19]; } bb1: { -- StorageDead(_12); -+ nop; + _0 = Poll::<()>::Ready(move _45); + discriminant((*_47)) = 1; return; } bb2 (cleanup): { -- StorageDead(_4); -- StorageDead(_12); - resume; -+ nop; -+ nop; -+ goto -> bb26; ++ goto -> bb28; } bb3 (cleanup): { @@ -110,10 +104,7 @@ } bb4 (cleanup): { - StorageDead(_8); -- StorageDead(_16); - drop(((*_3).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; -+ nop; + _49 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); + drop(((*_49).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; } @@ -130,174 +121,194 @@ goto -> bb1; } - bb7: { -- async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2]; -+ _28 = move _2; -+ goto -> bb16; + bb7 (cleanup): { +- StorageDead(_4); ++ nop; + goto -> bb2; } bb8: { +- async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb6, unwind: bb7]; ++ _28 = move _2; ++ goto -> bb18; + } + + bb9: { - _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb2]; +- _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb7]; + _15 = copy (_14.0: &mut AsyncInt); + nop; -+ (((*_47) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb7, unwind: bb2]; ++ (((*_47) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb8, unwind: bb7]; } - bb9: { + bb10: { - _5 = &mut ((*_3).3: AsyncInt); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; + _51 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); + _13 = &mut ((*_51).3: AsyncInt); -+ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb8, unwind: bb2]; ++ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb9, unwind: bb2]; } - bb10: { -- StorageDead(_16); -- drop(((*_3).2: SyncInt)) -> [return: bb9, unwind: bb3]; + bb11: { +- StorageDead(_12); +- goto -> bb1; + nop; + _52 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_52).2: SyncInt)) -> [return: bb9, unwind: bb3]; ++ drop(((*_52).2: SyncInt)) -> [return: bb10, unwind: bb3]; } - bb11: { +- bb12: { - StorageDead(_12); - goto -> bb1; ++ bb12 (cleanup): { ++ nop; ++ goto -> bb4; + } + +- bb13 (cleanup): { +- StorageDead(_12); +- goto -> bb2; ++ bb13: { + _37 = move _2; -+ goto -> bb22; ++ goto -> bb24; } - bb12: { -- async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb11, unwind: bb2, drop: bb1]; + bb14: { +- async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb11, unwind: bb13, drop: bb12]; + _19 = copy (_18.0: &mut AsyncInt); + nop; -+ (((*_47) as variant#7).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb11, unwind: bb4]; ++ (((*_47) as variant#7).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb13, unwind: bb12]; } - bb13: { + bb15: { - _15 = copy (_14.0: &mut AsyncInt); - StorageLive(_12); -- _12 = async_drop_in_place::(move _15) -> [return: bb12, unwind: bb2]; +- _12 = async_drop_in_place::(move _15) -> [return: bb14, unwind: bb13]; + _53 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); + _17 = &mut ((*_53).1: AsyncInt); -+ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb12, unwind: bb4]; ++ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb14, unwind: bb4]; } - bb14: { + bb16: { - _13 = &mut ((*_3).3: AsyncInt); -- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb13, unwind: bb2]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb26]; +- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb15, unwind: bb2]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb16, unwind: bb28]; } - bb15: { + bb17: { - StorageDead(_16); -- drop(((*_3).2: SyncInt)) -> [return: bb14, unwind: bb3]; +- drop(((*_3).2: SyncInt)) -> [return: bb16, unwind: bb3]; + _0 = Poll::<()>::Pending; + discriminant((*_47)) = 4; + return; } - bb16: { -- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb15, unwind: bb4, drop: bb10]; + bb18: { +- StorageDead(_16); +- drop(((*_3).2: SyncInt)) -> [return: bb10, unwind: bb3]; + StorageLive(_30); + _29 = &mut (((*_47) as variant#5).0: impl std::future::Future); -+ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb19, unwind: bb26]; ++ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb21, unwind: bb28]; } - bb17: { -- _19 = copy (_18.0: &mut AsyncInt); -- StorageLive(_16); -- _16 = async_drop_in_place::(move _19) -> [return: bb16, unwind: bb4]; +- bb19 (cleanup): { +- StorageDead(_16); +- goto -> bb4; ++ bb19: { + unreachable; } - bb18: { -- _17 = &mut ((*_3).1: AsyncInt); -- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb17, unwind: bb4]; + bb20: { +- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb17, unwind: bb19, drop: bb18]; + StorageDead(_30); + _31 = discriminant(_27); -+ switchInt(move _31) -> [0: bb6, 1: bb15, otherwise: bb17]; -+ } -+ -+ bb19: { -+ _27 = as Future>::poll(move _30, move _28) -> [return: bb18, unwind: bb2]; -+ } -+ -+ bb20: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb20, unwind: bb26]; ++ switchInt(move _31) -> [0: bb6, 1: bb17, otherwise: bb19]; + } + + bb21: { +- _19 = copy (_18.0: &mut AsyncInt); +- StorageLive(_16); +- _16 = async_drop_in_place::(move _19) -> [return: bb20, unwind: bb19]; ++ _27 = as Future>::poll(move _30, move _28) -> [return: bb20, unwind: bb7]; + } + + bb22: { +- _17 = &mut ((*_3).1: AsyncInt); +- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb21, unwind: bb4]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb28]; + } + -+ bb21: { ++ bb23: { + _0 = Poll::<()>::Pending; + discriminant((*_47)) = 6; + return; + } + -+ bb22: { ++ bb24: { + StorageLive(_39); + _38 = &mut (((*_47) as variant#7).1: impl std::future::Future); -+ _39 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb24, unwind: bb26]; ++ _39 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb26, unwind: bb28]; + } + -+ bb23: { ++ bb25: { + StorageDead(_39); + _40 = discriminant(_36); -+ switchInt(move _40) -> [0: bb10, 1: bb21, otherwise: bb17]; ++ switchInt(move _40) -> [0: bb11, 1: bb23, otherwise: bb19]; + } + -+ bb24: { -+ _36 = as Future>::poll(move _39, move _37) -> [return: bb23, unwind: bb4]; ++ bb26: { ++ _36 = as Future>::poll(move _39, move _37) -> [return: bb25, unwind: bb12]; + } + -+ bb25: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb25, unwind: bb26]; ++ bb27: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb27, unwind: bb28]; + } + -+ bb26 (cleanup): { ++ bb28 (cleanup): { + discriminant((*_47)) = 2; + resume; + } + -+ bb27: { ++ bb29: { + _23 = move _2; -+ goto -> bb14; ++ goto -> bb16; + } + -+ bb28: { ++ bb30: { + _28 = move _2; -+ goto -> bb16; ++ goto -> bb18; + } + -+ bb29: { ++ bb31: { + _32 = move _2; -+ goto -> bb20; ++ goto -> bb22; + } + -+ bb30: { ++ bb32: { + _37 = move _2; -+ goto -> bb22; ++ goto -> bb24; + } + -+ bb31: { ++ bb33: { + _41 = move _2; -+ goto -> bb25; ++ goto -> bb27; + } + -+ bb32: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb32, unwind continue]; ++ bb34: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb34, unwind continue]; + } + -+ bb33: { ++ bb35: { + _0 = Poll::<()>::Ready(const ()); + return; + } + -+ bb34: { ++ bb36: { + (((*_47) as variant#7).0: &mut SyncThenAsync) = move ((*_47).0: &mut SyncThenAsync); + _54 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); + _20 = &mut (*_54); -+ _21 = ::drop(move _20) -> [return: bb13, unwind: bb5]; ++ _21 = ::drop(move _20) -> [return: bb15, unwind: bb5]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff index 5d4d1f65cb552..7ce5a342b8623 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff @@ -40,13 +40,13 @@ _5 = AsyncInt(const 0_i32); _0 = const (); - drop(_5) -> [return: bb1, unwind: bb9, drop: bb5]; -+ goto -> bb18; ++ goto -> bb20; } bb1: { StorageDead(_5); - drop(_4) -> [return: bb2, unwind: bb10, drop: bb6]; -+ goto -> bb22; ++ goto -> bb26; } bb2: { @@ -57,7 +57,7 @@ bb3: { StorageDead(_3); - drop(_1) -> [return: bb4, drop: bb8, unwind continue]; -+ goto -> bb26; ++ goto -> bb32; } bb4: { @@ -65,14 +65,12 @@ } bb5: { -+ StorageDead(_6); StorageDead(_5); - drop(_4) -> [return: bb6, unwind: bb13]; + goto -> bb6; } bb6: { -+ StorageDead(_10); StorageDead(_4); - drop(_3) -> [return: bb7, unwind: bb14]; + goto -> bb7; @@ -85,18 +83,15 @@ } bb8: { -+ StorageDead(_14); coroutine_drop; } bb9 (cleanup): { -+ StorageDead(_6); StorageDead(_5); drop(_4) -> [return: bb10, unwind terminate(cleanup)]; } bb10 (cleanup): { -+ StorageDead(_10); StorageDead(_4); drop(_3) -> [return: bb11, unwind terminate(cleanup)]; } @@ -107,7 +102,6 @@ } bb12 (cleanup): { -+ StorageDead(_14); resume; } @@ -129,58 +123,88 @@ + } + + bb16: { -+ async drop(_5; poll=_6) -> [return: bb15, unwind: bb9, drop: bb5]; ++ StorageDead(_6); ++ goto -> bb5; ++ } ++ ++ bb17 (cleanup): { ++ StorageDead(_6); ++ goto -> bb9; + } + -+ bb17: { ++ bb18: { ++ async drop(_5; poll=_6) -> [return: bb15, unwind: bb17, drop: bb16]; ++ } ++ ++ bb19: { + _9 = copy (_8.0: &mut AsyncInt); + StorageLive(_6); -+ _6 = async_drop_in_place::(move _9) -> [return: bb16, unwind: bb9]; ++ _6 = async_drop_in_place::(move _9) -> [return: bb18, unwind: bb17]; + } + -+ bb18: { ++ bb20: { + _7 = &mut _5; -+ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb17, unwind: bb9]; ++ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb19, unwind: bb9]; + } + -+ bb19: { ++ bb21: { + StorageDead(_10); + goto -> bb2; + } + -+ bb20: { -+ async drop(_4; poll=_10) -> [return: bb19, unwind: bb10, drop: bb6]; ++ bb22: { ++ StorageDead(_10); ++ goto -> bb6; + } + -+ bb21: { ++ bb23 (cleanup): { ++ StorageDead(_10); ++ goto -> bb10; ++ } ++ ++ bb24: { ++ async drop(_4; poll=_10) -> [return: bb21, unwind: bb23, drop: bb22]; ++ } ++ ++ bb25: { + _13 = copy (_12.0: &mut AsyncInt); + StorageLive(_10); -+ _10 = async_drop_in_place::(move _13) -> [return: bb20, unwind: bb10]; ++ _10 = async_drop_in_place::(move _13) -> [return: bb24, unwind: bb23]; + } + -+ bb22: { ++ bb26: { + _11 = &mut _4; -+ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb21, unwind: bb10]; ++ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb25, unwind: bb10]; + } + -+ bb23: { ++ bb27: { + StorageDead(_14); + goto -> bb4; + } + -+ bb24: { -+ async drop(_1; poll=_14) -> [return: bb23, unwind: bb12, drop: bb8]; ++ bb28: { ++ StorageDead(_14); ++ goto -> bb8; + } + -+ bb25: { ++ bb29 (cleanup): { ++ StorageDead(_14); ++ goto -> bb12; ++ } ++ ++ bb30: { ++ async drop(_1; poll=_14) -> [return: bb27, unwind: bb29, drop: bb28]; ++ } ++ ++ bb31: { + _17 = copy (_16.0: &mut {async fn body of double()}); + StorageLive(_14); -+ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb24, unwind: bb12]; ++ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb30, unwind: bb29]; + } + -+ bb26: { ++ bb32: { + _15 = &mut _1; -+ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb25, unwind: bb12]; ++ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb31, unwind: bb12]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff index 30816c938635d..121de06ec08f4 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff @@ -86,17 +86,17 @@ - StorageLive(_5); - _5 = AsyncInt(const 0_i32); - _0 = const (); -- goto -> bb16; +- goto -> bb18; + _38 = copy (_1.0: &mut {async fn body of double()}); + _37 = discriminant((*_38)); -+ switchInt(move _37) -> [0: bb40, 1: bb39, 2: bb38, 3: bb34, 4: bb35, 5: bb36, 6: bb37, otherwise: bb23]; ++ switchInt(move _37) -> [0: bb43, 1: bb42, 2: bb41, 3: bb37, 4: bb38, 5: bb39, 6: bb40, otherwise: bb26]; } bb1: { - StorageDead(_5); -- goto -> bb20; +- goto -> bb24; + nop; -+ goto -> bb16; ++ goto -> bb18; } bb2: { @@ -108,9 +108,9 @@ bb3: { - StorageDead(_3); -- goto -> bb24; +- goto -> bb30; + nop; -+ goto -> bb20; ++ goto -> bb23; } bb4: { @@ -120,22 +120,18 @@ } - bb5: { -- StorageDead(_6); - StorageDead(_5); - goto -> bb6; + bb5 (cleanup): { + nop; -+ nop; + drop((((*_38) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; } - bb6: { -- StorageDead(_10); - StorageDead(_4); - goto -> bb7; + bb6 (cleanup): { + nop; -+ nop; + drop((((*_38) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; } @@ -147,14 +143,12 @@ } - bb8: { -+ bb8 (cleanup): { - StorageDead(_14); - coroutine_drop; -+ goto -> bb33; ++ bb8 (cleanup): { ++ goto -> bb36; } - bb9 (cleanup): { -- StorageDead(_6); - StorageDead(_5); - drop(_4) -> [return: bb10, unwind terminate(cleanup)]; + bb9: { @@ -162,191 +156,218 @@ + goto -> bb1; } -- bb10 (cleanup): { -- StorageDead(_10); + bb10 (cleanup): { - StorageDead(_4); - drop(_3) -> [return: bb11, unwind terminate(cleanup)]; -+ bb10: { -+ _19 = move _2; -+ goto -> bb22; ++ nop; ++ goto -> bb5; } - bb11 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb12, unwind terminate(cleanup)]; + bb11: { -+ _9 = copy (_8.0: &mut AsyncInt); -+ nop; -+ (((*_38) as variant#4).3: impl std::future::Future) = async_drop_in_place::(move _9) -> [return: bb10, unwind: bb5]; ++ _19 = move _2; ++ goto -> bb25; } - bb12 (cleanup): { -- StorageDead(_14); - resume; + bb12: { -+ _7 = &mut (((*_38) as variant#4).2: AsyncInt); -+ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb11, unwind: bb5]; ++ _9 = copy (_8.0: &mut AsyncInt); ++ nop; ++ (((*_38) as variant#4).3: impl std::future::Future) = async_drop_in_place::(move _9) -> [return: bb11, unwind: bb10]; } bb13: { - StorageDead(_6); - goto -> bb1; ++ _7 = &mut (((*_38) as variant#4).2: AsyncInt); ++ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb12, unwind: bb5]; + } + + bb14: { +- StorageDead(_6); +- goto -> bb5; + nop; + goto -> bb2; } - bb14: { -- async drop(_5; poll=_6) -> [return: bb13, unwind: bb9, drop: bb5]; + bb15 (cleanup): { +- StorageDead(_6); +- goto -> bb9; ++ nop; ++ goto -> bb6; + } + + bb16: { +- async drop(_5; poll=_6) -> [return: bb13, unwind: bb15, drop: bb14]; + _28 = move _2; -+ goto -> bb28; ++ goto -> bb31; } - bb15: { + bb17: { - _9 = copy (_8.0: &mut AsyncInt); - StorageLive(_6); -- _6 = async_drop_in_place::(move _9) -> [return: bb14, unwind: bb9]; +- _6 = async_drop_in_place::(move _9) -> [return: bb16, unwind: bb15]; + _13 = copy (_12.0: &mut AsyncInt); + nop; -+ (((*_38) as variant#6).2: impl std::future::Future) = async_drop_in_place::(move _13) -> [return: bb14, unwind: bb6]; ++ (((*_38) as variant#6).2: impl std::future::Future) = async_drop_in_place::(move _13) -> [return: bb16, unwind: bb15]; } - bb16: { + bb18: { - _7 = &mut _5; -- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb9]; +- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb17, unwind: bb9]; + _11 = &mut (((*_38) as variant#6).1: AsyncInt); -+ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb15, unwind: bb6]; ++ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb17, unwind: bb6]; } - bb17: { + bb19: { - StorageDead(_10); - goto -> bb2; + StorageDead(_14); + goto -> bb4; } - bb18: { -- async drop(_4; poll=_10) -> [return: bb17, unwind: bb10, drop: bb6]; -+ goto -> bb32; +- bb20: { +- StorageDead(_10); +- goto -> bb6; ++ bb20 (cleanup): { ++ StorageDead(_14); ++ goto -> bb8; } - bb19: { -- _13 = copy (_12.0: &mut AsyncInt); -- StorageLive(_10); -- _10 = async_drop_in_place::(move _13) -> [return: bb18, unwind: bb10]; +- bb21 (cleanup): { +- StorageDead(_10); +- goto -> bb10; ++ bb21: { ++ goto -> bb35; + } + + bb22: { +- async drop(_4; poll=_10) -> [return: bb19, unwind: bb21, drop: bb20]; + _17 = copy (_16.0: &mut {async fn body of double()}); + StorageLive(_14); -+ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb18, unwind: bb8]; ++ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb21, unwind: bb20]; } - bb20: { -- _11 = &mut _4; -- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb19, unwind: bb10]; + bb23: { +- _13 = copy (_12.0: &mut AsyncInt); +- StorageLive(_10); +- _10 = async_drop_in_place::(move _13) -> [return: bb22, unwind: bb21]; + _15 = &mut (*_38); -+ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb19, unwind: bb8]; ++ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb22, unwind: bb8]; } - bb21: { -- StorageDead(_14); -- goto -> bb4; + bb24: { +- _11 = &mut _4; +- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb23, unwind: bb10]; + _0 = Poll::<()>::Pending; + discriminant((*_38)) = 3; + return; } - bb22: { -- async drop(_1; poll=_14) -> [return: bb21, unwind: bb12, drop: bb8]; + bb25: { +- StorageDead(_14); +- goto -> bb4; + StorageLive(_21); + _20 = &mut (((*_38) as variant#4).3: impl std::future::Future); -+ _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb25, unwind: bb33]; ++ _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb28, unwind: bb36]; } - bb23: { -- _17 = copy (_16.0: &mut {async fn body of double()}); -- StorageLive(_14); -- _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb22, unwind: bb12]; + bb26: { +- StorageDead(_14); +- goto -> bb8; + unreachable; } - bb24: { -- _15 = &mut _1; -- _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb23, unwind: bb12]; +- bb27 (cleanup): { +- StorageDead(_14); +- goto -> bb12; ++ bb27: { + StorageDead(_21); + _22 = discriminant(_18); -+ switchInt(move _22) -> [0: bb9, 1: bb21, otherwise: bb23]; -+ } -+ -+ bb25: { -+ _18 = as Future>::poll(move _21, move _19) -> [return: bb24, unwind: bb5]; -+ } -+ -+ bb26: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb26, unwind: bb33]; -+ } -+ -+ bb27: { ++ switchInt(move _22) -> [0: bb9, 1: bb24, otherwise: bb26]; + } + + bb28: { +- async drop(_1; poll=_14) -> [return: bb25, unwind: bb27, drop: bb26]; ++ _18 = as Future>::poll(move _21, move _19) -> [return: bb27, unwind: bb10]; + } + + bb29: { +- _17 = copy (_16.0: &mut {async fn body of double()}); +- StorageLive(_14); +- _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb28, unwind: bb27]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb29, unwind: bb36]; + } + + bb30: { +- _15 = &mut _1; +- _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb29, unwind: bb12]; + _0 = Poll::<()>::Pending; + discriminant((*_38)) = 5; + return; + } + -+ bb28: { ++ bb31: { + StorageLive(_30); + _29 = &mut (((*_38) as variant#6).2: impl std::future::Future); -+ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb30, unwind: bb33]; ++ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb33, unwind: bb36]; + } + -+ bb29: { ++ bb32: { + StorageDead(_30); + _31 = discriminant(_27); -+ switchInt(move _31) -> [0: bb13, 1: bb27, otherwise: bb23]; ++ switchInt(move _31) -> [0: bb14, 1: bb30, otherwise: bb26]; + } + -+ bb30: { -+ _27 = as Future>::poll(move _30, move _28) -> [return: bb29, unwind: bb6]; ++ bb33: { ++ _27 = as Future>::poll(move _30, move _28) -> [return: bb32, unwind: bb15]; + } + -+ bb31: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb31, unwind: bb33]; ++ bb34: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb34, unwind: bb36]; + } + -+ bb32: { -+ goto -> bb17; ++ bb35: { ++ goto -> bb19; + } + -+ bb33 (cleanup): { ++ bb36 (cleanup): { + discriminant((*_38)) = 2; + resume; + } + -+ bb34: { ++ bb37: { + _19 = move _2; -+ goto -> bb22; ++ goto -> bb25; + } + -+ bb35: { ++ bb38: { + _23 = move _2; -+ goto -> bb26; ++ goto -> bb29; + } + -+ bb36: { ++ bb39: { + _28 = move _2; -+ goto -> bb28; ++ goto -> bb31; + } + -+ bb37: { ++ bb40: { + _32 = move _2; -+ goto -> bb31; ++ goto -> bb34; + } + -+ bb38: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb38, unwind continue]; ++ bb41: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb41, unwind continue]; + } + -+ bb39: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb39, unwind continue]; ++ bb42: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb42, unwind continue]; + } + -+ bb40: { ++ bb43: { + nop; + (((*_38) as variant#6).0: SyncInt) = SyncInt(const 0_i32); + nop; @@ -354,7 +375,7 @@ + nop; + (((*_38) as variant#4).2: AsyncInt) = AsyncInt(const 0_i32); + (((*_38) as variant#5).0: ()) = const (); -+ goto -> bb12; ++ goto -> bb13; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir index 7cd28072f1f97..27e865fd22188 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir @@ -56,12 +56,12 @@ yields () StorageLive(_5); _5 = AsyncInt(const 0_i32); _0 = const (); - goto -> bb16; + goto -> bb18; } bb1: { StorageDead(_5); - goto -> bb20; + goto -> bb24; } bb2: { @@ -71,7 +71,7 @@ yields () bb3: { StorageDead(_3); - goto -> bb24; + goto -> bb30; } bb4: { @@ -79,13 +79,11 @@ yields () } bb5: { - StorageDead(_6); StorageDead(_5); goto -> bb6; } bb6: { - StorageDead(_10); StorageDead(_4); goto -> bb7; } @@ -96,18 +94,15 @@ yields () } bb8: { - StorageDead(_14); coroutine_drop; } bb9 (cleanup): { - StorageDead(_6); StorageDead(_5); drop(_4) -> [return: bb10, unwind terminate(cleanup)]; } bb10 (cleanup): { - StorageDead(_10); StorageDead(_4); drop(_3) -> [return: bb11, unwind terminate(cleanup)]; } @@ -118,7 +113,6 @@ yields () } bb12 (cleanup): { - StorageDead(_14); resume; } @@ -128,163 +122,193 @@ yields () } bb14: { + StorageDead(_6); + goto -> bb5; + } + + bb15 (cleanup): { + StorageDead(_6); + goto -> bb9; + } + + bb16: { _19 = move _2; - goto -> bb26; + goto -> bb32; } - bb15: { + bb17: { _9 = copy (_8.0: &mut AsyncInt); StorageLive(_6); - _6 = async_drop_in_place::(move _9) -> [return: bb14, unwind: bb9]; + _6 = async_drop_in_place::(move _9) -> [return: bb16, unwind: bb15]; } - bb16: { + bb18: { _7 = &mut _5; - _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb9]; + _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb17, unwind: bb9]; } - bb17: { + bb19: { StorageDead(_10); goto -> bb2; } - bb18: { + bb20: { + StorageDead(_10); + goto -> bb6; + } + + bb21 (cleanup): { + StorageDead(_10); + goto -> bb10; + } + + bb22: { _28 = move _2; - goto -> bb37; + goto -> bb43; } - bb19: { + bb23: { _13 = copy (_12.0: &mut AsyncInt); StorageLive(_10); - _10 = async_drop_in_place::(move _13) -> [return: bb18, unwind: bb10]; + _10 = async_drop_in_place::(move _13) -> [return: bb22, unwind: bb21]; } - bb20: { + bb24: { _11 = &mut _4; - _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb19, unwind: bb10]; + _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb23, unwind: bb10]; } - bb21: { + bb25: { StorageDead(_14); goto -> bb4; } - bb22: { - drop(_1) -> [return: bb21, unwind: bb12]; + bb26: { + StorageDead(_14); + goto -> bb8; } - bb23: { + bb27 (cleanup): { + StorageDead(_14); + goto -> bb12; + } + + bb28: { + drop(_1) -> [return: bb25, unwind: bb27]; + } + + bb29: { _17 = copy (_16.0: &mut {async fn body of double()}); StorageLive(_14); - _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb22, unwind: bb12]; + _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb28, unwind: bb27]; } - bb24: { + bb30: { _15 = &mut _1; - _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb23, unwind: bb12]; + _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb29, unwind: bb12]; } - bb25: { - _19 = yield(const false) -> [resume: bb26, drop: bb31]; + bb31: { + _19 = yield(const false) -> [resume: bb32, drop: bb37]; } - bb26: { + bb32: { StorageLive(_21); _20 = &mut _6; - _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb29, unwind continue]; + _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb35, unwind continue]; } - bb27: { + bb33: { unreachable; } - bb28: { + bb34: { StorageDead(_21); _22 = discriminant(_18); - switchInt(move _22) -> [0: bb13, 1: bb25, otherwise: bb27]; + switchInt(move _22) -> [0: bb13, 1: bb31, otherwise: bb33]; } - bb29: { - _18 = as Future>::poll(move _21, move _19) -> [return: bb28, unwind: bb9]; + bb35: { + _18 = as Future>::poll(move _21, move _19) -> [return: bb34, unwind: bb15]; } - bb30: { - _23 = yield(const false) -> [resume: bb35, drop: bb31]; + bb36: { + _23 = yield(const false) -> [resume: bb41, drop: bb37]; } - bb31: { + bb37: { StorageLive(_25); _24 = &mut _6; - _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb34, unwind continue]; + _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb40, unwind continue]; } - bb32: { + bb38: { unreachable; } - bb33: { + bb39: { StorageDead(_25); _26 = discriminant(_18); - switchInt(move _26) -> [0: bb5, 1: bb30, otherwise: bb32]; + switchInt(move _26) -> [0: bb14, 1: bb36, otherwise: bb38]; } - bb34: { - _18 = as Future>::poll(move _25, move _23) -> [return: bb33, unwind: bb9]; + bb40: { + _18 = as Future>::poll(move _25, move _23) -> [return: bb39, unwind: bb15]; } - bb35: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb35, unwind continue]; + bb41: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb41, unwind continue]; } - bb36: { - _28 = yield(const false) -> [resume: bb37, drop: bb42]; + bb42: { + _28 = yield(const false) -> [resume: bb43, drop: bb48]; } - bb37: { + bb43: { StorageLive(_30); _29 = &mut _10; - _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb40, unwind continue]; + _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb46, unwind continue]; } - bb38: { + bb44: { unreachable; } - bb39: { + bb45: { StorageDead(_30); _31 = discriminant(_27); - switchInt(move _31) -> [0: bb17, 1: bb36, otherwise: bb38]; + switchInt(move _31) -> [0: bb19, 1: bb42, otherwise: bb44]; } - bb40: { - _27 = as Future>::poll(move _30, move _28) -> [return: bb39, unwind: bb10]; + bb46: { + _27 = as Future>::poll(move _30, move _28) -> [return: bb45, unwind: bb21]; } - bb41: { - _32 = yield(const false) -> [resume: bb46, drop: bb42]; + bb47: { + _32 = yield(const false) -> [resume: bb52, drop: bb48]; } - bb42: { + bb48: { StorageLive(_34); _33 = &mut _10; - _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb45, unwind continue]; + _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb51, unwind continue]; } - bb43: { + bb49: { unreachable; } - bb44: { + bb50: { StorageDead(_34); _35 = discriminant(_27); - switchInt(move _35) -> [0: bb6, 1: bb41, otherwise: bb43]; + switchInt(move _35) -> [0: bb20, 1: bb47, otherwise: bb49]; } - bb45: { - _27 = as Future>::poll(move _34, move _32) -> [return: bb44, unwind: bb10]; + bb51: { + _27 = as Future>::poll(move _34, move _32) -> [return: bb50, unwind: bb21]; } - bb46: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb46, unwind continue]; + bb52: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb52, unwind continue]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir index 7d16583b7ae96..6852a990e54f8 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir @@ -52,17 +52,15 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte bb0: { _38 = copy (_1.0: &mut {async fn body of double()}); _37 = discriminant((*_38)); - switchInt(move _37) -> [0: bb19, 2: bb26, 3: bb22, 4: bb23, 5: bb24, 6: bb25, otherwise: bb27]; + switchInt(move _37) -> [0: bb23, 2: bb30, 3: bb26, 4: bb27, 5: bb28, 6: bb29, otherwise: bb31]; } bb1: { - nop; nop; goto -> bb2; } bb2: { - nop; nop; goto -> bb3; } @@ -73,19 +71,16 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte } bb4: { - StorageDead(_14); _0 = Poll::<()>::Ready(const ()); return; } bb5 (cleanup): { - nop; nop; drop((((*_38) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; } bb6 (cleanup): { - nop; nop; drop((((*_38) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; } @@ -96,101 +91,120 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte } bb8 (cleanup): { - StorageDead(_14); - goto -> bb21; + goto -> bb25; } bb9: { + nop; + goto -> bb1; + } + + bb10 (cleanup): { + nop; + goto -> bb5; + } + + bb11: { + nop; + goto -> bb2; + } + + bb12 (cleanup): { + nop; + goto -> bb6; + } + + bb13: { _0 = Poll::<()>::Pending; discriminant((*_38)) = 4; return; } - bb10: { + bb14: { StorageLive(_25); _24 = &mut (((*_38) as variant#4).3: impl std::future::Future); - _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb13, unwind: bb21]; + _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb17, unwind: bb25]; } - bb11: { + bb15: { unreachable; } - bb12: { + bb16: { StorageDead(_25); _26 = discriminant(_18); - switchInt(move _26) -> [0: bb1, 1: bb9, otherwise: bb11]; + switchInt(move _26) -> [0: bb9, 1: bb13, otherwise: bb15]; } - bb13: { - _18 = as Future>::poll(move _25, move _23) -> [return: bb12, unwind: bb5]; + bb17: { + _18 = as Future>::poll(move _25, move _23) -> [return: bb16, unwind: bb10]; } - bb14: { + bb18: { _0 = Poll::<()>::Pending; discriminant((*_38)) = 6; return; } - bb15: { + bb19: { StorageLive(_34); _33 = &mut (((*_38) as variant#6).2: impl std::future::Future); - _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb17, unwind: bb21]; + _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb21, unwind: bb25]; } - bb16: { + bb20: { StorageDead(_34); _35 = discriminant(_27); - switchInt(move _35) -> [0: bb2, 1: bb14, otherwise: bb11]; + switchInt(move _35) -> [0: bb11, 1: bb18, otherwise: bb15]; } - bb17: { - _27 = as Future>::poll(move _34, move _32) -> [return: bb16, unwind: bb6]; + bb21: { + _27 = as Future>::poll(move _34, move _32) -> [return: bb20, unwind: bb12]; } - bb18: { + bb22: { _0 = Poll::<()>::Ready(const ()); return; } - bb19: { - goto -> bb20; + bb23: { + goto -> bb24; } - bb20: { - goto -> bb18; + bb24: { + goto -> bb22; } - bb21 (cleanup): { + bb25 (cleanup): { discriminant((*_38)) = 2; resume; } - bb22: { + bb26: { _19 = move _2; - goto -> bb10; + goto -> bb14; } - bb23: { + bb27: { _23 = move _2; - goto -> bb10; + goto -> bb14; } - bb24: { + bb28: { _28 = move _2; - goto -> bb15; + goto -> bb19; } - bb25: { + bb29: { _32 = move _2; - goto -> bb15; + goto -> bb19; } - bb26: { - assert(const false, "`async fn` resumed after panicking") -> [success: bb26, unwind continue]; + bb30: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb30, unwind continue]; } - bb27: { + bb31: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff index 8505963eb373e..aab8937384332 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff @@ -215,7 +215,7 @@ _26 = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; _0 = const (); - drop(_26) -> [return: bb10, unwind: bb44, drop: bb23]; -+ goto -> bb86; ++ goto -> bb88; } bb10: { @@ -227,7 +227,7 @@ bb11: { StorageDead(_25); - drop(_24) -> [return: bb12, unwind: bb46, drop: bb25]; -+ goto -> bb90; ++ goto -> bb94; } bb12: { @@ -239,44 +239,44 @@ bb13: { StorageDead(_23); - drop(_20) -> [return: bb14, unwind: bb48, drop: bb27]; -+ goto -> bb94; ++ goto -> bb100; } bb14: { StorageDead(_20); - drop(_19) -> [return: bb15, unwind: bb49, drop: bb28]; -+ goto -> bb98; ++ goto -> bb106; } bb15: { StorageDead(_19); StorageDead(_17); - drop(_15) -> [return: bb16, unwind: bb54, drop: bb30]; -+ goto -> bb102; ++ goto -> bb112; } bb16: { StorageDead(_15); - drop(_11) -> [return: bb17, unwind: bb58, drop: bb34]; -+ goto -> bb106; ++ goto -> bb118; } bb17: { StorageDead(_11); - drop(_8) -> [return: bb18, unwind: bb61, drop: bb37]; -+ goto -> bb110; ++ goto -> bb124; } bb18: { StorageDead(_8); - drop(_5) -> [return: bb19, unwind: bb64, drop: bb40]; -+ goto -> bb114; ++ goto -> bb130; } bb19: { StorageDead(_5); - drop(_4) -> [return: bb20, unwind: bb65, drop: bb41]; -+ goto -> bb118; ++ goto -> bb136; } bb20: { @@ -287,7 +287,7 @@ bb21: { StorageDead(_3); - drop(_1) -> [return: bb22, drop: bb43, unwind continue]; -+ goto -> bb122; ++ goto -> bb142; } bb22: { @@ -295,7 +295,6 @@ } bb23: { -+ StorageDead(_27); StorageDead(_26); - drop(_25) -> [return: bb24, unwind: bb68]; + goto -> bb24; @@ -308,7 +307,6 @@ } bb25: { -+ StorageDead(_31); StorageDead(_24); - drop(_23) -> [return: bb26, unwind: bb70]; + goto -> bb26; @@ -321,14 +319,12 @@ } bb27: { -+ StorageDead(_35); StorageDead(_20); - drop(_19) -> [return: bb28, unwind: bb72]; + goto -> bb28; } bb28: { -+ StorageDead(_39); StorageDead(_19); StorageDead(_17); - drop(_15) -> [return: bb30, unwind: bb73]; @@ -341,7 +337,6 @@ } bb30: { -+ StorageDead(_43); StorageDead(_15); - drop(_11) -> [return: bb34, unwind: bb76]; + goto -> bb34; @@ -365,7 +360,6 @@ } bb34: { -+ StorageDead(_47); StorageDead(_11); - drop(_8) -> [return: bb37, unwind: bb78]; + goto -> bb37; @@ -383,7 +377,6 @@ } bb37: { -+ StorageDead(_51); StorageDead(_8); - drop(_5) -> [return: bb40, unwind: bb80]; + goto -> bb40; @@ -401,14 +394,12 @@ } bb40: { -+ StorageDead(_55); StorageDead(_5); - drop(_4) -> [return: bb41, unwind: bb81]; + goto -> bb41; } bb41: { -+ StorageDead(_59); StorageDead(_4); - drop(_3) -> [return: bb42, unwind: bb82]; + goto -> bb42; @@ -421,12 +412,10 @@ } bb43: { -+ StorageDead(_63); coroutine_drop; } bb44 (cleanup): { -+ StorageDead(_27); StorageDead(_26); - drop(_25) -> [return: bb45, unwind terminate(cleanup)]; + goto -> bb45; @@ -438,7 +427,6 @@ } bb46 (cleanup): { -+ StorageDead(_31); StorageDead(_24); - drop(_23) -> [return: bb47, unwind terminate(cleanup)]; + goto -> bb47; @@ -450,13 +438,11 @@ } bb48 (cleanup): { -+ StorageDead(_35); StorageDead(_20); drop(_19) -> [return: bb49, unwind terminate(cleanup)]; } bb49 (cleanup): { -+ StorageDead(_39); StorageDead(_19); goto -> bb52; } @@ -482,7 +468,6 @@ } bb54 (cleanup): { -+ StorageDead(_43); StorageDead(_15); drop(_11) -> [return: bb58, unwind terminate(cleanup)]; } @@ -505,7 +490,6 @@ } bb58 (cleanup): { -+ StorageDead(_47); StorageDead(_11); drop(_8) -> [return: bb61, unwind terminate(cleanup)]; } @@ -522,7 +506,6 @@ } bb61 (cleanup): { -+ StorageDead(_51); StorageDead(_8); drop(_5) -> [return: bb64, unwind terminate(cleanup)]; } @@ -539,13 +522,11 @@ } bb64 (cleanup): { -+ StorageDead(_55); StorageDead(_5); drop(_4) -> [return: bb65, unwind terminate(cleanup)]; } bb65 (cleanup): { -+ StorageDead(_59); StorageDead(_4); drop(_3) -> [return: bb66, unwind terminate(cleanup)]; } @@ -556,7 +537,6 @@ } bb67 (cleanup): { -+ StorageDead(_63); resume; } @@ -654,198 +634,298 @@ + } + + bb84: { -+ async drop(_26; poll=_27) -> [return: bb83, unwind: bb44, drop: bb23]; ++ StorageDead(_27); ++ goto -> bb23; ++ } ++ ++ bb85 (cleanup): { ++ StorageDead(_27); ++ goto -> bb44; + } + -+ bb85: { ++ bb86: { ++ async drop(_26; poll=_27) -> [return: bb83, unwind: bb85, drop: bb84]; ++ } ++ ++ bb87: { + _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); + StorageLive(_27); -+ _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb84, unwind: bb44]; ++ _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb86, unwind: bb85]; + } + -+ bb86: { ++ bb88: { + _28 = &mut _26; -+ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb85, unwind: bb44]; ++ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb87, unwind: bb44]; + } + -+ bb87: { ++ bb89: { + StorageDead(_31); + goto -> bb12; + } + -+ bb88: { -+ async drop(_24; poll=_31) -> [return: bb87, unwind: bb46, drop: bb25]; ++ bb90: { ++ StorageDead(_31); ++ goto -> bb25; + } + -+ bb89: { ++ bb91 (cleanup): { ++ StorageDead(_31); ++ goto -> bb46; ++ } ++ ++ bb92: { ++ async drop(_24; poll=_31) -> [return: bb89, unwind: bb91, drop: bb90]; ++ } ++ ++ bb93: { + _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); + StorageLive(_31); -+ _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb88, unwind: bb46]; ++ _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb92, unwind: bb91]; + } + -+ bb90: { ++ bb94: { + _32 = &mut _24; -+ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb89, unwind: bb46]; ++ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb93, unwind: bb46]; + } + -+ bb91: { ++ bb95: { + StorageDead(_35); + goto -> bb14; + } + -+ bb92: { -+ async drop(_20; poll=_35) -> [return: bb91, unwind: bb48, drop: bb27]; ++ bb96: { ++ StorageDead(_35); ++ goto -> bb27; + } + -+ bb93: { ++ bb97 (cleanup): { ++ StorageDead(_35); ++ goto -> bb48; ++ } ++ ++ bb98: { ++ async drop(_20; poll=_35) -> [return: bb95, unwind: bb97, drop: bb96]; ++ } ++ ++ bb99: { + _38 = copy (_37.0: &mut AsyncReference<'_>); + StorageLive(_35); -+ _35 = async_drop_in_place::>(move _38) -> [return: bb92, unwind: bb48]; ++ _35 = async_drop_in_place::>(move _38) -> [return: bb98, unwind: bb97]; + } + -+ bb94: { ++ bb100: { + _36 = &mut _20; -+ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb93, unwind: bb48]; ++ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb99, unwind: bb48]; + } + -+ bb95: { ++ bb101: { + StorageDead(_39); + goto -> bb15; + } + -+ bb96: { -+ async drop(_19; poll=_39) -> [return: bb95, unwind: bb49, drop: bb28]; ++ bb102: { ++ StorageDead(_39); ++ goto -> bb28; ++ } ++ ++ bb103 (cleanup): { ++ StorageDead(_39); ++ goto -> bb49; ++ } ++ ++ bb104: { ++ async drop(_19; poll=_39) -> [return: bb101, unwind: bb103, drop: bb102]; + } + -+ bb97: { ++ bb105: { + _42 = copy (_41.0: &mut AsyncInt); + StorageLive(_39); -+ _39 = async_drop_in_place::(move _42) -> [return: bb96, unwind: bb49]; ++ _39 = async_drop_in_place::(move _42) -> [return: bb104, unwind: bb103]; + } + -+ bb98: { ++ bb106: { + _40 = &mut _19; -+ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb97, unwind: bb49]; ++ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb105, unwind: bb49]; + } + -+ bb99: { ++ bb107: { + StorageDead(_43); + goto -> bb16; + } + -+ bb100: { -+ async drop(_15; poll=_43) -> [return: bb99, unwind: bb54, drop: bb30]; ++ bb108: { ++ StorageDead(_43); ++ goto -> bb30; + } + -+ bb101: { ++ bb109 (cleanup): { ++ StorageDead(_43); ++ goto -> bb54; ++ } ++ ++ bb110: { ++ async drop(_15; poll=_43) -> [return: bb107, unwind: bb109, drop: bb108]; ++ } ++ ++ bb111: { + _46 = copy (_45.0: &mut AsyncEnum); + StorageLive(_43); -+ _43 = async_drop_in_place::(move _46) -> [return: bb100, unwind: bb54]; ++ _43 = async_drop_in_place::(move _46) -> [return: bb110, unwind: bb109]; + } + -+ bb102: { ++ bb112: { + _44 = &mut _15; -+ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb101, unwind: bb54]; ++ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb111, unwind: bb54]; + } + -+ bb103: { ++ bb113: { + StorageDead(_47); + goto -> bb17; + } + -+ bb104: { -+ async drop(_11; poll=_47) -> [return: bb103, unwind: bb58, drop: bb34]; ++ bb114: { ++ StorageDead(_47); ++ goto -> bb34; + } + -+ bb105: { ++ bb115 (cleanup): { ++ StorageDead(_47); ++ goto -> bb58; ++ } ++ ++ bb116: { ++ async drop(_11; poll=_47) -> [return: bb113, unwind: bb115, drop: bb114]; ++ } ++ ++ bb117: { + _50 = copy (_49.0: &mut SyncThenAsync); + StorageLive(_47); -+ _47 = async_drop_in_place::(move _50) -> [return: bb104, unwind: bb58]; ++ _47 = async_drop_in_place::(move _50) -> [return: bb116, unwind: bb115]; + } + -+ bb106: { ++ bb118: { + _48 = &mut _11; -+ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb105, unwind: bb58]; ++ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb117, unwind: bb58]; + } + -+ bb107: { ++ bb119: { + StorageDead(_51); + goto -> bb18; + } + -+ bb108: { -+ async drop(_8; poll=_51) -> [return: bb107, unwind: bb61, drop: bb37]; ++ bb120: { ++ StorageDead(_51); ++ goto -> bb37; + } + -+ bb109: { ++ bb121 (cleanup): { ++ StorageDead(_51); ++ goto -> bb61; ++ } ++ ++ bb122: { ++ async drop(_8; poll=_51) -> [return: bb119, unwind: bb121, drop: bb120]; ++ } ++ ++ bb123: { + _54 = copy (_53.0: &mut AsyncStruct); + StorageLive(_51); -+ _51 = async_drop_in_place::(move _54) -> [return: bb108, unwind: bb61]; ++ _51 = async_drop_in_place::(move _54) -> [return: bb122, unwind: bb121]; + } + -+ bb110: { ++ bb124: { + _52 = &mut _8; -+ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb109, unwind: bb61]; ++ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb123, unwind: bb61]; + } + -+ bb111: { ++ bb125: { + StorageDead(_55); + goto -> bb19; + } + -+ bb112: { -+ async drop(_5; poll=_55) -> [return: bb111, unwind: bb64, drop: bb40]; ++ bb126: { ++ StorageDead(_55); ++ goto -> bb40; + } + -+ bb113: { ++ bb127 (cleanup): { ++ StorageDead(_55); ++ goto -> bb64; ++ } ++ ++ bb128: { ++ async drop(_5; poll=_55) -> [return: bb125, unwind: bb127, drop: bb126]; ++ } ++ ++ bb129: { + _58 = copy (_57.0: &mut [AsyncInt; 2]); + StorageLive(_55); -+ _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb112, unwind: bb64]; ++ _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb128, unwind: bb127]; + } + -+ bb114: { ++ bb130: { + _56 = &mut _5; -+ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb113, unwind: bb64]; ++ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb129, unwind: bb64]; + } + -+ bb115: { ++ bb131: { + StorageDead(_59); + goto -> bb20; + } + -+ bb116: { -+ async drop(_4; poll=_59) -> [return: bb115, unwind: bb65, drop: bb41]; ++ bb132: { ++ StorageDead(_59); ++ goto -> bb41; + } + -+ bb117: { ++ bb133 (cleanup): { ++ StorageDead(_59); ++ goto -> bb65; ++ } ++ ++ bb134: { ++ async drop(_4; poll=_59) -> [return: bb131, unwind: bb133, drop: bb132]; ++ } ++ ++ bb135: { + _62 = copy (_61.0: &mut AsyncInt); + StorageLive(_59); -+ _59 = async_drop_in_place::(move _62) -> [return: bb116, unwind: bb65]; ++ _59 = async_drop_in_place::(move _62) -> [return: bb134, unwind: bb133]; + } + -+ bb118: { ++ bb136: { + _60 = &mut _4; -+ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb117, unwind: bb65]; ++ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb135, unwind: bb65]; + } + -+ bb119: { ++ bb137: { + StorageDead(_63); + goto -> bb22; + } + -+ bb120: { -+ async drop(_1; poll=_63) -> [return: bb119, unwind: bb67, drop: bb43]; ++ bb138: { ++ StorageDead(_63); ++ goto -> bb43; + } + -+ bb121: { ++ bb139 (cleanup): { ++ StorageDead(_63); ++ goto -> bb67; ++ } ++ ++ bb140: { ++ async drop(_1; poll=_63) -> [return: bb137, unwind: bb139, drop: bb138]; ++ } ++ ++ bb141: { + _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); + StorageLive(_63); -+ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb120, unwind: bb67]; ++ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb140, unwind: bb139]; + } + -+ bb122: { ++ bb142: { + _64 = &mut _1; -+ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb121, unwind: bb67]; ++ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb141, unwind: bb67]; } } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff index f2e670df1964f..ba5f8099dbe95 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff @@ -276,7 +276,7 @@ - goto -> bb1; + _150 = copy (_1.0: &mut {async fn body of elaborate_drops()}); + _149 = discriminant((*_150)); -+ switchInt(move _149) -> [0: bb147, 1: bb146, 2: bb145, 3: bb127, 4: bb128, 5: bb129, 6: bb130, 7: bb131, 8: bb132, 9: bb133, 10: bb134, 11: bb135, 12: bb136, 13: bb137, 14: bb138, 15: bb139, 16: bb140, 17: bb141, 18: bb142, 19: bb143, 20: bb144, otherwise: bb81]; ++ switchInt(move _149) -> [0: bb157, 1: bb156, 2: bb155, 3: bb137, 4: bb138, 5: bb139, 6: bb140, 7: bb141, 8: bb142, 9: bb143, 10: bb144, 11: bb145, 12: bb146, 13: bb147, 14: bb148, 15: bb149, 16: bb150, 17: bb151, 18: bb152, 19: bb153, 20: bb154, otherwise: bb91]; } bb1: { @@ -375,11 +375,11 @@ - StorageLive(_26); - _26 = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; - _0 = const (); -- goto -> bb55; +- goto -> bb57; + nop; + (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}) = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; + (((*_150) as variant#19).0: ()) = const (); -+ goto -> bb42; ++ goto -> bb43; } bb10: { @@ -390,8 +390,8 @@ bb11: { StorageDead(_25); -- goto -> bb59; -+ goto -> bb46; +- goto -> bb63; ++ goto -> bb48; } bb12: { @@ -402,51 +402,51 @@ bb13: { StorageDead(_23); -- goto -> bb63; -+ goto -> bb50; +- goto -> bb69; ++ goto -> bb53; } bb14: { - StorageDead(_20); -- goto -> bb67; +- goto -> bb75; + nop; -+ goto -> bb54; ++ goto -> bb58; } bb15: { - StorageDead(_19); + nop; StorageDead(_17); -- goto -> bb71; -+ goto -> bb58; +- goto -> bb81; ++ goto -> bb63; } bb16: { - StorageDead(_15); -- goto -> bb75; +- goto -> bb87; + nop; -+ goto -> bb62; ++ goto -> bb68; } bb17: { - StorageDead(_11); -- goto -> bb79; +- goto -> bb93; + nop; -+ goto -> bb66; ++ goto -> bb73; } bb18: { - StorageDead(_8); -- goto -> bb83; +- goto -> bb99; + nop; -+ goto -> bb70; ++ goto -> bb78; } bb19: { - StorageDead(_5); -- goto -> bb87; +- goto -> bb105; + nop; -+ goto -> bb74; ++ goto -> bb83; } bb20: { @@ -458,9 +458,9 @@ bb21: { - StorageDead(_3); -- goto -> bb91; +- goto -> bb111; + nop; -+ goto -> bb78; ++ goto -> bb88; } bb22: { @@ -470,10 +470,8 @@ } - bb23: { -- StorageDead(_27); - StorageDead(_26); + bb23 (cleanup): { -+ nop; + nop; goto -> bb24; } @@ -486,10 +484,8 @@ } - bb25: { -- StorageDead(_31); - StorageDead(_24); + bb25 (cleanup): { -+ nop; + nop; goto -> bb26; } @@ -502,35 +498,29 @@ } - bb27: { -- StorageDead(_35); - StorageDead(_20); - goto -> bb28; + bb27 (cleanup): { + nop; -+ nop; + drop((((*_150) as variant#10).6: AsyncInt)) -> [return: bb28, unwind terminate(cleanup)]; } - bb28: { -- StorageDead(_39); - StorageDead(_19); - StorageDead(_17); - goto -> bb29; + bb28 (cleanup): { + nop; -+ nop; + goto -> bb31; } - bb29: { -- StorageDead(_43); - StorageDead(_15); + bb29 (cleanup): { goto -> bb30; } - bb30: { -- StorageDead(_47); - StorageDead(_11); + bb30 (cleanup): { + StorageDead(_18); @@ -538,7 +528,6 @@ } - bb31: { -- StorageDead(_51); - StorageDead(_8); - goto -> bb32; + bb31 (cleanup): { @@ -547,22 +536,18 @@ } - bb32: { -- StorageDead(_55); - StorageDead(_5); - goto -> bb33; + bb32 (cleanup): { + nop; -+ nop; + drop((((*_150) as variant#14).4: SyncThenAsync)) -> [return: bb33, unwind terminate(cleanup)]; } - bb33: { -- StorageDead(_59); - StorageDead(_4); - goto -> bb34; + bb33 (cleanup): { + nop; -+ nop; + drop((((*_150) as variant#16).3: AsyncStruct)) -> [return: bb34, unwind terminate(cleanup)]; } @@ -571,25 +556,20 @@ - goto -> bb35; + bb34 (cleanup): { + nop; -+ nop; + drop((((*_150) as variant#18).2: [AsyncInt; 2])) -> [return: bb35, unwind terminate(cleanup)]; } - bb35: { -- StorageDead(_63); - coroutine_drop; + bb35 (cleanup): { + nop; -+ nop; + drop((((*_150) as variant#20).1: AsyncInt)) -> [return: bb36, unwind terminate(cleanup)]; } bb36 (cleanup): { -- StorageDead(_27); - StorageDead(_26); - goto -> bb37; + nop; -+ nop; + drop((((*_150) as variant#20).0: SyncInt)) -> [return: bb37, unwind terminate(cleanup)]; } @@ -601,11 +581,9 @@ } bb38 (cleanup): { -- StorageDead(_31); - StorageDead(_24); - goto -> bb39; -+ StorageDead(_63); -+ goto -> bb126; ++ goto -> bb136; } - bb39 (cleanup): { @@ -616,309 +594,379 @@ + goto -> bb10; } -- bb40 (cleanup): { -- StorageDead(_35); + bb40 (cleanup): { - StorageDead(_20); - drop(_19) -> [return: bb41, unwind terminate(cleanup)]; -+ bb40: { -+ _68 = move _2; -+ goto -> bb80; ++ nop; ++ goto -> bb23; } - bb41 (cleanup): { -- StorageDead(_39); - StorageDead(_19); - goto -> bb44; + bb41: { -+ _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); -+ nop; -+ (((*_150) as variant#4).10: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb40, unwind: bb23]; ++ _68 = move _2; ++ goto -> bb90; } - bb42 (cleanup): { - goto -> bb43; + bb42: { -+ _28 = &mut (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); -+ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb41, unwind: bb23]; ++ _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ nop; ++ (((*_150) as variant#4).10: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb41, unwind: bb40]; } - bb43 (cleanup): { - StorageDead(_18); - goto -> bb44; + bb43: { -+ nop; -+ goto -> bb12; ++ _28 = &mut (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb42, unwind: bb23]; } - bb44 (cleanup): { - StorageDead(_17); - drop(_15) -> [return: bb45, unwind terminate(cleanup)]; + bb44: { -+ _77 = move _2; -+ goto -> bb86; ++ nop; ++ goto -> bb12; } -- bb45 (cleanup): { -- StorageDead(_43); + bb45 (cleanup): { - StorageDead(_15); - drop(_11) -> [return: bb46, unwind terminate(cleanup)]; -+ bb45: { -+ _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); + nop; -+ (((*_150) as variant#6).9: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb44, unwind: bb25]; ++ goto -> bb25; } - bb46 (cleanup): { -- StorageDead(_47); - StorageDead(_11); - drop(_8) -> [return: bb47, unwind terminate(cleanup)]; + bb46: { -+ _32 = &mut (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); -+ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb45, unwind: bb25]; ++ _77 = move _2; ++ goto -> bb96; } - bb47 (cleanup): { -- StorageDead(_51); - StorageDead(_8); - drop(_5) -> [return: bb48, unwind terminate(cleanup)]; + bb47: { ++ _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); + nop; -+ goto -> bb14; ++ (((*_150) as variant#6).9: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb46, unwind: bb45]; } - bb48 (cleanup): { -- StorageDead(_55); - StorageDead(_5); - drop(_4) -> [return: bb49, unwind terminate(cleanup)]; + bb48: { -+ _86 = move _2; -+ goto -> bb91; ++ _32 = &mut (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); ++ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb47, unwind: bb25]; } - bb49 (cleanup): { -- StorageDead(_59); - StorageDead(_4); - drop(_3) -> [return: bb50, unwind terminate(cleanup)]; + bb49: { -+ _38 = copy (_37.0: &mut AsyncReference<'_>); + nop; -+ (((*_150) as variant#8).8: impl std::future::Future) = async_drop_in_place::>(move _38) -> [return: bb48, unwind: bb27]; ++ goto -> bb14; } -- bb50 (cleanup): { + bb50 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb51, unwind terminate(cleanup)]; -+ bb50: { -+ _36 = &mut (((*_150) as variant#8).7: AsyncReference<'_>); -+ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb49, unwind: bb27]; ++ nop; ++ goto -> bb27; } - bb51 (cleanup): { -- StorageDead(_63); - resume; + bb51: { -+ nop; -+ goto -> bb15; ++ _86 = move _2; ++ goto -> bb101; } bb52: { - StorageDead(_27); - goto -> bb10; -+ _95 = move _2; -+ goto -> bb96; ++ _38 = copy (_37.0: &mut AsyncReference<'_>); ++ nop; ++ (((*_150) as variant#8).8: impl std::future::Future) = async_drop_in_place::>(move _38) -> [return: bb51, unwind: bb50]; } bb53: { -- async drop(_26; poll=_27) -> [return: bb52, unwind: bb36, drop: bb23]; -+ _42 = copy (_41.0: &mut AsyncInt); +- StorageDead(_27); +- goto -> bb23; ++ _36 = &mut (((*_150) as variant#8).7: AsyncReference<'_>); ++ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb52, unwind: bb27]; + } + +- bb54 (cleanup): { +- StorageDead(_27); +- goto -> bb36; ++ bb54: { ++ nop; ++ goto -> bb15; + } + +- bb55: { +- async drop(_26; poll=_27) -> [return: bb52, unwind: bb54, drop: bb53]; ++ bb55 (cleanup): { + nop; -+ (((*_150) as variant#10).7: impl std::future::Future) = async_drop_in_place::(move _42) -> [return: bb52, unwind: bb28]; ++ goto -> bb28; } - bb54: { + bb56: { - _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); - StorageLive(_27); -- _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb53, unwind: bb36]; -+ _40 = &mut (((*_150) as variant#10).6: AsyncInt); -+ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb53, unwind: bb28]; +- _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb55, unwind: bb54]; ++ _95 = move _2; ++ goto -> bb106; } - bb55: { + bb57: { - _28 = &mut _26; -- _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb54, unwind: bb36]; +- _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb56, unwind: bb36]; ++ _42 = copy (_41.0: &mut AsyncInt); + nop; -+ goto -> bb16; ++ (((*_150) as variant#10).7: impl std::future::Future) = async_drop_in_place::(move _42) -> [return: bb56, unwind: bb55]; } - bb56: { + bb58: { - StorageDead(_31); - goto -> bb12; -+ _104 = move _2; -+ goto -> bb101; ++ _40 = &mut (((*_150) as variant#10).6: AsyncInt); ++ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb57, unwind: bb28]; } - bb57: { -- async drop(_24; poll=_31) -> [return: bb56, unwind: bb38, drop: bb25]; -+ _46 = copy (_45.0: &mut AsyncEnum); + bb59: { +- StorageDead(_31); +- goto -> bb25; ++ nop; ++ goto -> bb16; + } + + bb60 (cleanup): { +- StorageDead(_31); +- goto -> bb38; + nop; -+ (((*_150) as variant#12).6: impl std::future::Future) = async_drop_in_place::(move _46) -> [return: bb56, unwind: bb32]; ++ goto -> bb32; } - bb58: { + bb61: { +- async drop(_24; poll=_31) -> [return: bb58, unwind: bb60, drop: bb59]; ++ _104 = move _2; ++ goto -> bb111; + } + + bb62: { - _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); - StorageLive(_31); -- _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb57, unwind: bb38]; -+ _44 = &mut (((*_150) as variant#12).5: AsyncEnum); -+ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb57, unwind: bb32]; +- _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb61, unwind: bb60]; ++ _46 = copy (_45.0: &mut AsyncEnum); ++ nop; ++ (((*_150) as variant#12).6: impl std::future::Future) = async_drop_in_place::(move _46) -> [return: bb61, unwind: bb60]; } - bb59: { + bb63: { - _32 = &mut _24; -- _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb58, unwind: bb38]; +- _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb62, unwind: bb38]; ++ _44 = &mut (((*_150) as variant#12).5: AsyncEnum); ++ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb62, unwind: bb32]; + } + + bb64: { +- StorageDead(_35); +- goto -> bb14; + nop; + goto -> bb17; } - bb60: { +- bb65: { - StorageDead(_35); -- goto -> bb14; +- goto -> bb27; ++ bb65 (cleanup): { ++ nop; ++ goto -> bb33; + } + +- bb66 (cleanup): { +- StorageDead(_35); +- goto -> bb40; ++ bb66: { + _113 = move _2; -+ goto -> bb106; ++ goto -> bb116; } - bb61: { -- async drop(_20; poll=_35) -> [return: bb60, unwind: bb40, drop: bb27]; + bb67: { +- async drop(_20; poll=_35) -> [return: bb64, unwind: bb66, drop: bb65]; + _50 = copy (_49.0: &mut SyncThenAsync); + nop; -+ (((*_150) as variant#14).5: impl std::future::Future) = async_drop_in_place::(move _50) -> [return: bb60, unwind: bb33]; ++ (((*_150) as variant#14).5: impl std::future::Future) = async_drop_in_place::(move _50) -> [return: bb66, unwind: bb65]; } - bb62: { + bb68: { - _38 = copy (_37.0: &mut AsyncReference<'_>); - StorageLive(_35); -- _35 = async_drop_in_place::>(move _38) -> [return: bb61, unwind: bb40]; +- _35 = async_drop_in_place::>(move _38) -> [return: bb67, unwind: bb66]; + _48 = &mut (((*_150) as variant#14).4: SyncThenAsync); -+ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb61, unwind: bb33]; ++ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb67, unwind: bb33]; } - bb63: { + bb69: { - _36 = &mut _20; -- _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb62, unwind: bb40]; +- _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb68, unwind: bb40]; + nop; + goto -> bb18; } - bb64: { +- bb70: { - StorageDead(_39); - goto -> bb15; ++ bb70 (cleanup): { ++ nop; ++ goto -> bb34; + } + + bb71: { +- StorageDead(_39); +- goto -> bb28; + _122 = move _2; -+ goto -> bb111; ++ goto -> bb121; } - bb65: { -- async drop(_19; poll=_39) -> [return: bb64, unwind: bb41, drop: bb28]; +- bb72 (cleanup): { +- StorageDead(_39); +- goto -> bb41; ++ bb72: { + _54 = copy (_53.0: &mut AsyncStruct); + nop; -+ (((*_150) as variant#16).4: impl std::future::Future) = async_drop_in_place::(move _54) -> [return: bb64, unwind: bb34]; ++ (((*_150) as variant#16).4: impl std::future::Future) = async_drop_in_place::(move _54) -> [return: bb71, unwind: bb70]; } - bb66: { + bb73: { +- async drop(_19; poll=_39) -> [return: bb70, unwind: bb72, drop: bb71]; ++ _52 = &mut (((*_150) as variant#16).3: AsyncStruct); ++ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb72, unwind: bb34]; + } + + bb74: { - _42 = copy (_41.0: &mut AsyncInt); - StorageLive(_39); -- _39 = async_drop_in_place::(move _42) -> [return: bb65, unwind: bb41]; -+ _52 = &mut (((*_150) as variant#16).3: AsyncStruct); -+ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb65, unwind: bb34]; +- _39 = async_drop_in_place::(move _42) -> [return: bb73, unwind: bb72]; ++ nop; ++ goto -> bb19; } - bb67: { +- bb75: { - _40 = &mut _19; -- _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb66, unwind: bb41]; +- _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb74, unwind: bb41]; ++ bb75 (cleanup): { + nop; -+ goto -> bb19; ++ goto -> bb35; } - bb68: { + bb76: { - StorageDead(_43); - goto -> bb16; + _131 = move _2; -+ goto -> bb116; ++ goto -> bb126; } - bb69: { -- async drop(_15; poll=_43) -> [return: bb68, unwind: bb45, drop: bb29]; + bb77: { +- StorageDead(_43); +- goto -> bb29; + _58 = copy (_57.0: &mut [AsyncInt; 2]); + nop; -+ (((*_150) as variant#18).3: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb68, unwind: bb35]; ++ (((*_150) as variant#18).3: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb76, unwind: bb75]; } - bb70: { -- _46 = copy (_45.0: &mut AsyncEnum); -- StorageLive(_43); -- _43 = async_drop_in_place::(move _46) -> [return: bb69, unwind: bb45]; +- bb78 (cleanup): { +- StorageDead(_43); +- goto -> bb45; ++ bb78: { + _56 = &mut (((*_150) as variant#18).2: [AsyncInt; 2]); -+ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb69, unwind: bb35]; ++ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb77, unwind: bb35]; } - bb71: { -- _44 = &mut _15; -- _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb70, unwind: bb45]; + bb79: { +- async drop(_15; poll=_43) -> [return: bb76, unwind: bb78, drop: bb77]; + nop; + goto -> bb20; } - bb72: { -- StorageDead(_47); -- goto -> bb17; +- bb80: { +- _46 = copy (_45.0: &mut AsyncEnum); +- StorageLive(_43); +- _43 = async_drop_in_place::(move _46) -> [return: bb79, unwind: bb78]; ++ bb80 (cleanup): { ++ nop; ++ goto -> bb36; + } + + bb81: { +- _44 = &mut _15; +- _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb80, unwind: bb45]; + _140 = move _2; -+ goto -> bb121; ++ goto -> bb131; } - bb73: { -- async drop(_11; poll=_47) -> [return: bb72, unwind: bb46, drop: bb30]; + bb82: { +- StorageDead(_47); +- goto -> bb17; + _62 = copy (_61.0: &mut AsyncInt); + nop; -+ (((*_150) as variant#20).2: impl std::future::Future) = async_drop_in_place::(move _62) -> [return: bb72, unwind: bb36]; ++ (((*_150) as variant#20).2: impl std::future::Future) = async_drop_in_place::(move _62) -> [return: bb81, unwind: bb80]; } - bb74: { -- _50 = copy (_49.0: &mut SyncThenAsync); -- StorageLive(_47); -- _47 = async_drop_in_place::(move _50) -> [return: bb73, unwind: bb46]; + bb83: { +- StorageDead(_47); +- goto -> bb30; + _60 = &mut (((*_150) as variant#20).1: AsyncInt); -+ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb73, unwind: bb36]; ++ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb82, unwind: bb36]; } - bb75: { -- _48 = &mut _11; -- _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb74, unwind: bb46]; +- bb84 (cleanup): { +- StorageDead(_47); +- goto -> bb46; ++ bb84: { + StorageDead(_63); + goto -> bb22; } - bb76: { -- StorageDead(_51); -- goto -> bb18; -+ goto -> bb125; +- bb85: { +- async drop(_11; poll=_47) -> [return: bb82, unwind: bb84, drop: bb83]; ++ bb85 (cleanup): { ++ StorageDead(_63); ++ goto -> bb38; } - bb77: { -- async drop(_8; poll=_51) -> [return: bb76, unwind: bb47, drop: bb31]; + bb86: { +- _50 = copy (_49.0: &mut SyncThenAsync); +- StorageLive(_47); +- _47 = async_drop_in_place::(move _50) -> [return: bb85, unwind: bb84]; ++ goto -> bb135; + } + + bb87: { +- _48 = &mut _11; +- _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb86, unwind: bb46]; + _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); + StorageLive(_63); -+ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb76, unwind: bb38]; ++ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb86, unwind: bb85]; } - bb78: { -- _54 = copy (_53.0: &mut AsyncStruct); -- StorageLive(_51); -- _51 = async_drop_in_place::(move _54) -> [return: bb77, unwind: bb47]; + bb88: { +- StorageDead(_51); +- goto -> bb18; + _64 = &mut (*_150); -+ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb77, unwind: bb38]; ++ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb87, unwind: bb38]; } - bb79: { -- _52 = &mut _8; -- _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb78, unwind: bb47]; + bb89: { +- StorageDead(_51); +- goto -> bb31; + _0 = Poll::<()>::Pending; + StorageDead(_17); + StorageDead(_23); @@ -927,42 +975,44 @@ + return; } - bb80: { -- StorageDead(_55); -- goto -> bb19; +- bb90 (cleanup): { +- StorageDead(_51); +- goto -> bb47; ++ bb90: { + StorageLive(_70); + _69 = &mut (((*_150) as variant#4).10: impl std::future::Future); -+ _70 = Pin::<&mut impl Future>::new_unchecked(move _69) -> [return: bb83, unwind: bb126]; ++ _70 = Pin::<&mut impl Future>::new_unchecked(move _69) -> [return: bb93, unwind: bb136]; } - bb81: { -- async drop(_5; poll=_55) -> [return: bb80, unwind: bb48, drop: bb32]; + bb91: { +- async drop(_8; poll=_51) -> [return: bb88, unwind: bb90, drop: bb89]; + unreachable; } - bb82: { -- _58 = copy (_57.0: &mut [AsyncInt; 2]); -- StorageLive(_55); -- _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb81, unwind: bb48]; + bb92: { +- _54 = copy (_53.0: &mut AsyncStruct); +- StorageLive(_51); +- _51 = async_drop_in_place::(move _54) -> [return: bb91, unwind: bb90]; + StorageDead(_70); + _71 = discriminant(_67); -+ switchInt(move _71) -> [0: bb39, 1: bb79, otherwise: bb81]; ++ switchInt(move _71) -> [0: bb39, 1: bb89, otherwise: bb91]; } - bb83: { -- _56 = &mut _5; -- _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb82, unwind: bb48]; -+ _67 = as Future>::poll(move _70, move _68) -> [return: bb82, unwind: bb23]; + bb93: { +- _52 = &mut _8; +- _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb92, unwind: bb47]; ++ _67 = as Future>::poll(move _70, move _68) -> [return: bb92, unwind: bb40]; } - bb84: { -- StorageDead(_59); -- goto -> bb20; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb84, unwind: bb126]; + bb94: { +- StorageDead(_55); +- goto -> bb19; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb94, unwind: bb136]; } - bb85: { -- async drop(_4; poll=_59) -> [return: bb84, unwind: bb49, drop: bb33]; + bb95: { +- StorageDead(_55); +- goto -> bb32; + _0 = Poll::<()>::Pending; + StorageDead(_17); + StorageDead(_23); @@ -970,345 +1020,367 @@ + return; } - bb86: { -- _62 = copy (_61.0: &mut AsyncInt); -- StorageLive(_59); -- _59 = async_drop_in_place::(move _62) -> [return: bb85, unwind: bb49]; +- bb96 (cleanup): { +- StorageDead(_55); +- goto -> bb48; ++ bb96: { + StorageLive(_79); + _78 = &mut (((*_150) as variant#6).9: impl std::future::Future); -+ _79 = Pin::<&mut impl Future>::new_unchecked(move _78) -> [return: bb88, unwind: bb126]; ++ _79 = Pin::<&mut impl Future>::new_unchecked(move _78) -> [return: bb98, unwind: bb136]; } - bb87: { -- _60 = &mut _4; -- _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb86, unwind: bb49]; + bb97: { +- async drop(_5; poll=_55) -> [return: bb94, unwind: bb96, drop: bb95]; + StorageDead(_79); + _80 = discriminant(_76); -+ switchInt(move _80) -> [0: bb43, 1: bb85, otherwise: bb81]; ++ switchInt(move _80) -> [0: bb44, 1: bb95, otherwise: bb91]; } - bb88: { -- StorageDead(_63); -- goto -> bb22; -+ _76 = as Future>::poll(move _79, move _77) -> [return: bb87, unwind: bb25]; + bb98: { +- _58 = copy (_57.0: &mut [AsyncInt; 2]); +- StorageLive(_55); +- _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb97, unwind: bb96]; ++ _76 = as Future>::poll(move _79, move _77) -> [return: bb97, unwind: bb45]; } - bb89: { -- async drop(_1; poll=_63) -> [return: bb88, unwind: bb51, drop: bb35]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb89, unwind: bb126]; + bb99: { +- _56 = &mut _5; +- _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb98, unwind: bb48]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb99, unwind: bb136]; } - bb90: { -- _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); -- StorageLive(_63); -- _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb89, unwind: bb51]; + bb100: { +- StorageDead(_59); +- goto -> bb20; + _0 = Poll::<()>::Pending; + StorageDead(_17); + discriminant((*_150)) = 7; + return; } - bb91: { -- _64 = &mut _1; -- _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb90, unwind: bb51]; + bb101: { +- StorageDead(_59); +- goto -> bb33; + StorageLive(_88); + _87 = &mut (((*_150) as variant#8).8: impl std::future::Future); -+ _88 = Pin::<&mut impl Future>::new_unchecked(move _87) -> [return: bb93, unwind: bb126]; -+ } -+ -+ bb92: { ++ _88 = Pin::<&mut impl Future>::new_unchecked(move _87) -> [return: bb103, unwind: bb136]; + } + +- bb102 (cleanup): { +- StorageDead(_59); +- goto -> bb49; ++ bb102: { + StorageDead(_88); + _89 = discriminant(_85); -+ switchInt(move _89) -> [0: bb47, 1: bb90, otherwise: bb81]; -+ } -+ -+ bb93: { -+ _85 = as Future>::poll(move _88, move _86) -> [return: bb92, unwind: bb27]; -+ } -+ -+ bb94: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb94, unwind: bb126]; -+ } -+ -+ bb95: { ++ switchInt(move _89) -> [0: bb49, 1: bb100, otherwise: bb91]; + } + + bb103: { +- async drop(_4; poll=_59) -> [return: bb100, unwind: bb102, drop: bb101]; ++ _85 = as Future>::poll(move _88, move _86) -> [return: bb102, unwind: bb50]; + } + + bb104: { +- _62 = copy (_61.0: &mut AsyncInt); +- StorageLive(_59); +- _59 = async_drop_in_place::(move _62) -> [return: bb103, unwind: bb102]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb104, unwind: bb136]; + } + + bb105: { +- _60 = &mut _4; +- _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb104, unwind: bb49]; + _0 = Poll::<()>::Pending; + StorageDead(_17); + discriminant((*_150)) = 9; + return; -+ } -+ -+ bb96: { + } + + bb106: { +- StorageDead(_63); +- goto -> bb22; + StorageLive(_97); + _96 = &mut (((*_150) as variant#10).7: impl std::future::Future); -+ _97 = Pin::<&mut impl Future>::new_unchecked(move _96) -> [return: bb98, unwind: bb126]; -+ } -+ -+ bb97: { ++ _97 = Pin::<&mut impl Future>::new_unchecked(move _96) -> [return: bb108, unwind: bb136]; + } + + bb107: { +- StorageDead(_63); +- goto -> bb35; + StorageDead(_97); + _98 = discriminant(_94); -+ switchInt(move _98) -> [0: bb51, 1: bb95, otherwise: bb81]; -+ } -+ -+ bb98: { -+ _94 = as Future>::poll(move _97, move _95) -> [return: bb97, unwind: bb28]; -+ } -+ -+ bb99: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb99, unwind: bb126]; -+ } -+ -+ bb100: { ++ switchInt(move _98) -> [0: bb54, 1: bb105, otherwise: bb91]; + } + +- bb108 (cleanup): { +- StorageDead(_63); +- goto -> bb51; ++ bb108: { ++ _94 = as Future>::poll(move _97, move _95) -> [return: bb107, unwind: bb55]; + } + + bb109: { +- async drop(_1; poll=_63) -> [return: bb106, unwind: bb108, drop: bb107]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb109, unwind: bb136]; + } + + bb110: { +- _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); +- StorageLive(_63); +- _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb109, unwind: bb108]; + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 11; + return; -+ } -+ -+ bb101: { + } + + bb111: { +- _64 = &mut _1; +- _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb110, unwind: bb51]; + StorageLive(_106); + _105 = &mut (((*_150) as variant#12).6: impl std::future::Future); -+ _106 = Pin::<&mut impl Future>::new_unchecked(move _105) -> [return: bb103, unwind: bb126]; ++ _106 = Pin::<&mut impl Future>::new_unchecked(move _105) -> [return: bb113, unwind: bb136]; + } + -+ bb102: { ++ bb112: { + StorageDead(_106); + _107 = discriminant(_103); -+ switchInt(move _107) -> [0: bb55, 1: bb100, otherwise: bb81]; ++ switchInt(move _107) -> [0: bb59, 1: bb110, otherwise: bb91]; + } + -+ bb103: { -+ _103 = as Future>::poll(move _106, move _104) -> [return: bb102, unwind: bb32]; ++ bb113: { ++ _103 = as Future>::poll(move _106, move _104) -> [return: bb112, unwind: bb60]; + } + -+ bb104: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb104, unwind: bb126]; ++ bb114: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb114, unwind: bb136]; + } + -+ bb105: { ++ bb115: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 13; + return; + } + -+ bb106: { ++ bb116: { + StorageLive(_115); + _114 = &mut (((*_150) as variant#14).5: impl std::future::Future); -+ _115 = Pin::<&mut impl Future>::new_unchecked(move _114) -> [return: bb108, unwind: bb126]; ++ _115 = Pin::<&mut impl Future>::new_unchecked(move _114) -> [return: bb118, unwind: bb136]; + } + -+ bb107: { ++ bb117: { + StorageDead(_115); + _116 = discriminant(_112); -+ switchInt(move _116) -> [0: bb59, 1: bb105, otherwise: bb81]; ++ switchInt(move _116) -> [0: bb64, 1: bb115, otherwise: bb91]; + } + -+ bb108: { -+ _112 = as Future>::poll(move _115, move _113) -> [return: bb107, unwind: bb33]; ++ bb118: { ++ _112 = as Future>::poll(move _115, move _113) -> [return: bb117, unwind: bb65]; + } + -+ bb109: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb109, unwind: bb126]; ++ bb119: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb119, unwind: bb136]; + } + -+ bb110: { ++ bb120: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 15; + return; + } + -+ bb111: { ++ bb121: { + StorageLive(_124); + _123 = &mut (((*_150) as variant#16).4: impl std::future::Future); -+ _124 = Pin::<&mut impl Future>::new_unchecked(move _123) -> [return: bb113, unwind: bb126]; ++ _124 = Pin::<&mut impl Future>::new_unchecked(move _123) -> [return: bb123, unwind: bb136]; + } + -+ bb112: { ++ bb122: { + StorageDead(_124); + _125 = discriminant(_121); -+ switchInt(move _125) -> [0: bb63, 1: bb110, otherwise: bb81]; ++ switchInt(move _125) -> [0: bb69, 1: bb120, otherwise: bb91]; + } + -+ bb113: { -+ _121 = as Future>::poll(move _124, move _122) -> [return: bb112, unwind: bb34]; ++ bb123: { ++ _121 = as Future>::poll(move _124, move _122) -> [return: bb122, unwind: bb70]; + } + -+ bb114: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb114, unwind: bb126]; ++ bb124: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb124, unwind: bb136]; + } + -+ bb115: { ++ bb125: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 17; + return; + } + -+ bb116: { ++ bb126: { + StorageLive(_133); + _132 = &mut (((*_150) as variant#18).3: impl std::future::Future); -+ _133 = Pin::<&mut impl Future>::new_unchecked(move _132) -> [return: bb118, unwind: bb126]; ++ _133 = Pin::<&mut impl Future>::new_unchecked(move _132) -> [return: bb128, unwind: bb136]; + } + -+ bb117: { ++ bb127: { + StorageDead(_133); + _134 = discriminant(_130); -+ switchInt(move _134) -> [0: bb67, 1: bb115, otherwise: bb81]; ++ switchInt(move _134) -> [0: bb74, 1: bb125, otherwise: bb91]; + } + -+ bb118: { -+ _130 = as Future>::poll(move _133, move _131) -> [return: bb117, unwind: bb35]; ++ bb128: { ++ _130 = as Future>::poll(move _133, move _131) -> [return: bb127, unwind: bb75]; + } + -+ bb119: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb119, unwind: bb126]; ++ bb129: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb129, unwind: bb136]; + } + -+ bb120: { ++ bb130: { + _0 = Poll::<()>::Pending; + discriminant((*_150)) = 19; + return; + } + -+ bb121: { ++ bb131: { + StorageLive(_142); + _141 = &mut (((*_150) as variant#20).2: impl std::future::Future); -+ _142 = Pin::<&mut impl Future>::new_unchecked(move _141) -> [return: bb123, unwind: bb126]; ++ _142 = Pin::<&mut impl Future>::new_unchecked(move _141) -> [return: bb133, unwind: bb136]; + } + -+ bb122: { ++ bb132: { + StorageDead(_142); + _143 = discriminant(_139); -+ switchInt(move _143) -> [0: bb71, 1: bb120, otherwise: bb81]; ++ switchInt(move _143) -> [0: bb79, 1: bb130, otherwise: bb91]; + } + -+ bb123: { -+ _139 = as Future>::poll(move _142, move _140) -> [return: bb122, unwind: bb36]; ++ bb133: { ++ _139 = as Future>::poll(move _142, move _140) -> [return: bb132, unwind: bb80]; + } + -+ bb124: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb124, unwind: bb126]; ++ bb134: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb134, unwind: bb136]; + } + -+ bb125: { -+ goto -> bb75; ++ bb135: { ++ goto -> bb84; + } + -+ bb126 (cleanup): { ++ bb136 (cleanup): { + discriminant((*_150)) = 2; + resume; + } + -+ bb127: { ++ bb137: { + StorageLive(_17); + StorageLive(_23); + StorageLive(_25); + _68 = move _2; -+ goto -> bb80; ++ goto -> bb90; + } + -+ bb128: { ++ bb138: { + StorageLive(_17); + StorageLive(_23); + StorageLive(_25); + _72 = move _2; -+ goto -> bb84; ++ goto -> bb94; + } + -+ bb129: { ++ bb139: { + StorageLive(_17); + StorageLive(_23); + _77 = move _2; -+ goto -> bb86; ++ goto -> bb96; + } + -+ bb130: { ++ bb140: { + StorageLive(_17); + StorageLive(_23); + _81 = move _2; -+ goto -> bb89; ++ goto -> bb99; + } + -+ bb131: { ++ bb141: { + StorageLive(_17); + _86 = move _2; -+ goto -> bb91; ++ goto -> bb101; + } + -+ bb132: { ++ bb142: { + StorageLive(_17); + _90 = move _2; -+ goto -> bb94; ++ goto -> bb104; + } + -+ bb133: { ++ bb143: { + StorageLive(_17); + _95 = move _2; -+ goto -> bb96; ++ goto -> bb106; + } + -+ bb134: { ++ bb144: { + StorageLive(_17); + _99 = move _2; -+ goto -> bb99; ++ goto -> bb109; + } + -+ bb135: { ++ bb145: { + _104 = move _2; -+ goto -> bb101; ++ goto -> bb111; + } + -+ bb136: { ++ bb146: { + _108 = move _2; -+ goto -> bb104; ++ goto -> bb114; + } + -+ bb137: { ++ bb147: { + _113 = move _2; -+ goto -> bb106; ++ goto -> bb116; + } + -+ bb138: { ++ bb148: { + _117 = move _2; -+ goto -> bb109; ++ goto -> bb119; + } + -+ bb139: { ++ bb149: { + _122 = move _2; -+ goto -> bb111; ++ goto -> bb121; + } + -+ bb140: { ++ bb150: { + _126 = move _2; -+ goto -> bb114; ++ goto -> bb124; + } + -+ bb141: { ++ bb151: { + _131 = move _2; -+ goto -> bb116; ++ goto -> bb126; + } + -+ bb142: { ++ bb152: { + _135 = move _2; -+ goto -> bb119; ++ goto -> bb129; + } + -+ bb143: { ++ bb153: { + _140 = move _2; -+ goto -> bb121; ++ goto -> bb131; + } + -+ bb144: { ++ bb154: { + _144 = move _2; -+ goto -> bb124; ++ goto -> bb134; + } + -+ bb145: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb145, unwind continue]; ++ bb155: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb155, unwind continue]; + } + -+ bb146: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb146, unwind continue]; ++ bb156: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb156, unwind continue]; + } + -+ bb147: { ++ bb157: { + nop; + (((*_150) as variant#20).0: SyncInt) = SyncInt(const 0_i32); + nop; diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff index 8155d7c7239b6..63d19fd2cf061 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff @@ -30,7 +30,7 @@ _4 = AsyncInt(const 0_i32); _0 = const (); - drop(_4) -> [return: bb1, unwind: bb7, drop: bb4]; -+ goto -> bb14; ++ goto -> bb16; } bb1: { @@ -41,7 +41,7 @@ bb2: { StorageDead(_3); - drop(_1) -> [return: bb3, drop: bb6, unwind continue]; -+ goto -> bb18; ++ goto -> bb22; } bb3: { @@ -49,7 +49,6 @@ } bb4: { -+ StorageDead(_5); StorageDead(_4); - drop(_3) -> [return: bb5, unwind: bb10]; + goto -> bb5; @@ -62,12 +61,10 @@ } bb6: { -+ StorageDead(_9); coroutine_drop; } bb7 (cleanup): { -+ StorageDead(_5); StorageDead(_4); drop(_3) -> [return: bb8, unwind terminate(cleanup)]; } @@ -78,7 +75,6 @@ } bb9 (cleanup): { -+ StorageDead(_9); resume; } @@ -94,38 +90,58 @@ + } + + bb12: { -+ async drop(_4; poll=_5) -> [return: bb11, unwind: bb7, drop: bb4]; ++ StorageDead(_5); ++ goto -> bb4; ++ } ++ ++ bb13 (cleanup): { ++ StorageDead(_5); ++ goto -> bb7; ++ } ++ ++ bb14: { ++ async drop(_4; poll=_5) -> [return: bb11, unwind: bb13, drop: bb12]; + } + -+ bb13: { ++ bb15: { + _8 = copy (_7.0: &mut AsyncInt); + StorageLive(_5); -+ _5 = async_drop_in_place::(move _8) -> [return: bb12, unwind: bb7]; ++ _5 = async_drop_in_place::(move _8) -> [return: bb14, unwind: bb13]; + } + -+ bb14: { ++ bb16: { + _6 = &mut _4; -+ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb13, unwind: bb7]; ++ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb15, unwind: bb7]; + } + -+ bb15: { ++ bb17: { + StorageDead(_9); + goto -> bb3; + } + -+ bb16: { -+ async drop(_1; poll=_9) -> [return: bb15, unwind: bb9, drop: bb6]; ++ bb18: { ++ StorageDead(_9); ++ goto -> bb6; + } + -+ bb17: { ++ bb19 (cleanup): { ++ StorageDead(_9); ++ goto -> bb9; ++ } ++ ++ bb20: { ++ async drop(_1; poll=_9) -> [return: bb17, unwind: bb19, drop: bb18]; ++ } ++ ++ bb21: { + _12 = copy (_11.0: &mut {async fn body of simple()}); + StorageLive(_9); -+ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb16, unwind: bb9]; ++ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb20, unwind: bb19]; + } + -+ bb18: { ++ bb22: { + _10 = &mut _1; -+ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb17, unwind: bb9]; ++ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb21, unwind: bb9]; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff index e7d5e3e9ab3d4..3cd434b00c498 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff @@ -61,10 +61,10 @@ - StorageLive(_4); - _4 = AsyncInt(const 0_i32); - _0 = const (); -- goto -> bb13; +- goto -> bb15; + _24 = copy (_1.0: &mut {async fn body of simple()}); + _23 = discriminant((*_24)); -+ switchInt(move _23) -> [0: bb27, 1: bb26, 2: bb25, 3: bb23, 4: bb24, otherwise: bb17]; ++ switchInt(move _23) -> [0: bb29, 1: bb28, 2: bb27, 3: bb25, 4: bb26, otherwise: bb19]; } bb1: { @@ -76,9 +76,9 @@ bb2: { - StorageDead(_3); -- goto -> bb17; +- goto -> bb21; + nop; -+ goto -> bb14; ++ goto -> bb16; } bb3: { @@ -88,12 +88,10 @@ } - bb4: { -- StorageDead(_5); - StorageDead(_4); - goto -> bb5; + bb4 (cleanup): { + nop; -+ nop; + drop((((*_24) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; } @@ -105,14 +103,12 @@ } - bb6: { -+ bb6 (cleanup): { - StorageDead(_9); - coroutine_drop; -+ goto -> bb22; ++ bb6 (cleanup): { ++ goto -> bb24; } - bb7 (cleanup): { -- StorageDead(_5); - StorageDead(_4); - drop(_3) -> [return: bb8, unwind terminate(cleanup)]; + bb7: { @@ -120,128 +116,147 @@ + goto -> bb1; } -- bb8 (cleanup): { + bb8 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb9, unwind terminate(cleanup)]; -+ bb8: { -+ _14 = move _2; -+ goto -> bb16; ++ nop; ++ goto -> bb4; } - bb9 (cleanup): { -- StorageDead(_9); - resume; + bb9: { -+ _8 = copy (_7.0: &mut AsyncInt); -+ nop; -+ (((*_24) as variant#4).2: impl std::future::Future) = async_drop_in_place::(move _8) -> [return: bb8, unwind: bb4]; ++ _14 = move _2; ++ goto -> bb18; } bb10: { - StorageDead(_5); - goto -> bb1; -+ _6 = &mut (((*_24) as variant#4).1: AsyncInt); -+ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb4]; ++ _8 = copy (_7.0: &mut AsyncInt); ++ nop; ++ (((*_24) as variant#4).2: impl std::future::Future) = async_drop_in_place::(move _8) -> [return: bb9, unwind: bb8]; } bb11: { -- async drop(_4; poll=_5) -> [return: bb10, unwind: bb7, drop: bb4]; +- StorageDead(_5); +- goto -> bb4; ++ _6 = &mut (((*_24) as variant#4).1: AsyncInt); ++ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb10, unwind: bb4]; + } + +- bb12 (cleanup): { +- StorageDead(_5); +- goto -> bb7; ++ bb12: { + StorageDead(_9); + goto -> bb3; } - bb12: { +- bb13: { +- async drop(_4; poll=_5) -> [return: bb10, unwind: bb12, drop: bb11]; ++ bb13 (cleanup): { ++ StorageDead(_9); ++ goto -> bb6; + } + + bb14: { - _8 = copy (_7.0: &mut AsyncInt); - StorageLive(_5); -- _5 = async_drop_in_place::(move _8) -> [return: bb11, unwind: bb7]; -+ goto -> bb21; +- _5 = async_drop_in_place::(move _8) -> [return: bb13, unwind: bb12]; ++ goto -> bb23; } - bb13: { + bb15: { - _6 = &mut _4; -- _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb12, unwind: bb7]; +- _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb14, unwind: bb7]; + _12 = copy (_11.0: &mut {async fn body of simple()}); + StorageLive(_9); -+ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb12, unwind: bb6]; ++ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb14, unwind: bb13]; } - bb14: { + bb16: { - StorageDead(_9); - goto -> bb3; + _10 = &mut (*_24); -+ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb13, unwind: bb6]; ++ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb15, unwind: bb6]; } - bb15: { -- async drop(_1; poll=_9) -> [return: bb14, unwind: bb9, drop: bb6]; + bb17: { +- StorageDead(_9); +- goto -> bb6; + _0 = Poll::<()>::Pending; + discriminant((*_24)) = 3; + return; } - bb16: { -- _12 = copy (_11.0: &mut {async fn body of simple()}); -- StorageLive(_9); -- _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb15, unwind: bb9]; +- bb18 (cleanup): { +- StorageDead(_9); +- goto -> bb9; ++ bb18: { + StorageLive(_16); + _15 = &mut (((*_24) as variant#4).2: impl std::future::Future); -+ _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb19, unwind: bb22]; ++ _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb21, unwind: bb24]; } - bb17: { -- _10 = &mut _1; -- _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb16, unwind: bb9]; + bb19: { +- async drop(_1; poll=_9) -> [return: bb16, unwind: bb18, drop: bb17]; + unreachable; -+ } -+ -+ bb18: { + } + + bb20: { +- _12 = copy (_11.0: &mut {async fn body of simple()}); +- StorageLive(_9); +- _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb19, unwind: bb18]; + StorageDead(_16); + _17 = discriminant(_13); -+ switchInt(move _17) -> [0: bb7, 1: bb15, otherwise: bb17]; -+ } -+ -+ bb19: { -+ _13 = as Future>::poll(move _16, move _14) -> [return: bb18, unwind: bb4]; ++ switchInt(move _17) -> [0: bb7, 1: bb17, otherwise: bb19]; + } + + bb21: { +- _10 = &mut _1; +- _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb20, unwind: bb9]; ++ _13 = as Future>::poll(move _16, move _14) -> [return: bb20, unwind: bb8]; + } + -+ bb20: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb20, unwind: bb22]; ++ bb22: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb24]; + } + -+ bb21: { -+ goto -> bb11; ++ bb23: { ++ goto -> bb12; + } + -+ bb22 (cleanup): { ++ bb24 (cleanup): { + discriminant((*_24)) = 2; + resume; + } + -+ bb23: { ++ bb25: { + _14 = move _2; -+ goto -> bb16; ++ goto -> bb18; + } + -+ bb24: { ++ bb26: { + _18 = move _2; -+ goto -> bb20; ++ goto -> bb22; + } + -+ bb25: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb25, unwind continue]; ++ bb27: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb27, unwind continue]; + } + -+ bb26: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb26, unwind continue]; ++ bb28: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind continue]; + } + -+ bb27: { ++ bb29: { + nop; + (((*_24) as variant#4).0: SyncInt) = SyncInt(const 0_i32); + nop; + (((*_24) as variant#4).1: AsyncInt) = AsyncInt(const 0_i32); + (((*_24) as variant#3).0: ()) = const (); -+ goto -> bb10; ++ goto -> bb11; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir index 5c528fd0bbadb..1296b494542fb 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir @@ -37,7 +37,7 @@ yields () StorageLive(_4); _4 = AsyncInt(const 0_i32); _0 = const (); - goto -> bb13; + goto -> bb15; } bb1: { @@ -47,7 +47,7 @@ yields () bb2: { StorageDead(_3); - goto -> bb17; + goto -> bb21; } bb3: { @@ -55,7 +55,6 @@ yields () } bb4: { - StorageDead(_5); StorageDead(_4); goto -> bb5; } @@ -66,12 +65,10 @@ yields () } bb6: { - StorageDead(_9); coroutine_drop; } bb7 (cleanup): { - StorageDead(_5); StorageDead(_4); drop(_3) -> [return: bb8, unwind terminate(cleanup)]; } @@ -82,7 +79,6 @@ yields () } bb9 (cleanup): { - StorageDead(_9); resume; } @@ -92,90 +88,110 @@ yields () } bb11: { + StorageDead(_5); + goto -> bb4; + } + + bb12 (cleanup): { + StorageDead(_5); + goto -> bb7; + } + + bb13: { _14 = move _2; - goto -> bb19; + goto -> bb23; } - bb12: { + bb14: { _8 = copy (_7.0: &mut AsyncInt); StorageLive(_5); - _5 = async_drop_in_place::(move _8) -> [return: bb11, unwind: bb7]; + _5 = async_drop_in_place::(move _8) -> [return: bb13, unwind: bb12]; } - bb13: { + bb15: { _6 = &mut _4; - _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb12, unwind: bb7]; + _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb14, unwind: bb7]; } - bb14: { + bb16: { StorageDead(_9); goto -> bb3; } - bb15: { - drop(_1) -> [return: bb14, unwind: bb9]; + bb17: { + StorageDead(_9); + goto -> bb6; } - bb16: { + bb18 (cleanup): { + StorageDead(_9); + goto -> bb9; + } + + bb19: { + drop(_1) -> [return: bb16, unwind: bb18]; + } + + bb20: { _12 = copy (_11.0: &mut {async fn body of simple()}); StorageLive(_9); - _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb15, unwind: bb9]; + _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb19, unwind: bb18]; } - bb17: { + bb21: { _10 = &mut _1; - _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb16, unwind: bb9]; + _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb20, unwind: bb9]; } - bb18: { - _14 = yield(const false) -> [resume: bb19, drop: bb24]; + bb22: { + _14 = yield(const false) -> [resume: bb23, drop: bb28]; } - bb19: { + bb23: { StorageLive(_16); _15 = &mut _5; - _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb22, unwind continue]; + _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb26, unwind continue]; } - bb20: { + bb24: { unreachable; } - bb21: { + bb25: { StorageDead(_16); _17 = discriminant(_13); - switchInt(move _17) -> [0: bb10, 1: bb18, otherwise: bb20]; + switchInt(move _17) -> [0: bb10, 1: bb22, otherwise: bb24]; } - bb22: { - _13 = as Future>::poll(move _16, move _14) -> [return: bb21, unwind: bb7]; + bb26: { + _13 = as Future>::poll(move _16, move _14) -> [return: bb25, unwind: bb12]; } - bb23: { - _18 = yield(const false) -> [resume: bb28, drop: bb24]; + bb27: { + _18 = yield(const false) -> [resume: bb32, drop: bb28]; } - bb24: { + bb28: { StorageLive(_20); _19 = &mut _5; - _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb27, unwind continue]; + _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb31, unwind continue]; } - bb25: { + bb29: { unreachable; } - bb26: { + bb30: { StorageDead(_20); _21 = discriminant(_13); - switchInt(move _21) -> [0: bb4, 1: bb23, otherwise: bb25]; + switchInt(move _21) -> [0: bb11, 1: bb27, otherwise: bb29]; } - bb27: { - _13 = as Future>::poll(move _20, move _18) -> [return: bb26, unwind: bb7]; + bb31: { + _13 = as Future>::poll(move _20, move _18) -> [return: bb30, unwind: bb12]; } - bb28: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb28, unwind continue]; + bb32: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb32, unwind continue]; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir index 9b1c0a10a92fa..7bfe14da8f7fa 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir @@ -35,11 +35,10 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte bb0: { _24 = copy (_1.0: &mut {async fn body of simple()}); _23 = discriminant((*_24)); - switchInt(move _23) -> [0: bb13, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19]; + switchInt(move _23) -> [0: bb15, 2: bb20, 3: bb18, 4: bb19, otherwise: bb21]; } bb1: { - nop; nop; goto -> bb2; } @@ -50,13 +49,11 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte } bb3: { - StorageDead(_9); _0 = Poll::<()>::Ready(const ()); return; } bb4 (cleanup): { - nop; nop; drop((((*_24) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; } @@ -67,69 +64,78 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte } bb6 (cleanup): { - StorageDead(_9); - goto -> bb15; + goto -> bb17; } bb7: { + nop; + goto -> bb1; + } + + bb8 (cleanup): { + nop; + goto -> bb4; + } + + bb9: { _0 = Poll::<()>::Pending; discriminant((*_24)) = 4; return; } - bb8: { + bb10: { StorageLive(_20); _19 = &mut (((*_24) as variant#4).2: impl std::future::Future); - _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb11, unwind: bb15]; + _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb13, unwind: bb17]; } - bb9: { + bb11: { unreachable; } - bb10: { + bb12: { StorageDead(_20); _21 = discriminant(_13); - switchInt(move _21) -> [0: bb1, 1: bb7, otherwise: bb9]; + switchInt(move _21) -> [0: bb7, 1: bb9, otherwise: bb11]; } - bb11: { - _13 = as Future>::poll(move _20, move _18) -> [return: bb10, unwind: bb4]; + bb13: { + _13 = as Future>::poll(move _20, move _18) -> [return: bb12, unwind: bb8]; } - bb12: { + bb14: { _0 = Poll::<()>::Ready(const ()); return; } - bb13: { - goto -> bb14; + bb15: { + goto -> bb16; } - bb14: { - goto -> bb12; + bb16: { + goto -> bb14; } - bb15 (cleanup): { + bb17 (cleanup): { discriminant((*_24)) = 2; resume; } - bb16: { + bb18: { _14 = move _2; - goto -> bb8; + goto -> bb10; } - bb17: { + bb19: { _18 = move _2; - goto -> bb8; + goto -> bb10; } - bb18: { - assert(const false, "`async fn` resumed after panicking") -> [success: bb18, unwind continue]; + bb20: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb20, unwind continue]; } - bb19: { + bb21: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir index 2213160a748f4..0e41de3eace5f 100644 --- a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir +++ b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir @@ -28,11 +28,10 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) bb0: { _19 = copy (_1.0: &mut {async fn body of a()}); _18 = discriminant((*_19)); - switchInt(move _18) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14]; + switchInt(move _18) -> [0: bb10, 3: bb13, 4: bb14, otherwise: bb15]; } bb1: { - nop; nop; goto -> bb2; } @@ -43,59 +42,64 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb3: { + nop; + goto -> bb1; + } + + bb4: { _0 = Poll::<()>::Pending; discriminant((*_19)) = 4; return; } - bb4: { + bb5: { StorageLive(_15); _14 = &mut (((*_19) as variant#4).1: impl std::future::Future); - _15 = Pin::<&mut impl Future>::new_unchecked(move _14) -> [return: bb7, unwind unreachable]; + _15 = Pin::<&mut impl Future>::new_unchecked(move _14) -> [return: bb8, unwind unreachable]; } - bb5: { + bb6: { unreachable; } - bb6: { + bb7: { StorageDead(_15); _16 = discriminant(_8); - switchInt(move _16) -> [0: bb1, 1: bb3, otherwise: bb5]; - } - - bb7: { - _8 = as Future>::poll(move _15, move _13) -> [return: bb6, unwind unreachable]; + switchInt(move _16) -> [0: bb3, 1: bb4, otherwise: bb6]; } bb8: { - _0 = Poll::<()>::Ready(const ()); - return; + _8 = as Future>::poll(move _15, move _13) -> [return: bb7, unwind unreachable]; } bb9: { - goto -> bb11; + _0 = Poll::<()>::Ready(const ()); + return; } bb10: { - goto -> bb8; + goto -> bb12; } bb11: { - drop(((*_19).0: T)) -> [return: bb10, unwind unreachable]; + goto -> bb9; } bb12: { - _9 = move _2; - goto -> bb4; + drop(((*_19).0: T)) -> [return: bb11, unwind unreachable]; } bb13: { - _13 = move _2; - goto -> bb4; + _9 = move _2; + goto -> bb5; } bb14: { + _13 = move _2; + goto -> bb5; + } + + bb15: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir index ae97c257a0ddb..cda8147afb495 100644 --- a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir +++ b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir @@ -28,11 +28,10 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) bb0: { _19 = copy (_1.0: &mut {async fn body of a()}); _18 = discriminant((*_19)); - switchInt(move _18) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19]; + switchInt(move _18) -> [0: bb14, 2: bb20, 3: bb18, 4: bb19, otherwise: bb21]; } bb1: { - nop; nop; goto -> bb2; } @@ -44,81 +43,90 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) bb3 (cleanup): { nop; - nop; - goto -> bb5; + goto -> bb7; } bb4 (cleanup): { - goto -> bb15; + goto -> bb17; + } + + bb5: { + nop; + goto -> bb1; + } + + bb6 (cleanup): { + nop; + goto -> bb3; } - bb5 (cleanup): { + bb7 (cleanup): { goto -> bb4; } - bb6: { + bb8: { _0 = Poll::<()>::Pending; discriminant((*_19)) = 4; return; } - bb7: { + bb9: { StorageLive(_15); _14 = &mut (((*_19) as variant#4).1: impl std::future::Future); - _15 = Pin::<&mut impl Future>::new_unchecked(move _14) -> [return: bb10, unwind: bb15]; + _15 = Pin::<&mut impl Future>::new_unchecked(move _14) -> [return: bb12, unwind: bb17]; } - bb8: { + bb10: { unreachable; } - bb9: { + bb11: { StorageDead(_15); _16 = discriminant(_8); - switchInt(move _16) -> [0: bb1, 1: bb6, otherwise: bb8]; + switchInt(move _16) -> [0: bb5, 1: bb8, otherwise: bb10]; } - bb10: { - _8 = as Future>::poll(move _15, move _13) -> [return: bb9, unwind: bb3]; + bb12: { + _8 = as Future>::poll(move _15, move _13) -> [return: bb11, unwind: bb6]; } - bb11: { + bb13: { _0 = Poll::<()>::Ready(const ()); return; } - bb12: { - goto -> bb14; + bb14: { + goto -> bb16; } - bb13: { - goto -> bb11; + bb15: { + goto -> bb13; } - bb14: { - drop(((*_19).0: T)) -> [return: bb13, unwind: bb4]; + bb16: { + drop(((*_19).0: T)) -> [return: bb15, unwind: bb4]; } - bb15 (cleanup): { + bb17 (cleanup): { discriminant((*_19)) = 2; resume; } - bb16: { + bb18: { _9 = move _2; - goto -> bb7; + goto -> bb9; } - bb17: { + bb19: { _13 = move _2; - goto -> bb7; + goto -> bb9; } - bb18: { - assert(const false, "`async fn` resumed after panicking") -> [success: bb18, unwind continue]; + bb20: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb20, unwind continue]; } - bb19: { + bb21: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir index a70704181ee35..751721f7c4094 100644 --- a/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir @@ -26,7 +26,7 @@ yields () bb0: { _3 = move (_1.0: &mut [Foo; 1]); - goto -> bb19; + goto -> bb22; } bb1: { @@ -44,8 +44,6 @@ yields () } bb4 (cleanup): { - StorageDead(_12); - StorageDead(_18); _9 = Eq(copy _7, copy _6); switchInt(move _9) -> [0: bb3, otherwise: bb2]; } @@ -53,11 +51,10 @@ yields () bb5: { _10 = &raw mut (*_5)[_7]; _7 = Add(move _7, const 1_usize); - goto -> bb10; + goto -> bb11; } bb6: { - StorageDead(_18); _11 = Eq(copy _7, copy _6); switchInt(move _11) -> [0: bb5, otherwise: bb1]; } @@ -67,65 +64,80 @@ yields () goto -> bb6; } - bb8: { - async drop((*_10); poll=_12) -> [return: bb7, unwind: bb4]; + bb8 (cleanup): { + StorageDead(_12); + goto -> bb4; } bb9: { + async drop((*_10); poll=_12) -> [return: bb7, unwind: bb8]; + } + + bb10: { _15 = copy (_14.0: &mut Foo); StorageLive(_12); - _12 = async_drop_in_place::(move _15) -> [return: bb8, unwind: bb4]; + _12 = async_drop_in_place::(move _15) -> [return: bb9, unwind: bb8]; } - bb10: { + bb11: { _13 = &mut (*_10); - _14 = Pin::<&mut Foo>::new_unchecked(move _13) -> [return: bb9, unwind: bb4]; + _14 = Pin::<&mut Foo>::new_unchecked(move _13) -> [return: bb10, unwind: bb4]; } - bb11: { + bb12: { _16 = &raw mut (*_5)[_7]; _7 = Add(move _7, const 1_usize); - goto -> bb16; + goto -> bb19; } - bb12: { + bb13: { _17 = Eq(copy _7, copy _6); - switchInt(move _17) -> [0: bb11, otherwise: bb1]; + switchInt(move _17) -> [0: bb12, otherwise: bb1]; } - bb13: { + bb14: { StorageDead(_18); - goto -> bb12; + goto -> bb13; } - bb14: { - async drop((*_16); poll=_18) -> [return: bb13, unwind: bb4, drop: bb6]; + bb15: { + StorageDead(_18); + goto -> bb6; } - bb15: { + bb16 (cleanup): { + StorageDead(_18); + goto -> bb4; + } + + bb17: { + async drop((*_16); poll=_18) -> [return: bb14, unwind: bb16, drop: bb15]; + } + + bb18: { _21 = copy (_20.0: &mut Foo); StorageLive(_18); - _18 = async_drop_in_place::(move _21) -> [return: bb14, unwind: bb4]; + _18 = async_drop_in_place::(move _21) -> [return: bb17, unwind: bb16]; } - bb16: { + bb19: { _19 = &mut (*_16); - _20 = Pin::<&mut Foo>::new_unchecked(move _19) -> [return: bb15, unwind: bb4]; + _20 = Pin::<&mut Foo>::new_unchecked(move _19) -> [return: bb18, unwind: bb4]; } - bb17: { + bb20: { _6 = PtrMetadata(copy _5); _7 = const 0_usize; - goto -> bb12; + goto -> bb13; } - bb18: { - goto -> bb17; + bb21: { + goto -> bb20; } - bb19: { + bb22: { _4 = &raw mut (*_3); _5 = move _4 as *mut [Foo] (PointerCoercion(Unsize, Implicit)); - goto -> bb18; + goto -> bb21; } } From ed0471b5450056de93e336b44323ee4665426ff4 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Fri, 15 May 2026 13:17:52 +0000 Subject: [PATCH 08/12] Do not resove trait impl during elaboration. Drop elaboration runs early in the MIR pipeline. That pipeline is designed to work with unresolved function calls. Instance resolution during will call `codegen_select_candidate` when appropriate. --- .../rustc_mir_transform/src/elaborate_drop.rs | 68 +++---------------- 1 file changed, 11 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 2d9f91e843095..4db998255c654 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -1,14 +1,13 @@ use std::{fmt, iter, mem}; use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; -use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; use rustc_index::Idx; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt}; -use rustc_middle::{bug, span_bug, traits}; +use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Spanned, dummy_spanned}; use tracing::{debug, instrument}; @@ -218,65 +217,20 @@ where let tcx = self.tcx(); let span = self.source_info.span; - let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only { + let async_drop_fn_def_id = if call_destructor_only { // Resolving obj.() - let trait_ref = - ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::AsyncDrop, span), [drop_ty]); - let (drop_trait, trait_args) = match tcx.codegen_select_candidate( - ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref), - ) { - Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { - impl_def_id, - args, - .. - })) => (*impl_def_id, *args), - impl_source => { - span_bug!(span, "invalid `AsyncDrop` impl_source: {:?}", impl_source); - } - }; - // impl_item_refs may be empty if drop fn is not implemented in 'impl AsyncDrop for ...' - // (#140974). - // Such code will report error, so just generate sync drop here and return - let Some(drop_fn_def_id) = - tcx.associated_item_def_ids(drop_trait).first().and_then(|&def_id| { - if tcx.def_kind(def_id) == DefKind::AssocFn - && tcx.check_args_compatible(def_id, trait_args) - { - Some(def_id) - } else { - None - } - }) - else { - tcx.dcx().span_delayed_bug( - self.elaborator.body().span, - "AsyncDrop type without correct `async fn drop(...)`.", - ); - return self.new_block( - unwind, - TerminatorKind::Drop { - place, - target: succ, - unwind: unwind.into_action(), - replace: false, - drop: None, - async_fut: None, - }, - ); - }; - let drop_fn = Ty::new_fn_def(tcx, drop_fn_def_id, trait_args); - let sig = drop_fn.fn_sig(tcx); - let sig = tcx.instantiate_bound_regions_with_erased(sig); - (sig.output(), drop_fn_def_id, trait_args) + let async_drop_trait = tcx.require_lang_item(LangItem::AsyncDrop, span); + tcx.associated_item_def_ids(async_drop_trait)[0] } else { // Resolving async_drop_in_place function for drop_ty - let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, span); - let trait_args = tcx.mk_args(&[drop_ty.into()]); - let sig = tcx.fn_sig(drop_fn_def_id).instantiate(tcx, trait_args).skip_norm_wip(); - let sig = tcx.instantiate_bound_regions_with_erased(sig); - (sig.output(), drop_fn_def_id, trait_args) + tcx.require_lang_item(LangItem::AsyncDropInPlace, span) }; + let fut_ty = tcx + .instantiate_bound_regions_with_erased( + Ty::new_fn_def(tcx, async_drop_fn_def_id, [drop_ty]).fn_sig(tcx), + ) + .output(); let fut = self.new_temp(fut_ty); // #1:pin_obj_bb >>> obj_ref = &mut obj @@ -368,7 +322,7 @@ where unwind, call_statements, TerminatorKind::Call { - func: Operand::function_handle(tcx, drop_fn_def_id, trait_args, span), + func: Operand::function_handle(tcx, async_drop_fn_def_id, [drop_ty.into()], span), args: [Spanned { node: Operand::Move(drop_arg), span: DUMMY_SP }].into(), destination: fut.into(), target: Some(drop_term_bb), From 358881efbd555067cfbbfb5adf3a7883bd4896d5 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 08:57:39 +0000 Subject: [PATCH 09/12] Simplify type computation. And also reduce the amount of intermediary locals. This shifts code to be mostly in reverse execution order. --- .../rustc_mir_transform/src/elaborate_drop.rs | 86 +- ...sure#0}.AsyncEnum.MentionedItems.after.mir | 70 +- ...-{closure#0}.AsyncEnum.StateTransform.diff | 227 +++--- ...osure#0}.AsyncInt.MentionedItems.after.mir | 10 +- ...e-{closure#0}.AsyncInt.StateTransform.diff | 16 +- ...syncReference_'__.MentionedItems.after.mir | 10 +- ...#0}.AsyncReference_'__.StateTransform.diff | 16 +- ...re#0}.AsyncStruct.MentionedItems.after.mir | 94 +-- ...closure#0}.AsyncStruct.StateTransform.diff | 276 ++++--- ...#0}.SyncThenAsync.MentionedItems.after.mir | 82 +- ...osure#0}.SyncThenAsync.StateTransform.diff | 213 +++-- ...rop.double-{closure#0}.ElaborateDrops.diff | 56 +- ...rop.double-{closure#0}.StateTransform.diff | 201 +++-- ...osure#0}.coroutine_async_drop_expand.0.mir | 156 ++-- ...ble-{closure#0}.coroutine_drop_async.0.mir | 117 ++- ...rate_drops-{closure#0}.ElaborateDrops.diff | 220 +++--- ...rate_drops-{closure#0}.StateTransform.diff | 738 +++++++++--------- ...rop.simple-{closure#0}.ElaborateDrops.diff | 32 +- ...rop.simple-{closure#0}.StateTransform.diff | 124 ++- ...osure#0}.coroutine_async_drop_expand.0.mir | 82 +- ...ple-{closure#0}.coroutine_drop_async.0.mir | 68 +- ...#0}.coroutine_drop_async.0.panic-abort.mir | 61 +- ...0}.coroutine_drop_async.0.panic-unwind.mir | 63 +- ...losure#0}.[Foo;1].MentionedItems.after.mir | 44 +- 24 files changed, 1450 insertions(+), 1612 deletions(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 4db998255c654..df1ab00eacbfd 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -6,9 +6,9 @@ use rustc_index::Idx; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_span::{DUMMY_SP, Spanned, dummy_spanned}; +use rustc_span::{DUMMY_SP, dummy_spanned}; use tracing::{debug, instrument}; use crate::patch::MirPatch; @@ -216,6 +216,7 @@ where ) -> BasicBlock { let tcx = self.tcx(); let span = self.source_info.span; + let obj_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, drop_ty); let async_drop_fn_def_id = if call_destructor_only { // Resolving obj.() @@ -233,32 +234,6 @@ where .output(); let fut = self.new_temp(fut_ty); - // #1:pin_obj_bb >>> obj_ref = &mut obj - let obj_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, drop_ty); - let obj_ref_place = Place::from(self.new_temp(obj_ref_ty)); - let assign_obj_ref_place = self.assign( - obj_ref_place, - Rvalue::Ref( - tcx.lifetimes.re_erased, - BorrowKind::Mut { kind: MutBorrowKind::Default }, - place, - ), - ); - - // pin_obj_place preparation - let pin_obj_new_unchecked_fn = Ty::new_fn_def( - tcx, - tcx.require_lang_item(LangItem::PinNewUnchecked, span), - [GenericArg::from(obj_ref_ty)], - ); - let pin_obj_ty = pin_obj_new_unchecked_fn.fn_sig(tcx).output().no_bound_vars().unwrap(); - let pin_obj_place = Place::from(self.new_temp(pin_obj_ty)); - let pin_obj_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand { - span, - user_ty: None, - const_: Const::zero_sized(pin_obj_new_unchecked_fn), - })); - // Create an intermediate block that does StorageDead(fut) then jumps to succ. // This is necessary because we do not want to modify statements // in existing blocks, in case those are used somewhere else in MIR. @@ -295,35 +270,24 @@ where }, ); - // #2:call_drop_bb - let mut call_statements = Vec::new(); + // #2:call_drop_bb >>> call AsyncDrop::drop(pin_obj) OR call async_drop_in_place(pin_obj.pointer) + let pin_adt_def = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); + let pin_obj_ty = Ty::new_adt(tcx, pin_adt_def, tcx.mk_args(&[obj_ref_ty.into()])); + // Where we store the result of Pin<&drop_ty>::new_unchecked(&mut place). + let pin_obj_local = self.new_temp(pin_obj_ty); let drop_arg = if call_destructor_only { - pin_obj_place + // `AsyncDrop::drop` takes `self: Pin<&mut Self>`. + Operand::Move(pin_obj_local.into()) } else { - let ty::Adt(adt_def, adt_args) = pin_obj_ty.kind() else { - bug!(); - }; - let unwrap_ty = - adt_def.non_enum_variant().fields[FieldIdx::ZERO].ty(tcx, adt_args).skip_norm_wip(); - let obj_ref_place = Place::from(self.new_temp(unwrap_ty)); - call_statements.push(self.assign( - obj_ref_place, - Rvalue::Use( - Operand::Copy(tcx.mk_place_field(pin_obj_place, FieldIdx::ZERO, unwrap_ty)), - WithRetag::Yes, - ), - )); - - obj_ref_place + // `async_drop_in_place` takes `obj: &mut T`. + Operand::Copy(tcx.mk_place_field(pin_obj_local.into(), FieldIdx::ZERO, obj_ref_ty)) }; - call_statements.push(self.storage_live(fut)); - let call_drop_bb = self.new_block_with_statements( unwind, - call_statements, + vec![self.storage_live(fut)], TerminatorKind::Call { func: Operand::function_handle(tcx, async_drop_fn_def_id, [drop_ty.into()], span), - args: [Spanned { node: Operand::Move(drop_arg), span: DUMMY_SP }].into(), + args: [dummy_spanned(drop_arg)].into(), destination: fut.into(), target: Some(drop_term_bb), unwind: unwind_with_dead.into_action(), @@ -333,13 +297,28 @@ where ); // #1:pin_obj_bb >>> call Pin::new_unchecked(&mut obj) + let obj_ref_place = Place::from(self.new_temp(obj_ref_ty)); + let pin_obj_new_unchecked_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, span); + let assign_obj_ref_place = self.assign( + obj_ref_place, + Rvalue::Ref( + tcx.lifetimes.re_erased, + BorrowKind::Mut { kind: MutBorrowKind::Default }, + place, + ), + ); self.new_block_with_statements( unwind, vec![assign_obj_ref_place], TerminatorKind::Call { - func: pin_obj_new_unchecked_fn, + func: Operand::function_handle( + tcx, + pin_obj_new_unchecked_fn, + [obj_ref_ty.into()], + span, + ), args: [dummy_spanned(Operand::Move(obj_ref_place))].into(), - destination: pin_obj_place, + destination: pin_obj_local.into(), target: Some(call_drop_bb), unwind: unwind.into_action(), call_source: CallSource::Misc, @@ -933,8 +912,7 @@ where )], TerminatorKind::Call { func: Operand::function_handle(tcx, drop_fn, [ty.into()], self.source_info.span), - args: [Spanned { node: Operand::Move(Place::from(ref_place)), span: DUMMY_SP }] - .into(), + args: [dummy_spanned(Operand::Move(Place::from(ref_place)))].into(), destination: unit_temp, target: Some(succ), unwind: unwind.into_action(), diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir index 84cf65da840e4..4ed6ef4e10692 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir @@ -6,19 +6,17 @@ yields () let mut _0: (); let mut _3: &mut AsyncEnum; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncInt; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; + let mut _5: std::pin::Pin<&mut AsyncInt>; + let mut _6: &mut AsyncInt; + let mut _7: impl std::future::Future; + let mut _8: std::pin::Pin<&mut AsyncInt>; let mut _9: &mut AsyncInt; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; + let mut _10: isize; + let mut _11: isize; let mut _12: isize; - let mut _13: isize; - let mut _14: isize; - let mut _15: impl std::future::Future; - let mut _16: &mut AsyncEnum; - let mut _17: std::pin::Pin<&mut AsyncEnum>; + let mut _13: impl std::future::Future; + let mut _14: std::pin::Pin<&mut AsyncEnum>; + let mut _15: &mut AsyncEnum; bb0: { _3 = move (_1.0: &mut AsyncEnum); @@ -60,44 +58,42 @@ yields () } bb9: { - _7 = copy (_6.0: &mut AsyncInt); StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb7]; + _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7]; } bb10: { - _5 = &mut (((*_3) as A).0: AsyncInt); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; + _6 = &mut (((*_3) as A).0: AsyncInt); + _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb2]; } bb11: { - StorageDead(_8); + StorageDead(_7); goto -> bb3; } bb12: { - StorageDead(_8); + StorageDead(_7); goto -> bb1; } bb13 (cleanup): { - StorageDead(_8); + StorageDead(_7); goto -> bb2; } bb14: { - async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb11, unwind: bb13, drop: bb12]; + async drop((((*_3) as A).0: AsyncInt); poll=_7) -> [return: bb11, unwind: bb13, drop: bb12]; } bb15: { - _11 = copy (_10.0: &mut AsyncInt); - StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb14, unwind: bb13]; + StorageLive(_7); + _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb14, unwind: bb13]; } bb16: { _9 = &mut (((*_3) as A).0: AsyncInt); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb15, unwind: bb2]; + _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb15, unwind: bb2]; } bb17 (cleanup): { @@ -117,46 +113,46 @@ yields () } bb21: { - _12 = discriminant((*_3)); - switchInt(move _12) -> [0: bb16, otherwise: bb20]; + _10 = discriminant((*_3)); + switchInt(move _10) -> [0: bb16, otherwise: bb20]; } bb22 (cleanup): { - _13 = discriminant((*_3)); - switchInt(move _13) -> [0: bb4, otherwise: bb17]; + _11 = discriminant((*_3)); + switchInt(move _11) -> [0: bb4, otherwise: bb17]; } bb23: { - _14 = discriminant((*_3)); - switchInt(move _14) -> [0: bb10, otherwise: bb19]; + _12 = discriminant((*_3)); + switchInt(move _12) -> [0: bb10, otherwise: bb19]; } bb24: { - StorageDead(_15); + StorageDead(_13); goto -> bb21; } bb25: { - StorageDead(_15); + StorageDead(_13); goto -> bb23; } bb26 (cleanup): { - StorageDead(_15); + StorageDead(_13); goto -> bb22; } bb27: { - async drop((*_3); poll=_15) -> [return: bb24, unwind: bb26, drop: bb25]; + async drop((*_3); poll=_13) -> [return: bb24, unwind: bb26, drop: bb25]; } bb28: { - StorageLive(_15); - _15 = ::drop(move _17) -> [return: bb27, unwind: bb26]; + StorageLive(_13); + _13 = ::drop(move _14) -> [return: bb27, unwind: bb26]; } bb29: { - _16 = &mut (*_3); - _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb28, unwind: bb22]; + _15 = &mut (*_3); + _14 = Pin::<&mut AsyncEnum>::new_unchecked(move _15) -> [return: bb28, unwind: bb22]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff index 9ae4219b3357b..3d85395372b4d 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff @@ -26,65 +26,63 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut AsyncEnum; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncInt; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; + let mut _5: std::pin::Pin<&mut AsyncInt>; + let mut _6: &mut AsyncInt; + let mut _7: impl std::future::Future; + let mut _8: std::pin::Pin<&mut AsyncInt>; let mut _9: &mut AsyncInt; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; + let mut _10: isize; + let mut _11: isize; let mut _12: isize; - let mut _13: isize; - let mut _14: isize; - let mut _15: impl std::future::Future; - let mut _16: &mut AsyncEnum; - let mut _17: std::pin::Pin<&mut AsyncEnum>; -+ let mut _18: std::task::Poll<()>; -+ let mut _19: &mut std::task::Context<'_>; -+ let mut _20: &mut impl std::future::Future; -+ let mut _21: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _22: isize; -+ let mut _23: std::task::Poll<()>; -+ let mut _24: &mut std::task::Context<'_>; -+ let mut _25: &mut impl std::future::Future; -+ let mut _26: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _27: isize; -+ let mut _28: &mut std::task::Context<'_>; -+ let mut _29: &mut impl std::future::Future; -+ let mut _30: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _31: isize; -+ let mut _32: std::task::Poll<()>; -+ let mut _33: &mut std::task::Context<'_>; -+ let mut _34: &mut impl std::future::Future; -+ let mut _35: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _36: isize; -+ let mut _37: &mut std::task::Context<'_>; -+ let mut _38: &mut impl std::future::Future; -+ let mut _39: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _40: isize; -+ let mut _41: (); -+ let mut _42: u32; -+ let mut _43: &mut {async fn body of std::future::async_drop_in_place()}; + let mut _13: impl std::future::Future; + let mut _14: std::pin::Pin<&mut AsyncEnum>; + let mut _15: &mut AsyncEnum; ++ let mut _16: std::task::Poll<()>; ++ let mut _17: &mut std::task::Context<'_>; ++ let mut _18: &mut impl std::future::Future; ++ let mut _19: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _20: isize; ++ let mut _21: std::task::Poll<()>; ++ let mut _22: &mut std::task::Context<'_>; ++ let mut _23: &mut impl std::future::Future; ++ let mut _24: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _25: isize; ++ let mut _26: &mut std::task::Context<'_>; ++ let mut _27: &mut impl std::future::Future; ++ let mut _28: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _29: isize; ++ let mut _30: std::task::Poll<()>; ++ let mut _31: &mut std::task::Context<'_>; ++ let mut _32: &mut impl std::future::Future; ++ let mut _33: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _34: isize; ++ let mut _35: &mut std::task::Context<'_>; ++ let mut _36: &mut impl std::future::Future; ++ let mut _37: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _38: isize; ++ let mut _39: (); ++ let mut _40: u32; ++ let mut _41: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _42: &mut AsyncEnum; ++ let mut _43: &mut AsyncEnum; + let mut _44: &mut AsyncEnum; + let mut _45: &mut AsyncEnum; + let mut _46: &mut AsyncEnum; + let mut _47: &mut AsyncEnum; + let mut _48: &mut AsyncEnum; -+ let mut _49: &mut AsyncEnum; -+ let mut _50: &mut AsyncEnum; bb0: { - _3 = move (_1.0: &mut AsyncEnum); -- _16 = &mut (*_3); -- _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb23, unwind: bb18]; -+ _43 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); -+ _42 = discriminant((*_43)); -+ switchInt(move _42) -> [0: bb36, 1: bb35, 2: bb34, 3: bb29, 4: bb30, 5: bb31, 6: bb32, 7: bb33, otherwise: bb19]; +- _15 = &mut (*_3); +- _14 = Pin::<&mut AsyncEnum>::new_unchecked(move _15) -> [return: bb23, unwind: bb18]; ++ _41 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _40 = discriminant((*_41)); ++ switchInt(move _40) -> [0: bb36, 1: bb35, 2: bb34, 3: bb29, 4: bb30, 5: bb31, 6: bb32, 7: bb33, otherwise: bb19]; } bb1: { -+ _0 = Poll::<()>::Ready(move _41); -+ discriminant((*_43)) = 1; ++ _0 = Poll::<()>::Ready(move _39); ++ discriminant((*_41)) = 1; return; } @@ -95,8 +93,8 @@ bb3 (cleanup): { - drop((((*_3) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ _44 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); -+ drop((((*_44) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _42 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); ++ drop((((*_42) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb4: { @@ -113,62 +111,59 @@ bb6: { - async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb4, unwind: bb5]; -+ _24 = move _2; ++ _22 = move _2; + goto -> bb18; } bb7: { -- _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb6, unwind: bb5]; -+ _11 = copy (_10.0: &mut AsyncInt); +- _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb6, unwind: bb5]; + nop; -+ (((*_43) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _11) -> [return: bb6, unwind: bb5]; ++ (((*_41) as variant#5).0: impl std::future::Future) = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb6, unwind: bb5]; } bb8: { -- _5 = &mut (((*_3) as A).0: AsyncInt); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; -+ _45 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); -+ _9 = &mut (((*_45) as A).0: AsyncInt); -+ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb7, unwind: bb2]; +- _6 = &mut (((*_3) as A).0: AsyncInt); +- _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb7, unwind: bb2]; ++ _43 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); ++ _9 = &mut (((*_43) as A).0: AsyncInt); ++ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb7, unwind: bb2]; } - bb9: { -- StorageDead(_8); +- StorageDead(_7); - goto -> bb1; + bb9 (cleanup): { -+ _46 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); -+ drop((((*_46) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _44 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); ++ drop((((*_44) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb10: { -- StorageDead(_8); +- StorageDead(_7); - goto -> bb1; -+ _47 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); -+ drop((((*_47) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; ++ _45 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); ++ drop((((*_45) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; } bb11 (cleanup): { -- StorageDead(_8); +- StorageDead(_7); - goto -> bb2; -+ _48 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); -+ _13 = discriminant((*_48)); -+ switchInt(move _13) -> [0: bb3, otherwise: bb9]; ++ _46 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); ++ _11 = discriminant((*_46)); ++ switchInt(move _11) -> [0: bb3, otherwise: bb9]; } bb12: { -- async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb9, unwind: bb11, drop: bb10]; +- async drop((((*_3) as A).0: AsyncInt); poll=_7) -> [return: bb9, unwind: bb11, drop: bb10]; + nop; -+ _49 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); -+ _12 = discriminant((*_49)); -+ switchInt(move _12) -> [0: bb8, otherwise: bb10]; ++ _47 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); ++ _10 = discriminant((*_47)); ++ switchInt(move _10) -> [0: bb8, otherwise: bb10]; } - bb13: { -- _11 = copy (_10.0: &mut AsyncInt); -- StorageLive(_8); -- _8 = async_drop_in_place::(move _11) -> [return: bb12, unwind: bb11]; +- StorageLive(_7); +- _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb12, unwind: bb11]; + bb13 (cleanup): { + nop; + goto -> bb11; @@ -176,8 +171,8 @@ bb14: { - _9 = &mut (((*_3) as A).0: AsyncInt); -- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb2]; -+ _33 = move _2; +- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb2]; ++ _31 = move _2; + goto -> bb24; } @@ -185,7 +180,7 @@ - drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + bb15: { + nop; -+ (((*_43) as variant#7).1: impl std::future::Future) = ::drop(move _17) -> [return: bb14, unwind: bb13]; ++ (((*_41) as variant#7).1: impl std::future::Future) = ::drop(move _14) -> [return: bb14, unwind: bb13]; } bb16: { @@ -196,69 +191,69 @@ bb17: { - drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; + _0 = Poll::<()>::Pending; -+ discriminant((*_43)) = 4; ++ discriminant((*_41)) = 4; + return; } - bb18 (cleanup): { -- _13 = discriminant((*_3)); -- switchInt(move _13) -> [0: bb3, otherwise: bb15]; +- _11 = discriminant((*_3)); +- switchInt(move _11) -> [0: bb3, otherwise: bb15]; + bb18: { -+ StorageLive(_26); -+ _25 = &mut (((*_43) as variant#5).0: impl std::future::Future); -+ _26 = Pin::<&mut impl Future>::new_unchecked(move _25) -> [return: bb21, unwind: bb28]; ++ StorageLive(_24); ++ _23 = &mut (((*_41) as variant#5).0: impl std::future::Future); ++ _24 = Pin::<&mut impl Future>::new_unchecked(move _23) -> [return: bb21, unwind: bb28]; } bb19: { -- StorageDead(_15); -- _12 = discriminant((*_3)); -- switchInt(move _12) -> [0: bb14, otherwise: bb17]; +- StorageDead(_13); +- _10 = discriminant((*_3)); +- switchInt(move _10) -> [0: bb14, otherwise: bb17]; + unreachable; } bb20: { -- StorageDead(_15); -- _14 = discriminant((*_3)); -- switchInt(move _14) -> [0: bb8, otherwise: bb16]; -+ StorageDead(_26); -+ _27 = discriminant(_23); -+ switchInt(move _27) -> [0: bb4, 1: bb17, otherwise: bb19]; +- StorageDead(_13); +- _12 = discriminant((*_3)); +- switchInt(move _12) -> [0: bb8, otherwise: bb16]; ++ StorageDead(_24); ++ _25 = discriminant(_21); ++ switchInt(move _25) -> [0: bb4, 1: bb17, otherwise: bb19]; } - bb21 (cleanup): { -- StorageDead(_15); +- StorageDead(_13); - goto -> bb18; + bb21: { -+ _23 = as Future>::poll(move _26, move _24) -> [return: bb20, unwind: bb5]; ++ _21 = as Future>::poll(move _24, move _22) -> [return: bb20, unwind: bb5]; } bb22: { -- async drop((*_3); poll=_15) -> [return: bb19, unwind: bb21, drop: bb20]; +- async drop((*_3); poll=_13) -> [return: bb19, unwind: bb21, drop: bb20]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb28]; } bb23: { -- StorageLive(_15); -- _15 = ::drop(move _17) -> [return: bb22, unwind: bb21]; +- StorageLive(_13); +- _13 = ::drop(move _14) -> [return: bb22, unwind: bb21]; + _0 = Poll::<()>::Pending; -+ discriminant((*_43)) = 6; ++ discriminant((*_41)) = 6; + return; + } + + bb24: { -+ StorageLive(_35); -+ _34 = &mut (((*_43) as variant#7).1: impl std::future::Future); -+ _35 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb26, unwind: bb28]; ++ StorageLive(_33); ++ _32 = &mut (((*_41) as variant#7).1: impl std::future::Future); ++ _33 = Pin::<&mut impl Future>::new_unchecked(move _32) -> [return: bb26, unwind: bb28]; + } + + bb25: { -+ StorageDead(_35); -+ _36 = discriminant(_32); -+ switchInt(move _36) -> [0: bb12, 1: bb23, otherwise: bb19]; ++ StorageDead(_33); ++ _34 = discriminant(_30); ++ switchInt(move _34) -> [0: bb12, 1: bb23, otherwise: bb19]; + } + + bb26: { -+ _32 = as Future>::poll(move _35, move _33) -> [return: bb25, unwind: bb13]; ++ _30 = as Future>::poll(move _33, move _31) -> [return: bb25, unwind: bb13]; + } + + bb27: { @@ -266,32 +261,32 @@ + } + + bb28 (cleanup): { -+ discriminant((*_43)) = 2; ++ discriminant((*_41)) = 2; + resume; + } + + bb29: { -+ _19 = move _2; ++ _17 = move _2; + goto -> bb16; + } + + bb30: { -+ _24 = move _2; ++ _22 = move _2; + goto -> bb18; + } + + bb31: { -+ _28 = move _2; ++ _26 = move _2; + goto -> bb22; + } + + bb32: { -+ _33 = move _2; ++ _31 = move _2; + goto -> bb24; + } + + bb33: { -+ _37 = move _2; ++ _35 = move _2; + goto -> bb27; + } + @@ -305,10 +300,10 @@ + } + + bb36: { -+ (((*_43) as variant#7).0: &mut AsyncEnum) = move ((*_43).0: &mut AsyncEnum); -+ _50 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum); -+ _16 = &mut (*_50); -+ _17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb15, unwind: bb11]; ++ (((*_41) as variant#7).0: &mut AsyncEnum) = move ((*_41).0: &mut AsyncEnum); ++ _48 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); ++ _15 = &mut (*_48); ++ _14 = Pin::<&mut AsyncEnum>::new_unchecked(move _15) -> [return: bb15, unwind: bb11]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir index 96a9f2ca080d1..f426f51f303e5 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir @@ -6,8 +6,8 @@ yields () let mut _0: (); let mut _3: &mut AsyncInt; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncInt; - let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _5: std::pin::Pin<&mut AsyncInt>; + let mut _6: &mut AsyncInt; bb0: { _3 = move (_1.0: &mut AsyncInt); @@ -47,11 +47,11 @@ yields () bb8: { StorageLive(_4); - _4 = ::drop(move _6) -> [return: bb7, unwind: bb6]; + _4 = ::drop(move _5) -> [return: bb7, unwind: bb6]; } bb9: { - _5 = &mut (*_3); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; + _6 = &mut (*_3); + _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb8, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff index 9eb5aa10bc77c..80cd8db89efc1 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff @@ -20,8 +20,8 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut AsyncInt; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncInt; - let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _5: std::pin::Pin<&mut AsyncInt>; + let mut _6: &mut AsyncInt; + let mut _7: std::task::Poll<()>; + let mut _8: &mut std::task::Context<'_>; + let mut _9: &mut impl std::future::Future; @@ -37,8 +37,8 @@ bb0: { - _3 = move (_1.0: &mut AsyncInt); -- _5 = &mut (*_3); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; +- _6 = &mut (*_3); +- _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb7, unwind: bb2]; + _18 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); + _17 = discriminant((*_18)); + switchInt(move _17) -> [0: bb18, 1: bb17, 2: bb16, 3: bb14, 4: bb15, otherwise: bb9]; @@ -80,12 +80,12 @@ bb6: { - async drop((*_3); poll=_4) -> [return: bb3, unwind: bb5, drop: bb4]; + nop; -+ (((*_18) as variant#4).0: impl std::future::Future) = ::drop(move _6) -> [return: bb5, unwind: bb4]; ++ (((*_18) as variant#4).0: impl std::future::Future) = ::drop(move _5) -> [return: bb5, unwind: bb4]; } bb7: { - StorageLive(_4); -- _4 = ::drop(move _6) -> [return: bb6, unwind: bb5]; +- _4 = ::drop(move _5) -> [return: bb6, unwind: bb5]; + _0 = Poll::<()>::Pending; + discriminant((*_18)) = 3; + return; @@ -141,8 +141,8 @@ + + bb18: { + _3 = move ((*_18).0: &mut AsyncInt); -+ _5 = &mut (*_3); -+ _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; ++ _6 = &mut (*_3); ++ _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb6, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir index 2d1f4e53b0447..ccedee84d6fa5 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir @@ -6,8 +6,8 @@ yields () let mut _0: (); let mut _3: &mut AsyncReference<'_>; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncReference<'_>; - let mut _6: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _5: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _6: &mut AsyncReference<'_>; bb0: { _3 = move (_1.0: &mut AsyncReference<'_>); @@ -47,11 +47,11 @@ yields () bb8: { StorageLive(_4); - _4 = as AsyncDrop>::drop(move _6) -> [return: bb7, unwind: bb6]; + _4 = as AsyncDrop>::drop(move _5) -> [return: bb7, unwind: bb6]; } bb9: { - _5 = &mut (*_3); - _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; + _6 = &mut (*_3); + _5 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _6) -> [return: bb8, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff index e2caa694c3657..3f0291fe18c24 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff @@ -20,8 +20,8 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut AsyncReference<'_>; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncReference<'_>; - let mut _6: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _5: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _6: &mut AsyncReference<'_>; + let mut _7: std::task::Poll<()>; + let mut _8: &mut std::task::Context<'_>; + let mut _9: &mut impl std::future::Future; @@ -37,8 +37,8 @@ bb0: { - _3 = move (_1.0: &mut AsyncReference<'_>); -- _5 = &mut (*_3); -- _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb7, unwind: bb2]; +- _6 = &mut (*_3); +- _5 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _6) -> [return: bb7, unwind: bb2]; + _18 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place>()}); + _17 = discriminant((*_18)); + switchInt(move _17) -> [0: bb18, 1: bb17, 2: bb16, 3: bb14, 4: bb15, otherwise: bb9]; @@ -80,12 +80,12 @@ bb6: { - async drop((*_3); poll=_4) -> [return: bb3, unwind: bb5, drop: bb4]; + nop; -+ (((*_18) as variant#4).0: impl std::future::Future) = as AsyncDrop>::drop(move _6) -> [return: bb5, unwind: bb4]; ++ (((*_18) as variant#4).0: impl std::future::Future) = as AsyncDrop>::drop(move _5) -> [return: bb5, unwind: bb4]; } bb7: { - StorageLive(_4); -- _4 = as AsyncDrop>::drop(move _6) -> [return: bb6, unwind: bb5]; +- _4 = as AsyncDrop>::drop(move _5) -> [return: bb6, unwind: bb5]; + _0 = Poll::<()>::Pending; + discriminant((*_18)) = 3; + return; @@ -141,8 +141,8 @@ + + bb18: { + _3 = move ((*_18).0: &mut AsyncReference<'_>); -+ _5 = &mut (*_3); -+ _6 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _5) -> [return: bb6, unwind: bb2]; ++ _6 = &mut (*_3); ++ _5 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _6) -> [return: bb6, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir index 48b90196a89ac..817fb07fec5fd 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir @@ -6,24 +6,20 @@ yields () let mut _0: (); let mut _3: &mut AsyncStruct; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncInt; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; + let mut _5: std::pin::Pin<&mut AsyncInt>; + let mut _6: &mut AsyncInt; + let mut _7: impl std::future::Future; + let mut _8: std::pin::Pin<&mut AsyncInt>; let mut _9: &mut AsyncInt; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; - let mut _12: impl std::future::Future; - let mut _13: &mut AsyncInt; + let mut _10: impl std::future::Future; + let mut _11: std::pin::Pin<&mut AsyncInt>; + let mut _12: &mut AsyncInt; + let mut _13: impl std::future::Future; let mut _14: std::pin::Pin<&mut AsyncInt>; let mut _15: &mut AsyncInt; let mut _16: impl std::future::Future; - let mut _17: &mut AsyncInt; - let mut _18: std::pin::Pin<&mut AsyncInt>; - let mut _19: &mut AsyncInt; - let mut _20: impl std::future::Future; - let mut _21: &mut AsyncStruct; - let mut _22: std::pin::Pin<&mut AsyncStruct>; + let mut _17: std::pin::Pin<&mut AsyncStruct>; + let mut _18: &mut AsyncStruct; bb0: { _3 = move (_1.0: &mut AsyncStruct); @@ -65,127 +61,123 @@ yields () } bb9: { - _7 = copy (_6.0: &mut AsyncInt); StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb7]; + _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7]; } bb10: { - _5 = &mut ((*_3).2: AsyncInt); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; + _6 = &mut ((*_3).2: AsyncInt); + _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb2]; } bb11: { - StorageDead(_8); + StorageDead(_7); goto -> bb10; } bb12 (cleanup): { - StorageDead(_8); + StorageDead(_7); goto -> bb4; } bb13: { - async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb11, unwind: bb12]; + async drop(((*_3).1: AsyncInt); poll=_7) -> [return: bb11, unwind: bb12]; } bb14: { - _11 = copy (_10.0: &mut AsyncInt); - StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb13, unwind: bb12]; + StorageLive(_7); + _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb13, unwind: bb12]; } bb15: { _9 = &mut ((*_3).1: AsyncInt); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb14, unwind: bb4]; + _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb14, unwind: bb4]; } bb16: { - StorageDead(_12); + StorageDead(_10); goto -> bb3; } bb17: { - StorageDead(_12); + StorageDead(_10); goto -> bb1; } bb18 (cleanup): { - StorageDead(_12); + StorageDead(_10); goto -> bb2; } bb19: { - async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb16, unwind: bb18, drop: bb17]; + async drop(((*_3).2: AsyncInt); poll=_10) -> [return: bb16, unwind: bb18, drop: bb17]; } bb20: { - _15 = copy (_14.0: &mut AsyncInt); - StorageLive(_12); - _12 = async_drop_in_place::(move _15) -> [return: bb19, unwind: bb18]; + StorageLive(_10); + _10 = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb19, unwind: bb18]; } bb21: { - _13 = &mut ((*_3).2: AsyncInt); - _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb20, unwind: bb2]; + _12 = &mut ((*_3).2: AsyncInt); + _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb20, unwind: bb2]; } bb22: { - StorageDead(_16); + StorageDead(_13); goto -> bb21; } bb23: { - StorageDead(_16); + StorageDead(_13); goto -> bb10; } bb24 (cleanup): { - StorageDead(_16); + StorageDead(_13); goto -> bb4; } bb25: { - async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb22, unwind: bb24, drop: bb23]; + async drop(((*_3).1: AsyncInt); poll=_13) -> [return: bb22, unwind: bb24, drop: bb23]; } bb26: { - _19 = copy (_18.0: &mut AsyncInt); - StorageLive(_16); - _16 = async_drop_in_place::(move _19) -> [return: bb25, unwind: bb24]; + StorageLive(_13); + _13 = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb25, unwind: bb24]; } bb27: { - _17 = &mut ((*_3).1: AsyncInt); - _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb26, unwind: bb4]; + _15 = &mut ((*_3).1: AsyncInt); + _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb26, unwind: bb4]; } bb28: { - StorageDead(_20); + StorageDead(_16); goto -> bb27; } bb29: { - StorageDead(_20); + StorageDead(_16); goto -> bb15; } bb30 (cleanup): { - StorageDead(_20); + StorageDead(_16); goto -> bb5; } bb31: { - async drop((*_3); poll=_20) -> [return: bb28, unwind: bb30, drop: bb29]; + async drop((*_3); poll=_16) -> [return: bb28, unwind: bb30, drop: bb29]; } bb32: { - StorageLive(_20); - _20 = ::drop(move _22) -> [return: bb31, unwind: bb30]; + StorageLive(_16); + _16 = ::drop(move _17) -> [return: bb31, unwind: bb30]; } bb33: { - _21 = &mut (*_3); - _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb32, unwind: bb5]; + _18 = &mut (*_3); + _17 = Pin::<&mut AsyncStruct>::new_unchecked(move _18) -> [return: bb32, unwind: bb5]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff index 7a4181d058848..0e68c6c1eafa4 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff @@ -31,82 +31,78 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut AsyncStruct; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncInt; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; + let mut _5: std::pin::Pin<&mut AsyncInt>; + let mut _6: &mut AsyncInt; + let mut _7: impl std::future::Future; + let mut _8: std::pin::Pin<&mut AsyncInt>; let mut _9: &mut AsyncInt; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; - let mut _12: impl std::future::Future; - let mut _13: &mut AsyncInt; + let mut _10: impl std::future::Future; + let mut _11: std::pin::Pin<&mut AsyncInt>; + let mut _12: &mut AsyncInt; + let mut _13: impl std::future::Future; let mut _14: std::pin::Pin<&mut AsyncInt>; let mut _15: &mut AsyncInt; let mut _16: impl std::future::Future; - let mut _17: &mut AsyncInt; - let mut _18: std::pin::Pin<&mut AsyncInt>; - let mut _19: &mut AsyncInt; - let mut _20: impl std::future::Future; - let mut _21: &mut AsyncStruct; - let mut _22: std::pin::Pin<&mut AsyncStruct>; -+ let mut _23: std::task::Poll<()>; -+ let mut _24: &mut std::task::Context<'_>; -+ let mut _25: &mut impl std::future::Future; -+ let mut _26: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _27: isize; -+ let mut _28: std::task::Poll<()>; -+ let mut _29: &mut std::task::Context<'_>; -+ let mut _30: &mut impl std::future::Future; -+ let mut _31: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _32: isize; -+ let mut _33: std::task::Poll<()>; + let mut _17: std::pin::Pin<&mut AsyncStruct>; + let mut _18: &mut AsyncStruct; ++ let mut _19: std::task::Poll<()>; ++ let mut _20: &mut std::task::Context<'_>; ++ let mut _21: &mut impl std::future::Future; ++ let mut _22: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _23: isize; ++ let mut _24: std::task::Poll<()>; ++ let mut _25: &mut std::task::Context<'_>; ++ let mut _26: &mut impl std::future::Future; ++ let mut _27: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _28: isize; ++ let mut _29: std::task::Poll<()>; ++ let mut _30: &mut std::task::Context<'_>; ++ let mut _31: &mut impl std::future::Future; ++ let mut _32: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _33: isize; + let mut _34: &mut std::task::Context<'_>; + let mut _35: &mut impl std::future::Future; + let mut _36: std::pin::Pin<&mut impl std::future::Future>; + let mut _37: isize; -+ let mut _38: &mut std::task::Context<'_>; -+ let mut _39: &mut impl std::future::Future; -+ let mut _40: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _41: isize; -+ let mut _42: std::task::Poll<()>; ++ let mut _38: std::task::Poll<()>; ++ let mut _39: &mut std::task::Context<'_>; ++ let mut _40: &mut impl std::future::Future; ++ let mut _41: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _42: isize; + let mut _43: &mut std::task::Context<'_>; + let mut _44: &mut impl std::future::Future; + let mut _45: std::pin::Pin<&mut impl std::future::Future>; + let mut _46: isize; -+ let mut _47: &mut std::task::Context<'_>; -+ let mut _48: &mut impl std::future::Future; -+ let mut _49: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _50: isize; -+ let mut _51: std::task::Poll<()>; ++ let mut _47: std::task::Poll<()>; ++ let mut _48: &mut std::task::Context<'_>; ++ let mut _49: &mut impl std::future::Future; ++ let mut _50: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _51: isize; + let mut _52: &mut std::task::Context<'_>; + let mut _53: &mut impl std::future::Future; + let mut _54: std::pin::Pin<&mut impl std::future::Future>; + let mut _55: isize; -+ let mut _56: &mut std::task::Context<'_>; -+ let mut _57: &mut impl std::future::Future; -+ let mut _58: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _59: isize; -+ let mut _60: (); -+ let mut _61: u32; -+ let mut _62: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _56: (); ++ let mut _57: u32; ++ let mut _58: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _59: &mut AsyncStruct; ++ let mut _60: &mut AsyncStruct; ++ let mut _61: &mut AsyncStruct; ++ let mut _62: &mut AsyncStruct; + let mut _63: &mut AsyncStruct; -+ let mut _64: &mut AsyncStruct; -+ let mut _65: &mut AsyncStruct; -+ let mut _66: &mut AsyncStruct; -+ let mut _67: &mut AsyncStruct; bb0: { - _3 = move (_1.0: &mut AsyncStruct); -- _21 = &mut (*_3); -- _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb28, unwind: bb4]; -+ _62 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); -+ _61 = discriminant((*_62)); -+ switchInt(move _61) -> [0: bb46, 1: bb45, 2: bb44, 3: bb36, 4: bb37, 5: bb38, 6: bb39, 7: bb40, 8: bb41, 9: bb42, 10: bb43, otherwise: bb21]; +- _18 = &mut (*_3); +- _17 = Pin::<&mut AsyncStruct>::new_unchecked(move _18) -> [return: bb28, unwind: bb4]; ++ _58 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _57 = discriminant((*_58)); ++ switchInt(move _57) -> [0: bb46, 1: bb45, 2: bb44, 3: bb36, 4: bb37, 5: bb38, 6: bb39, 7: bb40, 8: bb41, 9: bb42, 10: bb43, otherwise: bb21]; } bb1: { -+ _0 = Poll::<()>::Ready(move _60); -+ discriminant((*_62)) = 1; ++ _0 = Poll::<()>::Ready(move _56); ++ discriminant((*_58)) = 1; return; } @@ -117,14 +113,14 @@ bb3 (cleanup): { - drop(((*_3).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ _63 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); -+ drop(((*_63).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _59 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); ++ drop(((*_59).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb4 (cleanup): { - drop(((*_3).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; -+ _64 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); -+ drop(((*_64).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; ++ _60 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); ++ drop(((*_60).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; } bb5: { @@ -141,30 +137,28 @@ bb7: { - async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb5, unwind: bb6]; -+ _34 = move _2; ++ _30 = move _2; + goto -> bb20; } bb8: { -- _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb7, unwind: bb6]; -+ _15 = copy (_14.0: &mut AsyncInt); +- _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb7, unwind: bb6]; + nop; -+ (((*_62) as variant#6).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb7, unwind: bb6]; ++ (((*_58) as variant#6).0: impl std::future::Future) = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb7, unwind: bb6]; } bb9: { -- _5 = &mut ((*_3).2: AsyncInt); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2]; +- _6 = &mut ((*_3).2: AsyncInt); +- _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb8, unwind: bb2]; + nop; -+ _65 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); -+ _13 = &mut ((*_65).2: AsyncInt); -+ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb8, unwind: bb2]; ++ _61 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); ++ _12 = &mut ((*_61).2: AsyncInt); ++ _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb8, unwind: bb2]; } - bb10: { -- StorageDead(_8); +- StorageDead(_7); - goto -> bb9; + bb10 (cleanup): { + nop; @@ -172,32 +166,30 @@ } - bb11 (cleanup): { -- StorageDead(_8); +- StorageDead(_7); - goto -> bb3; + bb11: { -+ _43 = move _2; ++ _39 = move _2; + goto -> bb26; } bb12: { -- async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb10, unwind: bb11]; -+ _19 = copy (_18.0: &mut AsyncInt); +- async drop(((*_3).1: AsyncInt); poll=_7) -> [return: bb10, unwind: bb11]; + nop; -+ (((*_62) as variant#8).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb11, unwind: bb10]; ++ (((*_58) as variant#8).1: impl std::future::Future) = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb11, unwind: bb10]; } bb13: { -- _11 = copy (_10.0: &mut AsyncInt); -- StorageLive(_8); -- _8 = async_drop_in_place::(move _11) -> [return: bb12, unwind: bb11]; +- StorageLive(_7); +- _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb12, unwind: bb11]; + nop; -+ _66 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); -+ _17 = &mut ((*_66).1: AsyncInt); -+ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb12, unwind: bb3]; ++ _62 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); ++ _15 = &mut ((*_62).1: AsyncInt); ++ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb12, unwind: bb3]; } - bb14: { -- StorageDead(_12); +- StorageDead(_10); - goto -> bb1; + bb14 (cleanup): { + nop; @@ -205,106 +197,104 @@ } bb15: { -- StorageDead(_12); +- StorageDead(_10); - goto -> bb1; -+ _52 = move _2; ++ _48 = move _2; + goto -> bb31; } - bb16 (cleanup): { -- StorageDead(_12); +- StorageDead(_10); - goto -> bb2; + bb16: { + nop; -+ (((*_62) as variant#10).1: impl std::future::Future) = ::drop(move _22) -> [return: bb15, unwind: bb14]; ++ (((*_58) as variant#10).1: impl std::future::Future) = ::drop(move _17) -> [return: bb15, unwind: bb14]; } bb17: { -- async drop(((*_3).2: AsyncInt); poll=_12) -> [return: bb14, unwind: bb16, drop: bb15]; +- async drop(((*_3).2: AsyncInt); poll=_10) -> [return: bb14, unwind: bb16, drop: bb15]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb17, unwind: bb35]; } bb18: { -- _15 = copy (_14.0: &mut AsyncInt); -- StorageLive(_12); -- _12 = async_drop_in_place::(move _15) -> [return: bb17, unwind: bb16]; +- StorageLive(_10); +- _10 = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb17, unwind: bb16]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb18, unwind: bb35]; } bb19: { -- StorageDead(_16); -- _13 = &mut ((*_3).2: AsyncInt); -- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb18, unwind: bb2]; +- StorageDead(_13); +- _12 = &mut ((*_3).2: AsyncInt); +- _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb18, unwind: bb2]; + _0 = Poll::<()>::Pending; -+ discriminant((*_62)) = 5; ++ discriminant((*_58)) = 5; + return; } bb20: { -- StorageDead(_16); +- StorageDead(_13); - goto -> bb9; -+ StorageLive(_36); -+ _35 = &mut (((*_62) as variant#6).0: impl std::future::Future); -+ _36 = Pin::<&mut impl Future>::new_unchecked(move _35) -> [return: bb23, unwind: bb35]; ++ StorageLive(_32); ++ _31 = &mut (((*_58) as variant#6).0: impl std::future::Future); ++ _32 = Pin::<&mut impl Future>::new_unchecked(move _31) -> [return: bb23, unwind: bb35]; } - bb21 (cleanup): { -- StorageDead(_16); +- StorageDead(_13); - goto -> bb3; + bb21: { + unreachable; } bb22: { -- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb19, unwind: bb21, drop: bb20]; -+ StorageDead(_36); -+ _37 = discriminant(_33); -+ switchInt(move _37) -> [0: bb5, 1: bb19, otherwise: bb21]; +- async drop(((*_3).1: AsyncInt); poll=_13) -> [return: bb19, unwind: bb21, drop: bb20]; ++ StorageDead(_32); ++ _33 = discriminant(_29); ++ switchInt(move _33) -> [0: bb5, 1: bb19, otherwise: bb21]; } bb23: { -- _19 = copy (_18.0: &mut AsyncInt); -- StorageLive(_16); -- _16 = async_drop_in_place::(move _19) -> [return: bb22, unwind: bb21]; -+ _33 = as Future>::poll(move _36, move _34) -> [return: bb22, unwind: bb6]; +- StorageLive(_13); +- _13 = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb22, unwind: bb21]; ++ _29 = as Future>::poll(move _32, move _30) -> [return: bb22, unwind: bb6]; } bb24: { -- StorageDead(_20); -- _17 = &mut ((*_3).1: AsyncInt); -- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb23, unwind: bb3]; +- StorageDead(_16); +- _15 = &mut ((*_3).1: AsyncInt); +- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb23, unwind: bb3]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb24, unwind: bb35]; } bb25: { -- StorageDead(_20); +- StorageDead(_16); - _9 = &mut ((*_3).1: AsyncInt); -- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb3]; +- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb3]; + _0 = Poll::<()>::Pending; -+ discriminant((*_62)) = 7; ++ discriminant((*_58)) = 7; + return; } - bb26 (cleanup): { -- StorageDead(_20); +- StorageDead(_16); - goto -> bb4; + bb26: { -+ StorageLive(_45); -+ _44 = &mut (((*_62) as variant#8).1: impl std::future::Future); -+ _45 = Pin::<&mut impl Future>::new_unchecked(move _44) -> [return: bb28, unwind: bb35]; ++ StorageLive(_41); ++ _40 = &mut (((*_58) as variant#8).1: impl std::future::Future); ++ _41 = Pin::<&mut impl Future>::new_unchecked(move _40) -> [return: bb28, unwind: bb35]; } bb27: { -- async drop((*_3); poll=_20) -> [return: bb24, unwind: bb26, drop: bb25]; -+ StorageDead(_45); -+ _46 = discriminant(_42); -+ switchInt(move _46) -> [0: bb9, 1: bb25, otherwise: bb21]; +- async drop((*_3); poll=_16) -> [return: bb24, unwind: bb26, drop: bb25]; ++ StorageDead(_41); ++ _42 = discriminant(_38); ++ switchInt(move _42) -> [0: bb9, 1: bb25, otherwise: bb21]; } bb28: { -- StorageLive(_20); -- _20 = ::drop(move _22) -> [return: bb27, unwind: bb26]; -+ _42 = as Future>::poll(move _45, move _43) -> [return: bb27, unwind: bb10]; +- StorageLive(_16); +- _16 = ::drop(move _17) -> [return: bb27, unwind: bb26]; ++ _38 = as Future>::poll(move _41, move _39) -> [return: bb27, unwind: bb10]; + } + + bb29: { @@ -313,24 +303,24 @@ + + bb30: { + _0 = Poll::<()>::Pending; -+ discriminant((*_62)) = 9; ++ discriminant((*_58)) = 9; + return; + } + + bb31: { -+ StorageLive(_54); -+ _53 = &mut (((*_62) as variant#10).1: impl std::future::Future); -+ _54 = Pin::<&mut impl Future>::new_unchecked(move _53) -> [return: bb33, unwind: bb35]; ++ StorageLive(_50); ++ _49 = &mut (((*_58) as variant#10).1: impl std::future::Future); ++ _50 = Pin::<&mut impl Future>::new_unchecked(move _49) -> [return: bb33, unwind: bb35]; + } + + bb32: { -+ StorageDead(_54); -+ _55 = discriminant(_51); -+ switchInt(move _55) -> [0: bb13, 1: bb30, otherwise: bb21]; ++ StorageDead(_50); ++ _51 = discriminant(_47); ++ switchInt(move _51) -> [0: bb13, 1: bb30, otherwise: bb21]; + } + + bb33: { -+ _51 = as Future>::poll(move _54, move _52) -> [return: bb32, unwind: bb14]; ++ _47 = as Future>::poll(move _50, move _48) -> [return: bb32, unwind: bb14]; + } + + bb34: { @@ -338,47 +328,47 @@ + } + + bb35 (cleanup): { -+ discriminant((*_62)) = 2; ++ discriminant((*_58)) = 2; + resume; + } + + bb36: { -+ _24 = move _2; ++ _20 = move _2; + goto -> bb17; + } + + bb37: { -+ _29 = move _2; ++ _25 = move _2; + goto -> bb18; + } + + bb38: { -+ _34 = move _2; ++ _30 = move _2; + goto -> bb20; + } + + bb39: { -+ _38 = move _2; ++ _34 = move _2; + goto -> bb24; + } + + bb40: { -+ _43 = move _2; ++ _39 = move _2; + goto -> bb26; + } + + bb41: { -+ _47 = move _2; ++ _43 = move _2; + goto -> bb29; + } + + bb42: { -+ _52 = move _2; ++ _48 = move _2; + goto -> bb31; + } + + bb43: { -+ _56 = move _2; ++ _52 = move _2; + goto -> bb34; + } + @@ -392,10 +382,10 @@ + } + + bb46: { -+ (((*_62) as variant#10).0: &mut AsyncStruct) = move ((*_62).0: &mut AsyncStruct); -+ _67 = no_retag copy (((*_62) as variant#10).0: &mut AsyncStruct); -+ _21 = &mut (*_67); -+ _22 = Pin::<&mut AsyncStruct>::new_unchecked(move _21) -> [return: bb16, unwind: bb4]; ++ (((*_58) as variant#10).0: &mut AsyncStruct) = move ((*_58).0: &mut AsyncStruct); ++ _63 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); ++ _18 = &mut (*_63); ++ _17 = Pin::<&mut AsyncStruct>::new_unchecked(move _18) -> [return: bb16, unwind: bb4]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir index e2ad09cb99404..d4173722e4313 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir @@ -6,23 +6,19 @@ yields () let mut _0: (); let mut _3: &mut SyncThenAsync; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncInt; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; + let mut _5: std::pin::Pin<&mut AsyncInt>; + let mut _6: &mut AsyncInt; + let mut _7: impl std::future::Future; + let mut _8: std::pin::Pin<&mut AsyncInt>; let mut _9: &mut AsyncInt; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; - let mut _12: impl std::future::Future; - let mut _13: &mut AsyncInt; + let mut _10: impl std::future::Future; + let mut _11: std::pin::Pin<&mut AsyncInt>; + let mut _12: &mut AsyncInt; + let mut _13: impl std::future::Future; let mut _14: std::pin::Pin<&mut AsyncInt>; let mut _15: &mut AsyncInt; - let mut _16: impl std::future::Future; - let mut _17: &mut AsyncInt; - let mut _18: std::pin::Pin<&mut AsyncInt>; - let mut _19: &mut AsyncInt; - let mut _20: &mut SyncThenAsync; - let mut _21: (); + let mut _16: &mut SyncThenAsync; + let mut _17: (); bb0: { _3 = move (_1.0: &mut SyncThenAsync); @@ -68,14 +64,13 @@ yields () } bb10: { - _7 = copy (_6.0: &mut AsyncInt); StorageLive(_4); - _4 = async_drop_in_place::(move _7) -> [return: bb9, unwind: bb8]; + _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb9, unwind: bb8]; } bb11: { - _5 = &mut ((*_3).3: AsyncInt); - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb10, unwind: bb2]; + _6 = &mut ((*_3).3: AsyncInt); + _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb10, unwind: bb2]; } bb12: { @@ -83,58 +78,56 @@ yields () } bb13: { - StorageDead(_8); + StorageDead(_7); goto -> bb12; } bb14 (cleanup): { - StorageDead(_8); + StorageDead(_7); goto -> bb5; } bb15: { - async drop(((*_3).1: AsyncInt); poll=_8) -> [return: bb13, unwind: bb14]; + async drop(((*_3).1: AsyncInt); poll=_7) -> [return: bb13, unwind: bb14]; } bb16: { - _11 = copy (_10.0: &mut AsyncInt); - StorageLive(_8); - _8 = async_drop_in_place::(move _11) -> [return: bb15, unwind: bb14]; + StorageLive(_7); + _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb15, unwind: bb14]; } bb17: { _9 = &mut ((*_3).1: AsyncInt); - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb16, unwind: bb5]; + _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb16, unwind: bb5]; } bb18: { - StorageDead(_12); + StorageDead(_10); goto -> bb3; } bb19: { - StorageDead(_12); + StorageDead(_10); goto -> bb1; } bb20 (cleanup): { - StorageDead(_12); + StorageDead(_10); goto -> bb2; } bb21: { - async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb18, unwind: bb20, drop: bb19]; + async drop(((*_3).3: AsyncInt); poll=_10) -> [return: bb18, unwind: bb20, drop: bb19]; } bb22: { - _15 = copy (_14.0: &mut AsyncInt); - StorageLive(_12); - _12 = async_drop_in_place::(move _15) -> [return: bb21, unwind: bb20]; + StorageLive(_10); + _10 = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb21, unwind: bb20]; } bb23: { - _13 = &mut ((*_3).3: AsyncInt); - _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb22, unwind: bb2]; + _12 = &mut ((*_3).3: AsyncInt); + _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb22, unwind: bb2]; } bb24: { @@ -142,37 +135,36 @@ yields () } bb25: { - StorageDead(_16); + StorageDead(_13); goto -> bb24; } bb26: { - StorageDead(_16); + StorageDead(_13); goto -> bb12; } bb27 (cleanup): { - StorageDead(_16); + StorageDead(_13); goto -> bb5; } bb28: { - async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb25, unwind: bb27, drop: bb26]; + async drop(((*_3).1: AsyncInt); poll=_13) -> [return: bb25, unwind: bb27, drop: bb26]; } bb29: { - _19 = copy (_18.0: &mut AsyncInt); - StorageLive(_16); - _16 = async_drop_in_place::(move _19) -> [return: bb28, unwind: bb27]; + StorageLive(_13); + _13 = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb28, unwind: bb27]; } bb30: { - _17 = &mut ((*_3).1: AsyncInt); - _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb29, unwind: bb5]; + _15 = &mut ((*_3).1: AsyncInt); + _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb29, unwind: bb5]; } bb31: { - _20 = &mut (*_3); - _21 = ::drop(move _20) -> [return: bb30, unwind: bb6]; + _16 = &mut (*_3); + _17 = ::drop(move _16) -> [return: bb30, unwind: bb6]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff index eaf4fcd886013..d706d27e83238 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff @@ -26,69 +26,65 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut SyncThenAsync; let mut _4: impl std::future::Future; - let mut _5: &mut AsyncInt; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; + let mut _5: std::pin::Pin<&mut AsyncInt>; + let mut _6: &mut AsyncInt; + let mut _7: impl std::future::Future; + let mut _8: std::pin::Pin<&mut AsyncInt>; let mut _9: &mut AsyncInt; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; - let mut _12: impl std::future::Future; - let mut _13: &mut AsyncInt; + let mut _10: impl std::future::Future; + let mut _11: std::pin::Pin<&mut AsyncInt>; + let mut _12: &mut AsyncInt; + let mut _13: impl std::future::Future; let mut _14: std::pin::Pin<&mut AsyncInt>; let mut _15: &mut AsyncInt; - let mut _16: impl std::future::Future; - let mut _17: &mut AsyncInt; - let mut _18: std::pin::Pin<&mut AsyncInt>; - let mut _19: &mut AsyncInt; - let mut _20: &mut SyncThenAsync; - let mut _21: (); -+ let mut _22: std::task::Poll<()>; -+ let mut _23: &mut std::task::Context<'_>; -+ let mut _24: &mut impl std::future::Future; -+ let mut _25: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _26: isize; -+ let mut _27: std::task::Poll<()>; + let mut _16: &mut SyncThenAsync; + let mut _17: (); ++ let mut _18: std::task::Poll<()>; ++ let mut _19: &mut std::task::Context<'_>; ++ let mut _20: &mut impl std::future::Future; ++ let mut _21: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _22: isize; ++ let mut _23: std::task::Poll<()>; ++ let mut _24: &mut std::task::Context<'_>; ++ let mut _25: &mut impl std::future::Future; ++ let mut _26: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _27: isize; + let mut _28: &mut std::task::Context<'_>; + let mut _29: &mut impl std::future::Future; + let mut _30: std::pin::Pin<&mut impl std::future::Future>; + let mut _31: isize; -+ let mut _32: &mut std::task::Context<'_>; -+ let mut _33: &mut impl std::future::Future; -+ let mut _34: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _35: isize; -+ let mut _36: std::task::Poll<()>; ++ let mut _32: std::task::Poll<()>; ++ let mut _33: &mut std::task::Context<'_>; ++ let mut _34: &mut impl std::future::Future; ++ let mut _35: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _36: isize; + let mut _37: &mut std::task::Context<'_>; + let mut _38: &mut impl std::future::Future; + let mut _39: std::pin::Pin<&mut impl std::future::Future>; + let mut _40: isize; -+ let mut _41: &mut std::task::Context<'_>; -+ let mut _42: &mut impl std::future::Future; -+ let mut _43: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _44: isize; -+ let mut _45: (); -+ let mut _46: u32; -+ let mut _47: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _41: (); ++ let mut _42: u32; ++ let mut _43: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _44: &mut SyncThenAsync; ++ let mut _45: &mut SyncThenAsync; ++ let mut _46: &mut SyncThenAsync; ++ let mut _47: &mut SyncThenAsync; + let mut _48: &mut SyncThenAsync; + let mut _49: &mut SyncThenAsync; + let mut _50: &mut SyncThenAsync; -+ let mut _51: &mut SyncThenAsync; -+ let mut _52: &mut SyncThenAsync; -+ let mut _53: &mut SyncThenAsync; -+ let mut _54: &mut SyncThenAsync; bb0: { - _3 = move (_1.0: &mut SyncThenAsync); -- _20 = &mut (*_3); -- _21 = ::drop(move _20) -> [return: bb22, unwind: bb5]; -+ _47 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); -+ _46 = discriminant((*_47)); -+ switchInt(move _46) -> [0: bb36, 1: bb35, 2: bb34, 3: bb29, 4: bb30, 5: bb31, 6: bb32, 7: bb33, otherwise: bb19]; +- _16 = &mut (*_3); +- _17 = ::drop(move _16) -> [return: bb22, unwind: bb5]; ++ _43 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _42 = discriminant((*_43)); ++ switchInt(move _42) -> [0: bb36, 1: bb35, 2: bb34, 3: bb29, 4: bb30, 5: bb31, 6: bb32, 7: bb33, otherwise: bb19]; } bb1: { -+ _0 = Poll::<()>::Ready(move _45); -+ discriminant((*_47)) = 1; ++ _0 = Poll::<()>::Ready(move _41); ++ discriminant((*_43)) = 1; return; } @@ -99,20 +95,20 @@ bb3 (cleanup): { - drop(((*_3).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ _48 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_48).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _44 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_44).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb4 (cleanup): { - drop(((*_3).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; -+ _49 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_49).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; ++ _45 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_45).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; } bb5 (cleanup): { - drop(((*_3).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; -+ _50 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_50).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; ++ _46 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_46).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; } bb6: { @@ -129,37 +125,35 @@ bb8: { - async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb6, unwind: bb7]; -+ _28 = move _2; ++ _24 = move _2; + goto -> bb18; } bb9: { -- _7 = copy (_6.0: &mut AsyncInt); - StorageLive(_4); -- _4 = async_drop_in_place::(move _7) -> [return: bb8, unwind: bb7]; -+ _15 = copy (_14.0: &mut AsyncInt); +- _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7]; + nop; -+ (((*_47) as variant#5).0: impl std::future::Future) = async_drop_in_place::(move _15) -> [return: bb8, unwind: bb7]; ++ (((*_43) as variant#5).0: impl std::future::Future) = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7]; } bb10: { -- _5 = &mut ((*_3).3: AsyncInt); -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2]; -+ _51 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ _13 = &mut ((*_51).3: AsyncInt); -+ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb9, unwind: bb2]; +- _6 = &mut ((*_3).3: AsyncInt); +- _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb2]; ++ _47 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); ++ _12 = &mut ((*_47).3: AsyncInt); ++ _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb9, unwind: bb2]; } bb11: { -- StorageDead(_12); +- StorageDead(_10); - goto -> bb1; + nop; -+ _52 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_52).2: SyncInt)) -> [return: bb10, unwind: bb3]; ++ _48 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_48).2: SyncInt)) -> [return: bb10, unwind: bb3]; } - bb12: { -- StorageDead(_12); +- StorageDead(_10); - goto -> bb1; + bb12 (cleanup): { + nop; @@ -167,98 +161,95 @@ } - bb13 (cleanup): { -- StorageDead(_12); +- StorageDead(_10); - goto -> bb2; + bb13: { -+ _37 = move _2; ++ _33 = move _2; + goto -> bb24; } bb14: { -- async drop(((*_3).3: AsyncInt); poll=_12) -> [return: bb11, unwind: bb13, drop: bb12]; -+ _19 = copy (_18.0: &mut AsyncInt); +- async drop(((*_3).3: AsyncInt); poll=_10) -> [return: bb11, unwind: bb13, drop: bb12]; + nop; -+ (((*_47) as variant#7).1: impl std::future::Future) = async_drop_in_place::(move _19) -> [return: bb13, unwind: bb12]; ++ (((*_43) as variant#7).1: impl std::future::Future) = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb13, unwind: bb12]; } bb15: { -- _15 = copy (_14.0: &mut AsyncInt); -- StorageLive(_12); -- _12 = async_drop_in_place::(move _15) -> [return: bb14, unwind: bb13]; -+ _53 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ _17 = &mut ((*_53).1: AsyncInt); -+ _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb14, unwind: bb4]; +- StorageLive(_10); +- _10 = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb14, unwind: bb13]; ++ _49 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); ++ _15 = &mut ((*_49).1: AsyncInt); ++ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb14, unwind: bb4]; } bb16: { -- _13 = &mut ((*_3).3: AsyncInt); -- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb15, unwind: bb2]; +- _12 = &mut ((*_3).3: AsyncInt); +- _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb15, unwind: bb2]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb16, unwind: bb28]; } bb17: { -- StorageDead(_16); +- StorageDead(_13); - drop(((*_3).2: SyncInt)) -> [return: bb16, unwind: bb3]; + _0 = Poll::<()>::Pending; -+ discriminant((*_47)) = 4; ++ discriminant((*_43)) = 4; + return; } bb18: { -- StorageDead(_16); +- StorageDead(_13); - drop(((*_3).2: SyncInt)) -> [return: bb10, unwind: bb3]; -+ StorageLive(_30); -+ _29 = &mut (((*_47) as variant#5).0: impl std::future::Future); -+ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb21, unwind: bb28]; ++ StorageLive(_26); ++ _25 = &mut (((*_43) as variant#5).0: impl std::future::Future); ++ _26 = Pin::<&mut impl Future>::new_unchecked(move _25) -> [return: bb21, unwind: bb28]; } - bb19 (cleanup): { -- StorageDead(_16); +- StorageDead(_13); - goto -> bb4; + bb19: { + unreachable; } bb20: { -- async drop(((*_3).1: AsyncInt); poll=_16) -> [return: bb17, unwind: bb19, drop: bb18]; -+ StorageDead(_30); -+ _31 = discriminant(_27); -+ switchInt(move _31) -> [0: bb6, 1: bb17, otherwise: bb19]; +- async drop(((*_3).1: AsyncInt); poll=_13) -> [return: bb17, unwind: bb19, drop: bb18]; ++ StorageDead(_26); ++ _27 = discriminant(_23); ++ switchInt(move _27) -> [0: bb6, 1: bb17, otherwise: bb19]; } bb21: { -- _19 = copy (_18.0: &mut AsyncInt); -- StorageLive(_16); -- _16 = async_drop_in_place::(move _19) -> [return: bb20, unwind: bb19]; -+ _27 = as Future>::poll(move _30, move _28) -> [return: bb20, unwind: bb7]; +- StorageLive(_13); +- _13 = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb20, unwind: bb19]; ++ _23 = as Future>::poll(move _26, move _24) -> [return: bb20, unwind: bb7]; } bb22: { -- _17 = &mut ((*_3).1: AsyncInt); -- _18 = Pin::<&mut AsyncInt>::new_unchecked(move _17) -> [return: bb21, unwind: bb4]; +- _15 = &mut ((*_3).1: AsyncInt); +- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb21, unwind: bb4]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb28]; + } + + bb23: { + _0 = Poll::<()>::Pending; -+ discriminant((*_47)) = 6; ++ discriminant((*_43)) = 6; + return; + } + + bb24: { -+ StorageLive(_39); -+ _38 = &mut (((*_47) as variant#7).1: impl std::future::Future); -+ _39 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb26, unwind: bb28]; ++ StorageLive(_35); ++ _34 = &mut (((*_43) as variant#7).1: impl std::future::Future); ++ _35 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb26, unwind: bb28]; + } + + bb25: { -+ StorageDead(_39); -+ _40 = discriminant(_36); -+ switchInt(move _40) -> [0: bb11, 1: bb23, otherwise: bb19]; ++ StorageDead(_35); ++ _36 = discriminant(_32); ++ switchInt(move _36) -> [0: bb11, 1: bb23, otherwise: bb19]; + } + + bb26: { -+ _36 = as Future>::poll(move _39, move _37) -> [return: bb25, unwind: bb12]; ++ _32 = as Future>::poll(move _35, move _33) -> [return: bb25, unwind: bb12]; + } + + bb27: { @@ -266,32 +257,32 @@ + } + + bb28 (cleanup): { -+ discriminant((*_47)) = 2; ++ discriminant((*_43)) = 2; + resume; + } + + bb29: { -+ _23 = move _2; ++ _19 = move _2; + goto -> bb16; + } + + bb30: { -+ _28 = move _2; ++ _24 = move _2; + goto -> bb18; + } + + bb31: { -+ _32 = move _2; ++ _28 = move _2; + goto -> bb22; + } + + bb32: { -+ _37 = move _2; ++ _33 = move _2; + goto -> bb24; + } + + bb33: { -+ _41 = move _2; ++ _37 = move _2; + goto -> bb27; + } + @@ -305,10 +296,10 @@ + } + + bb36: { -+ (((*_47) as variant#7).0: &mut SyncThenAsync) = move ((*_47).0: &mut SyncThenAsync); -+ _54 = no_retag copy (((*_47) as variant#7).0: &mut SyncThenAsync); -+ _20 = &mut (*_54); -+ _21 = ::drop(move _20) -> [return: bb15, unwind: bb5]; ++ (((*_43) as variant#7).0: &mut SyncThenAsync) = move ((*_43).0: &mut SyncThenAsync); ++ _50 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); ++ _16 = &mut (*_50); ++ _17 = ::drop(move _16) -> [return: bb15, unwind: bb5]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff index 7ce5a342b8623..f7df7875c0fb0 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff @@ -8,17 +8,14 @@ let mut _0: (); let _3: SyncInt; + let mut _6: impl std::future::Future; -+ let mut _7: &mut AsyncInt; -+ let mut _8: std::pin::Pin<&mut AsyncInt>; -+ let mut _9: &mut AsyncInt; -+ let mut _10: impl std::future::Future; ++ let mut _7: std::pin::Pin<&mut AsyncInt>; ++ let mut _8: &mut AsyncInt; ++ let mut _9: impl std::future::Future; ++ let mut _10: std::pin::Pin<&mut AsyncInt>; + let mut _11: &mut AsyncInt; -+ let mut _12: std::pin::Pin<&mut AsyncInt>; -+ let mut _13: &mut AsyncInt; -+ let mut _14: impl std::future::Future; -+ let mut _15: &mut {async fn body of double()}; -+ let mut _16: std::pin::Pin<&mut {async fn body of double()}>; -+ let mut _17: &mut {async fn body of double()}; ++ let mut _12: impl std::future::Future; ++ let mut _13: std::pin::Pin<&mut {async fn body of double()}>; ++ let mut _14: &mut {async fn body of double()}; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -137,74 +134,71 @@ + } + + bb19: { -+ _9 = copy (_8.0: &mut AsyncInt); + StorageLive(_6); -+ _6 = async_drop_in_place::(move _9) -> [return: bb18, unwind: bb17]; ++ _6 = async_drop_in_place::(copy (_7.0: &mut AsyncInt)) -> [return: bb18, unwind: bb17]; + } + + bb20: { -+ _7 = &mut _5; -+ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb19, unwind: bb9]; ++ _8 = &mut _5; ++ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _8) -> [return: bb19, unwind: bb9]; + } + + bb21: { -+ StorageDead(_10); ++ StorageDead(_9); + goto -> bb2; + } + + bb22: { -+ StorageDead(_10); ++ StorageDead(_9); + goto -> bb6; + } + + bb23 (cleanup): { -+ StorageDead(_10); ++ StorageDead(_9); + goto -> bb10; + } + + bb24: { -+ async drop(_4; poll=_10) -> [return: bb21, unwind: bb23, drop: bb22]; ++ async drop(_4; poll=_9) -> [return: bb21, unwind: bb23, drop: bb22]; + } + + bb25: { -+ _13 = copy (_12.0: &mut AsyncInt); -+ StorageLive(_10); -+ _10 = async_drop_in_place::(move _13) -> [return: bb24, unwind: bb23]; ++ StorageLive(_9); ++ _9 = async_drop_in_place::(copy (_10.0: &mut AsyncInt)) -> [return: bb24, unwind: bb23]; + } + + bb26: { + _11 = &mut _4; -+ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb25, unwind: bb10]; ++ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb25, unwind: bb10]; + } + + bb27: { -+ StorageDead(_14); ++ StorageDead(_12); + goto -> bb4; + } + + bb28: { -+ StorageDead(_14); ++ StorageDead(_12); + goto -> bb8; + } + + bb29 (cleanup): { -+ StorageDead(_14); ++ StorageDead(_12); + goto -> bb12; + } + + bb30: { -+ async drop(_1; poll=_14) -> [return: bb27, unwind: bb29, drop: bb28]; ++ async drop(_1; poll=_12) -> [return: bb27, unwind: bb29, drop: bb28]; + } + + bb31: { -+ _17 = copy (_16.0: &mut {async fn body of double()}); -+ StorageLive(_14); -+ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb30, unwind: bb29]; ++ StorageLive(_12); ++ _12 = async_drop_in_place::<{async fn body of double()}>(copy (_13.0: &mut {async fn body of double()})) -> [return: bb30, unwind: bb29]; + } + + bb32: { -+ _15 = &mut _1; -+ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb31, unwind: bb12]; ++ _14 = &mut _1; ++ _13 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _14) -> [return: bb31, unwind: bb12]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff index 121de06ec08f4..14cb91c056b96 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff @@ -29,51 +29,48 @@ + let mut _0: std::task::Poll<()>; let _3: SyncInt; let mut _6: impl std::future::Future; - let mut _7: &mut AsyncInt; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: impl std::future::Future; + let mut _7: std::pin::Pin<&mut AsyncInt>; + let mut _8: &mut AsyncInt; + let mut _9: impl std::future::Future; + let mut _10: std::pin::Pin<&mut AsyncInt>; let mut _11: &mut AsyncInt; - let mut _12: std::pin::Pin<&mut AsyncInt>; - let mut _13: &mut AsyncInt; - let mut _14: impl std::future::Future; - let mut _15: &mut {async fn body of double()}; - let mut _16: std::pin::Pin<&mut {async fn body of double()}>; - let mut _17: &mut {async fn body of double()}; -+ let mut _18: std::task::Poll<()>; -+ let mut _19: &mut std::task::Context<'_>; -+ let mut _20: &mut impl std::future::Future; -+ let mut _21: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _22: isize; -+ let mut _23: &mut std::task::Context<'_>; -+ let mut _24: &mut impl std::future::Future; -+ let mut _25: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _26: isize; -+ let mut _27: std::task::Poll<()>; -+ let mut _28: &mut std::task::Context<'_>; -+ let mut _29: &mut impl std::future::Future; -+ let mut _30: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _31: isize; -+ let mut _32: &mut std::task::Context<'_>; -+ let mut _33: &mut impl std::future::Future; -+ let mut _34: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _35: isize; -+ let mut _36: (); -+ let mut _37: u32; -+ let mut _38: &mut {async fn body of double()}; + let mut _12: impl std::future::Future; + let mut _13: std::pin::Pin<&mut {async fn body of double()}>; + let mut _14: &mut {async fn body of double()}; ++ let mut _15: std::task::Poll<()>; ++ let mut _16: &mut std::task::Context<'_>; ++ let mut _17: &mut impl std::future::Future; ++ let mut _18: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _19: isize; ++ let mut _20: &mut std::task::Context<'_>; ++ let mut _21: &mut impl std::future::Future; ++ let mut _22: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _23: isize; ++ let mut _24: std::task::Poll<()>; ++ let mut _25: &mut std::task::Context<'_>; ++ let mut _26: &mut impl std::future::Future; ++ let mut _27: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _28: isize; ++ let mut _29: &mut std::task::Context<'_>; ++ let mut _30: &mut impl std::future::Future; ++ let mut _31: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _32: isize; ++ let mut _33: (); ++ let mut _34: u32; ++ let mut _35: &mut {async fn body of double()}; scope 1 { - debug sync_int => _3; -+ debug sync_int => (((*_38) as variant#6).0: SyncInt); ++ debug sync_int => (((*_35) as variant#6).0: SyncInt); + coroutine debug async_int => _s2; let _4: AsyncInt; scope 2 { - debug async_int => _4; -+ debug async_int => (((*_38) as variant#6).1: AsyncInt); ++ debug async_int => (((*_35) as variant#6).1: AsyncInt); + coroutine debug async_int_again => _s3; let _5: AsyncInt; scope 3 { - debug async_int_again => _5; -+ debug async_int_again => (((*_38) as variant#4).2: AsyncInt); ++ debug async_int_again => (((*_35) as variant#4).2: AsyncInt); } } } @@ -87,9 +84,9 @@ - _5 = AsyncInt(const 0_i32); - _0 = const (); - goto -> bb18; -+ _38 = copy (_1.0: &mut {async fn body of double()}); -+ _37 = discriminant((*_38)); -+ switchInt(move _37) -> [0: bb43, 1: bb42, 2: bb41, 3: bb37, 4: bb38, 5: bb39, 6: bb40, otherwise: bb26]; ++ _35 = copy (_1.0: &mut {async fn body of double()}); ++ _34 = discriminant((*_35)); ++ switchInt(move _34) -> [0: bb43, 1: bb42, 2: bb41, 3: bb37, 4: bb38, 5: bb39, 6: bb40, otherwise: bb26]; } bb1: { @@ -103,7 +100,7 @@ - StorageDead(_4); - drop(_3) -> [return: bb3, unwind: bb11]; + nop; -+ drop((((*_38) as variant#6).0: SyncInt)) -> [return: bb3, unwind: bb7]; ++ drop((((*_35) as variant#6).0: SyncInt)) -> [return: bb3, unwind: bb7]; } bb3: { @@ -114,8 +111,8 @@ } bb4: { -+ _0 = Poll::<()>::Ready(move (((*_38) as variant#5).0: ())); -+ discriminant((*_38)) = 1; ++ _0 = Poll::<()>::Ready(move (((*_35) as variant#5).0: ())); ++ discriminant((*_35)) = 1; return; } @@ -124,7 +121,7 @@ - goto -> bb6; + bb5 (cleanup): { + nop; -+ drop((((*_38) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; ++ drop((((*_35) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; } - bb6: { @@ -132,7 +129,7 @@ - goto -> bb7; + bb6 (cleanup): { + nop; -+ drop((((*_38) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; ++ drop((((*_35) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; } - bb7: { @@ -167,23 +164,22 @@ - StorageDead(_3); - drop(_1) -> [return: bb12, unwind terminate(cleanup)]; + bb11: { -+ _19 = move _2; ++ _16 = move _2; + goto -> bb25; } - bb12 (cleanup): { - resume; + bb12: { -+ _9 = copy (_8.0: &mut AsyncInt); + nop; -+ (((*_38) as variant#4).3: impl std::future::Future) = async_drop_in_place::(move _9) -> [return: bb11, unwind: bb10]; ++ (((*_35) as variant#4).3: impl std::future::Future) = async_drop_in_place::(copy (_7.0: &mut AsyncInt)) -> [return: bb11, unwind: bb10]; } bb13: { - StorageDead(_6); - goto -> bb1; -+ _7 = &mut (((*_38) as variant#4).2: AsyncInt); -+ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb12, unwind: bb5]; ++ _8 = &mut (((*_35) as variant#4).2: AsyncInt); ++ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _8) -> [return: bb12, unwind: bb5]; } bb14: { @@ -202,128 +198,123 @@ bb16: { - async drop(_5; poll=_6) -> [return: bb13, unwind: bb15, drop: bb14]; -+ _28 = move _2; ++ _25 = move _2; + goto -> bb31; } bb17: { -- _9 = copy (_8.0: &mut AsyncInt); - StorageLive(_6); -- _6 = async_drop_in_place::(move _9) -> [return: bb16, unwind: bb15]; -+ _13 = copy (_12.0: &mut AsyncInt); +- _6 = async_drop_in_place::(copy (_7.0: &mut AsyncInt)) -> [return: bb16, unwind: bb15]; + nop; -+ (((*_38) as variant#6).2: impl std::future::Future) = async_drop_in_place::(move _13) -> [return: bb16, unwind: bb15]; ++ (((*_35) as variant#6).2: impl std::future::Future) = async_drop_in_place::(copy (_10.0: &mut AsyncInt)) -> [return: bb16, unwind: bb15]; } bb18: { -- _7 = &mut _5; -- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb17, unwind: bb9]; -+ _11 = &mut (((*_38) as variant#6).1: AsyncInt); -+ _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb17, unwind: bb6]; +- _8 = &mut _5; +- _7 = Pin::<&mut AsyncInt>::new_unchecked(move _8) -> [return: bb17, unwind: bb9]; ++ _11 = &mut (((*_35) as variant#6).1: AsyncInt); ++ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb17, unwind: bb6]; } bb19: { -- StorageDead(_10); +- StorageDead(_9); - goto -> bb2; -+ StorageDead(_14); ++ StorageDead(_12); + goto -> bb4; } - bb20: { -- StorageDead(_10); +- StorageDead(_9); - goto -> bb6; + bb20 (cleanup): { -+ StorageDead(_14); ++ StorageDead(_12); + goto -> bb8; } - bb21 (cleanup): { -- StorageDead(_10); +- StorageDead(_9); - goto -> bb10; + bb21: { + goto -> bb35; } bb22: { -- async drop(_4; poll=_10) -> [return: bb19, unwind: bb21, drop: bb20]; -+ _17 = copy (_16.0: &mut {async fn body of double()}); -+ StorageLive(_14); -+ _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb21, unwind: bb20]; +- async drop(_4; poll=_9) -> [return: bb19, unwind: bb21, drop: bb20]; ++ StorageLive(_12); ++ _12 = async_drop_in_place::<{async fn body of double()}>(copy (_13.0: &mut {async fn body of double()})) -> [return: bb21, unwind: bb20]; } bb23: { -- _13 = copy (_12.0: &mut AsyncInt); -- StorageLive(_10); -- _10 = async_drop_in_place::(move _13) -> [return: bb22, unwind: bb21]; -+ _15 = &mut (*_38); -+ _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb22, unwind: bb8]; +- StorageLive(_9); +- _9 = async_drop_in_place::(copy (_10.0: &mut AsyncInt)) -> [return: bb22, unwind: bb21]; ++ _14 = &mut (*_35); ++ _13 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _14) -> [return: bb22, unwind: bb8]; } bb24: { - _11 = &mut _4; -- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb23, unwind: bb10]; +- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb23, unwind: bb10]; + _0 = Poll::<()>::Pending; -+ discriminant((*_38)) = 3; ++ discriminant((*_35)) = 3; + return; } bb25: { -- StorageDead(_14); +- StorageDead(_12); - goto -> bb4; -+ StorageLive(_21); -+ _20 = &mut (((*_38) as variant#4).3: impl std::future::Future); -+ _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb28, unwind: bb36]; ++ StorageLive(_18); ++ _17 = &mut (((*_35) as variant#4).3: impl std::future::Future); ++ _18 = Pin::<&mut impl Future>::new_unchecked(move _17) -> [return: bb28, unwind: bb36]; } bb26: { -- StorageDead(_14); +- StorageDead(_12); - goto -> bb8; + unreachable; } - bb27 (cleanup): { -- StorageDead(_14); +- StorageDead(_12); - goto -> bb12; + bb27: { -+ StorageDead(_21); -+ _22 = discriminant(_18); -+ switchInt(move _22) -> [0: bb9, 1: bb24, otherwise: bb26]; ++ StorageDead(_18); ++ _19 = discriminant(_15); ++ switchInt(move _19) -> [0: bb9, 1: bb24, otherwise: bb26]; } bb28: { -- async drop(_1; poll=_14) -> [return: bb25, unwind: bb27, drop: bb26]; -+ _18 = as Future>::poll(move _21, move _19) -> [return: bb27, unwind: bb10]; +- async drop(_1; poll=_12) -> [return: bb25, unwind: bb27, drop: bb26]; ++ _15 = as Future>::poll(move _18, move _16) -> [return: bb27, unwind: bb10]; } bb29: { -- _17 = copy (_16.0: &mut {async fn body of double()}); -- StorageLive(_14); -- _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb28, unwind: bb27]; +- StorageLive(_12); +- _12 = async_drop_in_place::<{async fn body of double()}>(copy (_13.0: &mut {async fn body of double()})) -> [return: bb28, unwind: bb27]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb29, unwind: bb36]; } bb30: { -- _15 = &mut _1; -- _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb29, unwind: bb12]; +- _14 = &mut _1; +- _13 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _14) -> [return: bb29, unwind: bb12]; + _0 = Poll::<()>::Pending; -+ discriminant((*_38)) = 5; ++ discriminant((*_35)) = 5; + return; + } + + bb31: { -+ StorageLive(_30); -+ _29 = &mut (((*_38) as variant#6).2: impl std::future::Future); -+ _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb33, unwind: bb36]; ++ StorageLive(_27); ++ _26 = &mut (((*_35) as variant#6).2: impl std::future::Future); ++ _27 = Pin::<&mut impl Future>::new_unchecked(move _26) -> [return: bb33, unwind: bb36]; + } + + bb32: { -+ StorageDead(_30); -+ _31 = discriminant(_27); -+ switchInt(move _31) -> [0: bb14, 1: bb30, otherwise: bb26]; ++ StorageDead(_27); ++ _28 = discriminant(_24); ++ switchInt(move _28) -> [0: bb14, 1: bb30, otherwise: bb26]; + } + + bb33: { -+ _27 = as Future>::poll(move _30, move _28) -> [return: bb32, unwind: bb15]; ++ _24 = as Future>::poll(move _27, move _25) -> [return: bb32, unwind: bb15]; + } + + bb34: { @@ -335,27 +326,27 @@ + } + + bb36 (cleanup): { -+ discriminant((*_38)) = 2; ++ discriminant((*_35)) = 2; + resume; + } + + bb37: { -+ _19 = move _2; ++ _16 = move _2; + goto -> bb25; + } + + bb38: { -+ _23 = move _2; ++ _20 = move _2; + goto -> bb29; + } + + bb39: { -+ _28 = move _2; ++ _25 = move _2; + goto -> bb31; + } + + bb40: { -+ _32 = move _2; ++ _29 = move _2; + goto -> bb34; + } + @@ -369,12 +360,12 @@ + + bb43: { + nop; -+ (((*_38) as variant#6).0: SyncInt) = SyncInt(const 0_i32); ++ (((*_35) as variant#6).0: SyncInt) = SyncInt(const 0_i32); + nop; -+ (((*_38) as variant#6).1: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_35) as variant#6).1: AsyncInt) = AsyncInt(const 0_i32); + nop; -+ (((*_38) as variant#4).2: AsyncInt) = AsyncInt(const 0_i32); -+ (((*_38) as variant#5).0: ()) = const (); ++ (((*_35) as variant#4).2: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_35) as variant#5).0: ()) = const (); + goto -> bb13; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir index 27e865fd22188..01a90a4a8fa5a 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir @@ -7,35 +7,32 @@ yields () let mut _0: (); let _3: SyncInt; let mut _6: impl std::future::Future; - let mut _7: &mut AsyncInt; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: impl std::future::Future; + let mut _7: std::pin::Pin<&mut AsyncInt>; + let mut _8: &mut AsyncInt; + let mut _9: impl std::future::Future; + let mut _10: std::pin::Pin<&mut AsyncInt>; let mut _11: &mut AsyncInt; - let mut _12: std::pin::Pin<&mut AsyncInt>; - let mut _13: &mut AsyncInt; - let mut _14: impl std::future::Future; - let mut _15: &mut {async fn body of double()}; - let mut _16: std::pin::Pin<&mut {async fn body of double()}>; - let mut _17: &mut {async fn body of double()}; - let mut _18: std::task::Poll<()>; - let mut _19: &mut std::task::Context<'_>; - let mut _20: &mut impl std::future::Future; - let mut _21: std::pin::Pin<&mut impl std::future::Future>; - let mut _22: isize; - let mut _23: &mut std::task::Context<'_>; - let mut _24: &mut impl std::future::Future; - let mut _25: std::pin::Pin<&mut impl std::future::Future>; - let mut _26: isize; - let mut _27: std::task::Poll<()>; - let mut _28: &mut std::task::Context<'_>; - let mut _29: &mut impl std::future::Future; - let mut _30: std::pin::Pin<&mut impl std::future::Future>; - let mut _31: isize; - let mut _32: &mut std::task::Context<'_>; - let mut _33: &mut impl std::future::Future; - let mut _34: std::pin::Pin<&mut impl std::future::Future>; - let mut _35: isize; + let mut _12: impl std::future::Future; + let mut _13: std::pin::Pin<&mut {async fn body of double()}>; + let mut _14: &mut {async fn body of double()}; + let mut _15: std::task::Poll<()>; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut impl std::future::Future; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: isize; + let mut _20: &mut std::task::Context<'_>; + let mut _21: &mut impl std::future::Future; + let mut _22: std::pin::Pin<&mut impl std::future::Future>; + let mut _23: isize; + let mut _24: std::task::Poll<()>; + let mut _25: &mut std::task::Context<'_>; + let mut _26: &mut impl std::future::Future; + let mut _27: std::pin::Pin<&mut impl std::future::Future>; + let mut _28: isize; + let mut _29: &mut std::task::Context<'_>; + let mut _30: &mut impl std::future::Future; + let mut _31: std::pin::Pin<&mut impl std::future::Future>; + let mut _32: isize; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -132,64 +129,62 @@ yields () } bb16: { - _19 = move _2; + _16 = move _2; goto -> bb32; } bb17: { - _9 = copy (_8.0: &mut AsyncInt); StorageLive(_6); - _6 = async_drop_in_place::(move _9) -> [return: bb16, unwind: bb15]; + _6 = async_drop_in_place::(copy (_7.0: &mut AsyncInt)) -> [return: bb16, unwind: bb15]; } bb18: { - _7 = &mut _5; - _8 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb17, unwind: bb9]; + _8 = &mut _5; + _7 = Pin::<&mut AsyncInt>::new_unchecked(move _8) -> [return: bb17, unwind: bb9]; } bb19: { - StorageDead(_10); + StorageDead(_9); goto -> bb2; } bb20: { - StorageDead(_10); + StorageDead(_9); goto -> bb6; } bb21 (cleanup): { - StorageDead(_10); + StorageDead(_9); goto -> bb10; } bb22: { - _28 = move _2; + _25 = move _2; goto -> bb43; } bb23: { - _13 = copy (_12.0: &mut AsyncInt); - StorageLive(_10); - _10 = async_drop_in_place::(move _13) -> [return: bb22, unwind: bb21]; + StorageLive(_9); + _9 = async_drop_in_place::(copy (_10.0: &mut AsyncInt)) -> [return: bb22, unwind: bb21]; } bb24: { _11 = &mut _4; - _12 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb23, unwind: bb10]; + _10 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb23, unwind: bb10]; } bb25: { - StorageDead(_14); + StorageDead(_12); goto -> bb4; } bb26: { - StorageDead(_14); + StorageDead(_12); goto -> bb8; } bb27 (cleanup): { - StorageDead(_14); + StorageDead(_12); goto -> bb12; } @@ -198,24 +193,23 @@ yields () } bb29: { - _17 = copy (_16.0: &mut {async fn body of double()}); - StorageLive(_14); - _14 = async_drop_in_place::<{async fn body of double()}>(move _17) -> [return: bb28, unwind: bb27]; + StorageLive(_12); + _12 = async_drop_in_place::<{async fn body of double()}>(copy (_13.0: &mut {async fn body of double()})) -> [return: bb28, unwind: bb27]; } bb30: { - _15 = &mut _1; - _16 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _15) -> [return: bb29, unwind: bb12]; + _14 = &mut _1; + _13 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _14) -> [return: bb29, unwind: bb12]; } bb31: { - _19 = yield(const false) -> [resume: bb32, drop: bb37]; + _16 = yield(const false) -> [resume: bb32, drop: bb37]; } bb32: { - StorageLive(_21); - _20 = &mut _6; - _21 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb35, unwind continue]; + StorageLive(_18); + _17 = &mut _6; + _18 = Pin::<&mut impl Future>::new_unchecked(move _17) -> [return: bb35, unwind continue]; } bb33: { @@ -223,23 +217,23 @@ yields () } bb34: { - StorageDead(_21); - _22 = discriminant(_18); - switchInt(move _22) -> [0: bb13, 1: bb31, otherwise: bb33]; + StorageDead(_18); + _19 = discriminant(_15); + switchInt(move _19) -> [0: bb13, 1: bb31, otherwise: bb33]; } bb35: { - _18 = as Future>::poll(move _21, move _19) -> [return: bb34, unwind: bb15]; + _15 = as Future>::poll(move _18, move _16) -> [return: bb34, unwind: bb15]; } bb36: { - _23 = yield(const false) -> [resume: bb41, drop: bb37]; + _20 = yield(const false) -> [resume: bb41, drop: bb37]; } bb37: { - StorageLive(_25); - _24 = &mut _6; - _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb40, unwind continue]; + StorageLive(_22); + _21 = &mut _6; + _22 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb40, unwind continue]; } bb38: { @@ -247,13 +241,13 @@ yields () } bb39: { - StorageDead(_25); - _26 = discriminant(_18); - switchInt(move _26) -> [0: bb14, 1: bb36, otherwise: bb38]; + StorageDead(_22); + _23 = discriminant(_15); + switchInt(move _23) -> [0: bb14, 1: bb36, otherwise: bb38]; } bb40: { - _18 = as Future>::poll(move _25, move _23) -> [return: bb39, unwind: bb15]; + _15 = as Future>::poll(move _22, move _20) -> [return: bb39, unwind: bb15]; } bb41: { @@ -261,13 +255,13 @@ yields () } bb42: { - _28 = yield(const false) -> [resume: bb43, drop: bb48]; + _25 = yield(const false) -> [resume: bb43, drop: bb48]; } bb43: { - StorageLive(_30); - _29 = &mut _10; - _30 = Pin::<&mut impl Future>::new_unchecked(move _29) -> [return: bb46, unwind continue]; + StorageLive(_27); + _26 = &mut _9; + _27 = Pin::<&mut impl Future>::new_unchecked(move _26) -> [return: bb46, unwind continue]; } bb44: { @@ -275,23 +269,23 @@ yields () } bb45: { - StorageDead(_30); - _31 = discriminant(_27); - switchInt(move _31) -> [0: bb19, 1: bb42, otherwise: bb44]; + StorageDead(_27); + _28 = discriminant(_24); + switchInt(move _28) -> [0: bb19, 1: bb42, otherwise: bb44]; } bb46: { - _27 = as Future>::poll(move _30, move _28) -> [return: bb45, unwind: bb21]; + _24 = as Future>::poll(move _27, move _25) -> [return: bb45, unwind: bb21]; } bb47: { - _32 = yield(const false) -> [resume: bb52, drop: bb48]; + _29 = yield(const false) -> [resume: bb52, drop: bb48]; } bb48: { - StorageLive(_34); - _33 = &mut _10; - _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb51, unwind continue]; + StorageLive(_31); + _30 = &mut _9; + _31 = Pin::<&mut impl Future>::new_unchecked(move _30) -> [return: bb51, unwind continue]; } bb49: { @@ -299,13 +293,13 @@ yields () } bb50: { - StorageDead(_34); - _35 = discriminant(_27); - switchInt(move _35) -> [0: bb20, 1: bb47, otherwise: bb49]; + StorageDead(_31); + _32 = discriminant(_24); + switchInt(move _32) -> [0: bb20, 1: bb47, otherwise: bb49]; } bb51: { - _27 = as Future>::poll(move _34, move _32) -> [return: bb50, unwind: bb21]; + _24 = as Future>::poll(move _31, move _29) -> [return: bb50, unwind: bb21]; } bb52: { diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir index 6852a990e54f8..fcdfbad469ce7 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir @@ -5,54 +5,51 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte let mut _0: std::task::Poll<()>; let _3: SyncInt; let mut _6: impl std::future::Future; - let mut _7: &mut AsyncInt; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: impl std::future::Future; + let mut _7: std::pin::Pin<&mut AsyncInt>; + let mut _8: &mut AsyncInt; + let mut _9: impl std::future::Future; + let mut _10: std::pin::Pin<&mut AsyncInt>; let mut _11: &mut AsyncInt; - let mut _12: std::pin::Pin<&mut AsyncInt>; - let mut _13: &mut AsyncInt; - let mut _14: impl std::future::Future; - let mut _15: &mut {async fn body of double()}; - let mut _16: std::pin::Pin<&mut {async fn body of double()}>; - let mut _17: &mut {async fn body of double()}; - let mut _18: std::task::Poll<()>; - let mut _19: &mut std::task::Context<'_>; - let mut _20: &mut impl std::future::Future; - let mut _21: std::pin::Pin<&mut impl std::future::Future>; - let mut _22: isize; - let mut _23: &mut std::task::Context<'_>; - let mut _24: &mut impl std::future::Future; - let mut _25: std::pin::Pin<&mut impl std::future::Future>; - let mut _26: isize; - let mut _27: std::task::Poll<()>; - let mut _28: &mut std::task::Context<'_>; - let mut _29: &mut impl std::future::Future; - let mut _30: std::pin::Pin<&mut impl std::future::Future>; - let mut _31: isize; - let mut _32: &mut std::task::Context<'_>; - let mut _33: &mut impl std::future::Future; - let mut _34: std::pin::Pin<&mut impl std::future::Future>; - let mut _35: isize; - let mut _36: (); - let mut _37: u32; - let mut _38: &mut {async fn body of double()}; + let mut _12: impl std::future::Future; + let mut _13: std::pin::Pin<&mut {async fn body of double()}>; + let mut _14: &mut {async fn body of double()}; + let mut _15: std::task::Poll<()>; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut impl std::future::Future; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: isize; + let mut _20: &mut std::task::Context<'_>; + let mut _21: &mut impl std::future::Future; + let mut _22: std::pin::Pin<&mut impl std::future::Future>; + let mut _23: isize; + let mut _24: std::task::Poll<()>; + let mut _25: &mut std::task::Context<'_>; + let mut _26: &mut impl std::future::Future; + let mut _27: std::pin::Pin<&mut impl std::future::Future>; + let mut _28: isize; + let mut _29: &mut std::task::Context<'_>; + let mut _30: &mut impl std::future::Future; + let mut _31: std::pin::Pin<&mut impl std::future::Future>; + let mut _32: isize; + let mut _33: (); + let mut _34: u32; + let mut _35: &mut {async fn body of double()}; scope 1 { - debug sync_int => (((*_38) as variant#6).0: SyncInt); + debug sync_int => (((*_35) as variant#6).0: SyncInt); let _4: AsyncInt; scope 2 { - debug async_int => (((*_38) as variant#6).1: AsyncInt); + debug async_int => (((*_35) as variant#6).1: AsyncInt); let _5: AsyncInt; scope 3 { - debug async_int_again => (((*_38) as variant#4).2: AsyncInt); + debug async_int_again => (((*_35) as variant#4).2: AsyncInt); } } } bb0: { - _38 = copy (_1.0: &mut {async fn body of double()}); - _37 = discriminant((*_38)); - switchInt(move _37) -> [0: bb23, 2: bb30, 3: bb26, 4: bb27, 5: bb28, 6: bb29, otherwise: bb31]; + _35 = copy (_1.0: &mut {async fn body of double()}); + _34 = discriminant((*_35)); + switchInt(move _34) -> [0: bb23, 2: bb30, 3: bb26, 4: bb27, 5: bb28, 6: bb29, otherwise: bb31]; } bb1: { @@ -77,12 +74,12 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte bb5 (cleanup): { nop; - drop((((*_38) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; + drop((((*_35) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; } bb6 (cleanup): { nop; - drop((((*_38) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; + drop((((*_35) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; } bb7 (cleanup): { @@ -116,14 +113,14 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte bb13: { _0 = Poll::<()>::Pending; - discriminant((*_38)) = 4; + discriminant((*_35)) = 4; return; } bb14: { - StorageLive(_25); - _24 = &mut (((*_38) as variant#4).3: impl std::future::Future); - _25 = Pin::<&mut impl Future>::new_unchecked(move _24) -> [return: bb17, unwind: bb25]; + StorageLive(_22); + _21 = &mut (((*_35) as variant#4).3: impl std::future::Future); + _22 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb17, unwind: bb25]; } bb15: { @@ -131,35 +128,35 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte } bb16: { - StorageDead(_25); - _26 = discriminant(_18); - switchInt(move _26) -> [0: bb9, 1: bb13, otherwise: bb15]; + StorageDead(_22); + _23 = discriminant(_15); + switchInt(move _23) -> [0: bb9, 1: bb13, otherwise: bb15]; } bb17: { - _18 = as Future>::poll(move _25, move _23) -> [return: bb16, unwind: bb10]; + _15 = as Future>::poll(move _22, move _20) -> [return: bb16, unwind: bb10]; } bb18: { _0 = Poll::<()>::Pending; - discriminant((*_38)) = 6; + discriminant((*_35)) = 6; return; } bb19: { - StorageLive(_34); - _33 = &mut (((*_38) as variant#6).2: impl std::future::Future); - _34 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb21, unwind: bb25]; + StorageLive(_31); + _30 = &mut (((*_35) as variant#6).2: impl std::future::Future); + _31 = Pin::<&mut impl Future>::new_unchecked(move _30) -> [return: bb21, unwind: bb25]; } bb20: { - StorageDead(_34); - _35 = discriminant(_27); - switchInt(move _35) -> [0: bb11, 1: bb18, otherwise: bb15]; + StorageDead(_31); + _32 = discriminant(_24); + switchInt(move _32) -> [0: bb11, 1: bb18, otherwise: bb15]; } bb21: { - _27 = as Future>::poll(move _34, move _32) -> [return: bb20, unwind: bb12]; + _24 = as Future>::poll(move _31, move _29) -> [return: bb20, unwind: bb12]; } bb22: { @@ -176,27 +173,27 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte } bb25 (cleanup): { - discriminant((*_38)) = 2; + discriminant((*_35)) = 2; resume; } bb26: { - _19 = move _2; + _16 = move _2; goto -> bb14; } bb27: { - _23 = move _2; + _20 = move _2; goto -> bb14; } bb28: { - _28 = move _2; + _25 = move _2; goto -> bb19; } bb29: { - _32 = move _2; + _29 = move _2; goto -> bb19; } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff index aab8937384332..204ccd0bef58f 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff @@ -19,45 +19,35 @@ let mut _21: &AsyncInt; let _22: &AsyncInt; + let mut _27: impl std::future::Future; -+ let mut _28: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; -+ let mut _29: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>; -+ let mut _30: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; -+ let mut _31: impl std::future::Future; ++ let mut _28: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>; ++ let mut _29: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; ++ let mut _30: impl std::future::Future; ++ let mut _31: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>; + let mut _32: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; -+ let mut _33: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>; -+ let mut _34: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; -+ let mut _35: impl std::future::Future; -+ let mut _36: &mut AsyncReference<'_>; -+ let mut _37: std::pin::Pin<&mut AsyncReference<'_>>; -+ let mut _38: &mut AsyncReference<'_>; ++ let mut _33: impl std::future::Future; ++ let mut _34: std::pin::Pin<&mut AsyncReference<'_>>; ++ let mut _35: &mut AsyncReference<'_>; ++ let mut _36: impl std::future::Future; ++ let mut _37: std::pin::Pin<&mut AsyncInt>; ++ let mut _38: &mut AsyncInt; + let mut _39: impl std::future::Future; -+ let mut _40: &mut AsyncInt; -+ let mut _41: std::pin::Pin<&mut AsyncInt>; -+ let mut _42: &mut AsyncInt; -+ let mut _43: impl std::future::Future; -+ let mut _44: &mut AsyncEnum; -+ let mut _45: std::pin::Pin<&mut AsyncEnum>; -+ let mut _46: &mut AsyncEnum; -+ let mut _47: impl std::future::Future; -+ let mut _48: &mut SyncThenAsync; -+ let mut _49: std::pin::Pin<&mut SyncThenAsync>; -+ let mut _50: &mut SyncThenAsync; ++ let mut _40: std::pin::Pin<&mut AsyncEnum>; ++ let mut _41: &mut AsyncEnum; ++ let mut _42: impl std::future::Future; ++ let mut _43: std::pin::Pin<&mut SyncThenAsync>; ++ let mut _44: &mut SyncThenAsync; ++ let mut _45: impl std::future::Future; ++ let mut _46: std::pin::Pin<&mut AsyncStruct>; ++ let mut _47: &mut AsyncStruct; ++ let mut _48: impl std::future::Future; ++ let mut _49: std::pin::Pin<&mut [AsyncInt; 2]>; ++ let mut _50: &mut [AsyncInt; 2]; + let mut _51: impl std::future::Future; -+ let mut _52: &mut AsyncStruct; -+ let mut _53: std::pin::Pin<&mut AsyncStruct>; -+ let mut _54: &mut AsyncStruct; -+ let mut _55: impl std::future::Future; -+ let mut _56: &mut [AsyncInt; 2]; -+ let mut _57: std::pin::Pin<&mut [AsyncInt; 2]>; -+ let mut _58: &mut [AsyncInt; 2]; -+ let mut _59: impl std::future::Future; -+ let mut _60: &mut AsyncInt; -+ let mut _61: std::pin::Pin<&mut AsyncInt>; -+ let mut _62: &mut AsyncInt; -+ let mut _63: impl std::future::Future; -+ let mut _64: &mut {async fn body of elaborate_drops()}; -+ let mut _65: std::pin::Pin<&mut {async fn body of elaborate_drops()}>; -+ let mut _66: &mut {async fn body of elaborate_drops()}; ++ let mut _52: std::pin::Pin<&mut AsyncInt>; ++ let mut _53: &mut AsyncInt; ++ let mut _54: impl std::future::Future; ++ let mut _55: std::pin::Pin<&mut {async fn body of elaborate_drops()}>; ++ let mut _56: &mut {async fn body of elaborate_drops()}; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -648,284 +638,274 @@ + } + + bb87: { -+ _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); + StorageLive(_27); -+ _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb86, unwind: bb85]; ++ _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(copy (_28.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35})) -> [return: bb86, unwind: bb85]; + } + + bb88: { -+ _28 = &mut _26; -+ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb87, unwind: bb44]; ++ _29 = &mut _26; ++ _28 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _29) -> [return: bb87, unwind: bb44]; + } + + bb89: { -+ StorageDead(_31); ++ StorageDead(_30); + goto -> bb12; + } + + bb90: { -+ StorageDead(_31); ++ StorageDead(_30); + goto -> bb25; + } + + bb91 (cleanup): { -+ StorageDead(_31); ++ StorageDead(_30); + goto -> bb46; + } + + bb92: { -+ async drop(_24; poll=_31) -> [return: bb89, unwind: bb91, drop: bb90]; ++ async drop(_24; poll=_30) -> [return: bb89, unwind: bb91, drop: bb90]; + } + + bb93: { -+ _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); -+ StorageLive(_31); -+ _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb92, unwind: bb91]; ++ StorageLive(_30); ++ _30 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(copy (_31.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb92, unwind: bb91]; + } + + bb94: { + _32 = &mut _24; -+ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb93, unwind: bb46]; ++ _31 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb93, unwind: bb46]; + } + + bb95: { -+ StorageDead(_35); ++ StorageDead(_33); + goto -> bb14; + } + + bb96: { -+ StorageDead(_35); ++ StorageDead(_33); + goto -> bb27; + } + + bb97 (cleanup): { -+ StorageDead(_35); ++ StorageDead(_33); + goto -> bb48; + } + + bb98: { -+ async drop(_20; poll=_35) -> [return: bb95, unwind: bb97, drop: bb96]; ++ async drop(_20; poll=_33) -> [return: bb95, unwind: bb97, drop: bb96]; + } + + bb99: { -+ _38 = copy (_37.0: &mut AsyncReference<'_>); -+ StorageLive(_35); -+ _35 = async_drop_in_place::>(move _38) -> [return: bb98, unwind: bb97]; ++ StorageLive(_33); ++ _33 = async_drop_in_place::>(copy (_34.0: &mut AsyncReference<'_>)) -> [return: bb98, unwind: bb97]; + } + + bb100: { -+ _36 = &mut _20; -+ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb99, unwind: bb48]; ++ _35 = &mut _20; ++ _34 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _35) -> [return: bb99, unwind: bb48]; + } + + bb101: { -+ StorageDead(_39); ++ StorageDead(_36); + goto -> bb15; + } + + bb102: { -+ StorageDead(_39); ++ StorageDead(_36); + goto -> bb28; + } + + bb103 (cleanup): { -+ StorageDead(_39); ++ StorageDead(_36); + goto -> bb49; + } + + bb104: { -+ async drop(_19; poll=_39) -> [return: bb101, unwind: bb103, drop: bb102]; ++ async drop(_19; poll=_36) -> [return: bb101, unwind: bb103, drop: bb102]; + } + + bb105: { -+ _42 = copy (_41.0: &mut AsyncInt); -+ StorageLive(_39); -+ _39 = async_drop_in_place::(move _42) -> [return: bb104, unwind: bb103]; ++ StorageLive(_36); ++ _36 = async_drop_in_place::(copy (_37.0: &mut AsyncInt)) -> [return: bb104, unwind: bb103]; + } + + bb106: { -+ _40 = &mut _19; -+ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb105, unwind: bb49]; ++ _38 = &mut _19; ++ _37 = Pin::<&mut AsyncInt>::new_unchecked(move _38) -> [return: bb105, unwind: bb49]; + } + + bb107: { -+ StorageDead(_43); ++ StorageDead(_39); + goto -> bb16; + } + + bb108: { -+ StorageDead(_43); ++ StorageDead(_39); + goto -> bb30; + } + + bb109 (cleanup): { -+ StorageDead(_43); ++ StorageDead(_39); + goto -> bb54; + } + + bb110: { -+ async drop(_15; poll=_43) -> [return: bb107, unwind: bb109, drop: bb108]; ++ async drop(_15; poll=_39) -> [return: bb107, unwind: bb109, drop: bb108]; + } + + bb111: { -+ _46 = copy (_45.0: &mut AsyncEnum); -+ StorageLive(_43); -+ _43 = async_drop_in_place::(move _46) -> [return: bb110, unwind: bb109]; ++ StorageLive(_39); ++ _39 = async_drop_in_place::(copy (_40.0: &mut AsyncEnum)) -> [return: bb110, unwind: bb109]; + } + + bb112: { -+ _44 = &mut _15; -+ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb111, unwind: bb54]; ++ _41 = &mut _15; ++ _40 = Pin::<&mut AsyncEnum>::new_unchecked(move _41) -> [return: bb111, unwind: bb54]; + } + + bb113: { -+ StorageDead(_47); ++ StorageDead(_42); + goto -> bb17; + } + + bb114: { -+ StorageDead(_47); ++ StorageDead(_42); + goto -> bb34; + } + + bb115 (cleanup): { -+ StorageDead(_47); ++ StorageDead(_42); + goto -> bb58; + } + + bb116: { -+ async drop(_11; poll=_47) -> [return: bb113, unwind: bb115, drop: bb114]; ++ async drop(_11; poll=_42) -> [return: bb113, unwind: bb115, drop: bb114]; + } + + bb117: { -+ _50 = copy (_49.0: &mut SyncThenAsync); -+ StorageLive(_47); -+ _47 = async_drop_in_place::(move _50) -> [return: bb116, unwind: bb115]; ++ StorageLive(_42); ++ _42 = async_drop_in_place::(copy (_43.0: &mut SyncThenAsync)) -> [return: bb116, unwind: bb115]; + } + + bb118: { -+ _48 = &mut _11; -+ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb117, unwind: bb58]; ++ _44 = &mut _11; ++ _43 = Pin::<&mut SyncThenAsync>::new_unchecked(move _44) -> [return: bb117, unwind: bb58]; + } + + bb119: { -+ StorageDead(_51); ++ StorageDead(_45); + goto -> bb18; + } + + bb120: { -+ StorageDead(_51); ++ StorageDead(_45); + goto -> bb37; + } + + bb121 (cleanup): { -+ StorageDead(_51); ++ StorageDead(_45); + goto -> bb61; + } + + bb122: { -+ async drop(_8; poll=_51) -> [return: bb119, unwind: bb121, drop: bb120]; ++ async drop(_8; poll=_45) -> [return: bb119, unwind: bb121, drop: bb120]; + } + + bb123: { -+ _54 = copy (_53.0: &mut AsyncStruct); -+ StorageLive(_51); -+ _51 = async_drop_in_place::(move _54) -> [return: bb122, unwind: bb121]; ++ StorageLive(_45); ++ _45 = async_drop_in_place::(copy (_46.0: &mut AsyncStruct)) -> [return: bb122, unwind: bb121]; + } + + bb124: { -+ _52 = &mut _8; -+ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb123, unwind: bb61]; ++ _47 = &mut _8; ++ _46 = Pin::<&mut AsyncStruct>::new_unchecked(move _47) -> [return: bb123, unwind: bb61]; + } + + bb125: { -+ StorageDead(_55); ++ StorageDead(_48); + goto -> bb19; + } + + bb126: { -+ StorageDead(_55); ++ StorageDead(_48); + goto -> bb40; + } + + bb127 (cleanup): { -+ StorageDead(_55); ++ StorageDead(_48); + goto -> bb64; + } + + bb128: { -+ async drop(_5; poll=_55) -> [return: bb125, unwind: bb127, drop: bb126]; ++ async drop(_5; poll=_48) -> [return: bb125, unwind: bb127, drop: bb126]; + } + + bb129: { -+ _58 = copy (_57.0: &mut [AsyncInt; 2]); -+ StorageLive(_55); -+ _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb128, unwind: bb127]; ++ StorageLive(_48); ++ _48 = async_drop_in_place::<[AsyncInt; 2]>(copy (_49.0: &mut [AsyncInt; 2])) -> [return: bb128, unwind: bb127]; + } + + bb130: { -+ _56 = &mut _5; -+ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb129, unwind: bb64]; ++ _50 = &mut _5; ++ _49 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _50) -> [return: bb129, unwind: bb64]; + } + + bb131: { -+ StorageDead(_59); ++ StorageDead(_51); + goto -> bb20; + } + + bb132: { -+ StorageDead(_59); ++ StorageDead(_51); + goto -> bb41; + } + + bb133 (cleanup): { -+ StorageDead(_59); ++ StorageDead(_51); + goto -> bb65; + } + + bb134: { -+ async drop(_4; poll=_59) -> [return: bb131, unwind: bb133, drop: bb132]; ++ async drop(_4; poll=_51) -> [return: bb131, unwind: bb133, drop: bb132]; + } + + bb135: { -+ _62 = copy (_61.0: &mut AsyncInt); -+ StorageLive(_59); -+ _59 = async_drop_in_place::(move _62) -> [return: bb134, unwind: bb133]; ++ StorageLive(_51); ++ _51 = async_drop_in_place::(copy (_52.0: &mut AsyncInt)) -> [return: bb134, unwind: bb133]; + } + + bb136: { -+ _60 = &mut _4; -+ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb135, unwind: bb65]; ++ _53 = &mut _4; ++ _52 = Pin::<&mut AsyncInt>::new_unchecked(move _53) -> [return: bb135, unwind: bb65]; + } + + bb137: { -+ StorageDead(_63); ++ StorageDead(_54); + goto -> bb22; + } + + bb138: { -+ StorageDead(_63); ++ StorageDead(_54); + goto -> bb43; + } + + bb139 (cleanup): { -+ StorageDead(_63); ++ StorageDead(_54); + goto -> bb67; + } + + bb140: { -+ async drop(_1; poll=_63) -> [return: bb137, unwind: bb139, drop: bb138]; ++ async drop(_1; poll=_54) -> [return: bb137, unwind: bb139, drop: bb138]; + } + + bb141: { -+ _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); -+ StorageLive(_63); -+ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb140, unwind: bb139]; ++ StorageLive(_54); ++ _54 = async_drop_in_place::<{async fn body of elaborate_drops()}>(copy (_55.0: &mut {async fn body of elaborate_drops()})) -> [return: bb140, unwind: bb139]; + } + + bb142: { -+ _64 = &mut _1; -+ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb141, unwind: bb67]; ++ _56 = &mut _1; ++ _55 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _56) -> [return: bb141, unwind: bb67]; } } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff index ba5f8099dbe95..12fd87a786c29 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff @@ -68,157 +68,147 @@ let mut _21: &AsyncInt; let _22: &AsyncInt; let mut _27: impl std::future::Future; - let mut _28: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; - let mut _29: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>; - let mut _30: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; - let mut _31: impl std::future::Future; + let mut _28: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>; + let mut _29: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; + let mut _30: impl std::future::Future; + let mut _31: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>; let mut _32: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; - let mut _33: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>; - let mut _34: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; - let mut _35: impl std::future::Future; - let mut _36: &mut AsyncReference<'_>; - let mut _37: std::pin::Pin<&mut AsyncReference<'_>>; - let mut _38: &mut AsyncReference<'_>; + let mut _33: impl std::future::Future; + let mut _34: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _35: &mut AsyncReference<'_>; + let mut _36: impl std::future::Future; + let mut _37: std::pin::Pin<&mut AsyncInt>; + let mut _38: &mut AsyncInt; let mut _39: impl std::future::Future; - let mut _40: &mut AsyncInt; - let mut _41: std::pin::Pin<&mut AsyncInt>; - let mut _42: &mut AsyncInt; - let mut _43: impl std::future::Future; - let mut _44: &mut AsyncEnum; - let mut _45: std::pin::Pin<&mut AsyncEnum>; - let mut _46: &mut AsyncEnum; - let mut _47: impl std::future::Future; - let mut _48: &mut SyncThenAsync; - let mut _49: std::pin::Pin<&mut SyncThenAsync>; - let mut _50: &mut SyncThenAsync; + let mut _40: std::pin::Pin<&mut AsyncEnum>; + let mut _41: &mut AsyncEnum; + let mut _42: impl std::future::Future; + let mut _43: std::pin::Pin<&mut SyncThenAsync>; + let mut _44: &mut SyncThenAsync; + let mut _45: impl std::future::Future; + let mut _46: std::pin::Pin<&mut AsyncStruct>; + let mut _47: &mut AsyncStruct; + let mut _48: impl std::future::Future; + let mut _49: std::pin::Pin<&mut [AsyncInt; 2]>; + let mut _50: &mut [AsyncInt; 2]; let mut _51: impl std::future::Future; - let mut _52: &mut AsyncStruct; - let mut _53: std::pin::Pin<&mut AsyncStruct>; - let mut _54: &mut AsyncStruct; - let mut _55: impl std::future::Future; - let mut _56: &mut [AsyncInt; 2]; - let mut _57: std::pin::Pin<&mut [AsyncInt; 2]>; - let mut _58: &mut [AsyncInt; 2]; - let mut _59: impl std::future::Future; - let mut _60: &mut AsyncInt; - let mut _61: std::pin::Pin<&mut AsyncInt>; - let mut _62: &mut AsyncInt; - let mut _63: impl std::future::Future; - let mut _64: &mut {async fn body of elaborate_drops()}; - let mut _65: std::pin::Pin<&mut {async fn body of elaborate_drops()}>; - let mut _66: &mut {async fn body of elaborate_drops()}; -+ let mut _67: std::task::Poll<()>; -+ let mut _68: &mut std::task::Context<'_>; -+ let mut _69: &mut impl std::future::Future; -+ let mut _70: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _71: isize; -+ let mut _72: &mut std::task::Context<'_>; -+ let mut _73: &mut impl std::future::Future; -+ let mut _74: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _75: isize; -+ let mut _76: std::task::Poll<()>; -+ let mut _77: &mut std::task::Context<'_>; -+ let mut _78: &mut impl std::future::Future; -+ let mut _79: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _80: isize; -+ let mut _81: &mut std::task::Context<'_>; -+ let mut _82: &mut impl std::future::Future; -+ let mut _83: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _84: isize; -+ let mut _85: std::task::Poll<()>; -+ let mut _86: &mut std::task::Context<'_>; -+ let mut _87: &mut impl std::future::Future; -+ let mut _88: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _89: isize; -+ let mut _90: &mut std::task::Context<'_>; -+ let mut _91: &mut impl std::future::Future; -+ let mut _92: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _93: isize; -+ let mut _94: std::task::Poll<()>; -+ let mut _95: &mut std::task::Context<'_>; -+ let mut _96: &mut impl std::future::Future; -+ let mut _97: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _98: isize; -+ let mut _99: &mut std::task::Context<'_>; -+ let mut _100: &mut impl std::future::Future; -+ let mut _101: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _102: isize; -+ let mut _103: std::task::Poll<()>; -+ let mut _104: &mut std::task::Context<'_>; -+ let mut _105: &mut impl std::future::Future; -+ let mut _106: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _107: isize; -+ let mut _108: &mut std::task::Context<'_>; -+ let mut _109: &mut impl std::future::Future; -+ let mut _110: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _111: isize; -+ let mut _112: std::task::Poll<()>; -+ let mut _113: &mut std::task::Context<'_>; -+ let mut _114: &mut impl std::future::Future; -+ let mut _115: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _116: isize; -+ let mut _117: &mut std::task::Context<'_>; -+ let mut _118: &mut impl std::future::Future; -+ let mut _119: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _120: isize; -+ let mut _121: std::task::Poll<()>; -+ let mut _122: &mut std::task::Context<'_>; -+ let mut _123: &mut impl std::future::Future; -+ let mut _124: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _125: isize; -+ let mut _126: &mut std::task::Context<'_>; -+ let mut _127: &mut impl std::future::Future; -+ let mut _128: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _129: isize; -+ let mut _130: std::task::Poll<()>; -+ let mut _131: &mut std::task::Context<'_>; -+ let mut _132: &mut impl std::future::Future; -+ let mut _133: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _134: isize; -+ let mut _135: &mut std::task::Context<'_>; -+ let mut _136: &mut impl std::future::Future; -+ let mut _137: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _138: isize; -+ let mut _139: std::task::Poll<()>; -+ let mut _140: &mut std::task::Context<'_>; -+ let mut _141: &mut impl std::future::Future; -+ let mut _142: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _143: isize; -+ let mut _144: &mut std::task::Context<'_>; -+ let mut _145: &mut impl std::future::Future; -+ let mut _146: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _147: isize; -+ let mut _148: (); -+ let mut _149: u32; -+ let mut _150: &mut {async fn body of elaborate_drops()}; + let mut _52: std::pin::Pin<&mut AsyncInt>; + let mut _53: &mut AsyncInt; + let mut _54: impl std::future::Future; + let mut _55: std::pin::Pin<&mut {async fn body of elaborate_drops()}>; + let mut _56: &mut {async fn body of elaborate_drops()}; ++ let mut _57: std::task::Poll<()>; ++ let mut _58: &mut std::task::Context<'_>; ++ let mut _59: &mut impl std::future::Future; ++ let mut _60: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _61: isize; ++ let mut _62: &mut std::task::Context<'_>; ++ let mut _63: &mut impl std::future::Future; ++ let mut _64: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _65: isize; ++ let mut _66: std::task::Poll<()>; ++ let mut _67: &mut std::task::Context<'_>; ++ let mut _68: &mut impl std::future::Future; ++ let mut _69: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _70: isize; ++ let mut _71: &mut std::task::Context<'_>; ++ let mut _72: &mut impl std::future::Future; ++ let mut _73: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _74: isize; ++ let mut _75: std::task::Poll<()>; ++ let mut _76: &mut std::task::Context<'_>; ++ let mut _77: &mut impl std::future::Future; ++ let mut _78: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _79: isize; ++ let mut _80: &mut std::task::Context<'_>; ++ let mut _81: &mut impl std::future::Future; ++ let mut _82: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _83: isize; ++ let mut _84: std::task::Poll<()>; ++ let mut _85: &mut std::task::Context<'_>; ++ let mut _86: &mut impl std::future::Future; ++ let mut _87: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _88: isize; ++ let mut _89: &mut std::task::Context<'_>; ++ let mut _90: &mut impl std::future::Future; ++ let mut _91: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _92: isize; ++ let mut _93: std::task::Poll<()>; ++ let mut _94: &mut std::task::Context<'_>; ++ let mut _95: &mut impl std::future::Future; ++ let mut _96: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _97: isize; ++ let mut _98: &mut std::task::Context<'_>; ++ let mut _99: &mut impl std::future::Future; ++ let mut _100: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _101: isize; ++ let mut _102: std::task::Poll<()>; ++ let mut _103: &mut std::task::Context<'_>; ++ let mut _104: &mut impl std::future::Future; ++ let mut _105: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _106: isize; ++ let mut _107: &mut std::task::Context<'_>; ++ let mut _108: &mut impl std::future::Future; ++ let mut _109: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _110: isize; ++ let mut _111: std::task::Poll<()>; ++ let mut _112: &mut std::task::Context<'_>; ++ let mut _113: &mut impl std::future::Future; ++ let mut _114: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _115: isize; ++ let mut _116: &mut std::task::Context<'_>; ++ let mut _117: &mut impl std::future::Future; ++ let mut _118: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _119: isize; ++ let mut _120: std::task::Poll<()>; ++ let mut _121: &mut std::task::Context<'_>; ++ let mut _122: &mut impl std::future::Future; ++ let mut _123: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _124: isize; ++ let mut _125: &mut std::task::Context<'_>; ++ let mut _126: &mut impl std::future::Future; ++ let mut _127: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _128: isize; ++ let mut _129: std::task::Poll<()>; ++ let mut _130: &mut std::task::Context<'_>; ++ let mut _131: &mut impl std::future::Future; ++ let mut _132: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _133: isize; ++ let mut _134: &mut std::task::Context<'_>; ++ let mut _135: &mut impl std::future::Future; ++ let mut _136: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _137: isize; ++ let mut _138: (); ++ let mut _139: u32; ++ let mut _140: &mut {async fn body of elaborate_drops()}; scope 1 { - debug sync_int => _3; -+ debug sync_int => (((*_150) as variant#20).0: SyncInt); ++ debug sync_int => (((*_140) as variant#20).0: SyncInt); + coroutine debug async_int => _s2; let _4: AsyncInt; scope 2 { - debug async_int => _4; -+ debug async_int => (((*_150) as variant#20).1: AsyncInt); ++ debug async_int => (((*_140) as variant#20).1: AsyncInt); + coroutine debug tuple => _s3; let _5: [AsyncInt; 2]; scope 3 { - debug tuple => _5; -+ debug tuple => (((*_150) as variant#18).2: [AsyncInt; 2]); ++ debug tuple => (((*_140) as variant#18).2: [AsyncInt; 2]); + coroutine debug async_struct => _s4; let _8: AsyncStruct; scope 4 { - debug async_struct => _8; -+ debug async_struct => (((*_150) as variant#16).3: AsyncStruct); ++ debug async_struct => (((*_140) as variant#16).3: AsyncStruct); + coroutine debug async_struct_mix => _s5; let _11: SyncThenAsync; scope 5 { - debug async_struct_mix => _11; -+ debug async_struct_mix => (((*_150) as variant#14).4: SyncThenAsync); ++ debug async_struct_mix => (((*_140) as variant#14).4: SyncThenAsync); + coroutine debug async_enum => _s6; let _15: AsyncEnum; scope 6 { - debug async_enum => _15; -+ debug async_enum => (((*_150) as variant#12).5: AsyncEnum); ++ debug async_enum => (((*_140) as variant#12).5: AsyncEnum); let _17: std::mem::ManuallyDrop; scope 7 { debug manually_drop_async_int => _17; @@ -226,12 +216,12 @@ let _19: AsyncInt; scope 8 { - debug foo => _19; -+ debug foo => (((*_150) as variant#10).6: AsyncInt); ++ debug foo => (((*_140) as variant#10).6: AsyncInt); + coroutine debug async_ref => _s8; let _20: AsyncReference<'_>; scope 9 { - debug async_ref => _20; -+ debug async_ref => (((*_150) as variant#8).7: AsyncReference<'_>); ++ debug async_ref => (((*_140) as variant#8).7: AsyncReference<'_>); let _23: AsyncInt; scope 10 { debug foo => _23; @@ -239,7 +229,7 @@ let _24: {closure@$DIR/async_drop.rs:72:25: 72:27}; scope 11 { - debug async_closure => _24; -+ debug async_closure => (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); ++ debug async_closure => (((*_140) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); let _25: AsyncInt; scope 12 { debug foo => _25; @@ -247,7 +237,7 @@ let _26: {async closure@$DIR/async_drop.rs:80:27: 80:35}; scope 13 { - debug async_coroutine => _26; -+ debug async_coroutine => (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ debug async_coroutine => (((*_140) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); } } } @@ -274,9 +264,9 @@ - _7 = AsyncInt(const 2_i32); - _5 = [move _6, move _7]; - goto -> bb1; -+ _150 = copy (_1.0: &mut {async fn body of elaborate_drops()}); -+ _149 = discriminant((*_150)); -+ switchInt(move _149) -> [0: bb157, 1: bb156, 2: bb155, 3: bb137, 4: bb138, 5: bb139, 6: bb140, 7: bb141, 8: bb142, 9: bb143, 10: bb144, 11: bb145, 12: bb146, 13: bb147, 14: bb148, 15: bb149, 16: bb150, 17: bb151, 18: bb152, 19: bb153, 20: bb154, otherwise: bb91]; ++ _140 = copy (_1.0: &mut {async fn body of elaborate_drops()}); ++ _139 = discriminant((*_140)); ++ switchInt(move _139) -> [0: bb157, 1: bb156, 2: bb155, 3: bb137, 4: bb138, 5: bb139, 6: bb140, 7: bb141, 8: bb142, 9: bb143, 10: bb144, 11: bb145, 12: bb146, 13: bb147, 14: bb148, 15: bb149, 16: bb150, 17: bb151, 18: bb152, 19: bb153, 20: bb154, otherwise: bb91]; } bb1: { @@ -293,7 +283,7 @@ StorageLive(_10); _10 = AsyncInt(const 4_i32); - _8 = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; -+ (((*_150) as variant#16).3: AsyncStruct) = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; ++ (((*_140) as variant#16).3: AsyncStruct) = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; goto -> bb3; } @@ -313,7 +303,7 @@ StorageLive(_14); _14 = AsyncInt(const 9_i32); - _11 = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; -+ (((*_150) as variant#14).4: SyncThenAsync) = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; ++ (((*_140) as variant#14).4: SyncThenAsync) = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; goto -> bb5; } @@ -334,7 +324,7 @@ StorageLive(_16); _16 = AsyncInt(const 10_i32); - _15 = AsyncEnum::A(move _16); -+ (((*_150) as variant#12).5: AsyncEnum) = AsyncEnum::A(move _16); ++ (((*_140) as variant#12).5: AsyncEnum) = AsyncEnum::A(move _16); goto -> bb8; } @@ -353,15 +343,15 @@ - _19 = AsyncInt(const 12_i32); - StorageLive(_20); + nop; -+ (((*_150) as variant#10).6: AsyncInt) = AsyncInt(const 12_i32); ++ (((*_140) as variant#10).6: AsyncInt) = AsyncInt(const 12_i32); + nop; StorageLive(_21); StorageLive(_22); - _22 = &_19; -+ _22 = &(((*_150) as variant#10).6: AsyncInt); ++ _22 = &(((*_140) as variant#10).6: AsyncInt); _21 = &(*_22); - _20 = AsyncReference::<'_> { foo: move _21 }; -+ (((*_150) as variant#8).7: AsyncReference<'_>) = AsyncReference::<'_> { foo: move _21 }; ++ (((*_140) as variant#8).7: AsyncReference<'_>) = AsyncReference::<'_> { foo: move _21 }; StorageDead(_21); StorageDead(_22); StorageLive(_23); @@ -369,7 +359,7 @@ - StorageLive(_24); - _24 = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; + nop; -+ (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}) = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; ++ (((*_140) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}) = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; StorageLive(_25); _25 = AsyncInt(const 15_i32); - StorageLive(_26); @@ -377,8 +367,8 @@ - _0 = const (); - goto -> bb57; + nop; -+ (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}) = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; -+ (((*_150) as variant#19).0: ()) = const (); ++ (((*_140) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}) = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; ++ (((*_140) as variant#19).0: ()) = const (); + goto -> bb43; } @@ -453,7 +443,7 @@ - StorageDead(_4); - drop(_3) -> [return: bb21, unwind: bb50]; + nop; -+ drop((((*_150) as variant#20).0: SyncInt)) -> [return: bb21, unwind: bb37]; ++ drop((((*_140) as variant#20).0: SyncInt)) -> [return: bb21, unwind: bb37]; } bb21: { @@ -464,8 +454,8 @@ } bb22: { -+ _0 = Poll::<()>::Ready(move (((*_150) as variant#19).0: ())); -+ discriminant((*_150)) = 1; ++ _0 = Poll::<()>::Ready(move (((*_140) as variant#19).0: ())); ++ discriminant((*_140)) = 1; return; } @@ -480,7 +470,7 @@ + bb24 (cleanup): { StorageDead(_25); - goto -> bb25; -+ drop((((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb25, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb25, unwind terminate(cleanup)]; } - bb25: { @@ -494,7 +484,7 @@ + bb26 (cleanup): { StorageDead(_23); - goto -> bb27; -+ drop((((*_150) as variant#8).7: AsyncReference<'_>)) -> [return: bb27, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#8).7: AsyncReference<'_>)) -> [return: bb27, unwind terminate(cleanup)]; } - bb27: { @@ -502,7 +492,7 @@ - goto -> bb28; + bb27 (cleanup): { + nop; -+ drop((((*_150) as variant#10).6: AsyncInt)) -> [return: bb28, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#10).6: AsyncInt)) -> [return: bb28, unwind terminate(cleanup)]; } - bb28: { @@ -532,7 +522,7 @@ - goto -> bb32; + bb31 (cleanup): { + StorageDead(_17); -+ drop((((*_150) as variant#12).5: AsyncEnum)) -> [return: bb32, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#12).5: AsyncEnum)) -> [return: bb32, unwind terminate(cleanup)]; } - bb32: { @@ -540,7 +530,7 @@ - goto -> bb33; + bb32 (cleanup): { + nop; -+ drop((((*_150) as variant#14).4: SyncThenAsync)) -> [return: bb33, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#14).4: SyncThenAsync)) -> [return: bb33, unwind terminate(cleanup)]; } - bb33: { @@ -548,7 +538,7 @@ - goto -> bb34; + bb33 (cleanup): { + nop; -+ drop((((*_150) as variant#16).3: AsyncStruct)) -> [return: bb34, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#16).3: AsyncStruct)) -> [return: bb34, unwind terminate(cleanup)]; } - bb34: { @@ -556,21 +546,21 @@ - goto -> bb35; + bb34 (cleanup): { + nop; -+ drop((((*_150) as variant#18).2: [AsyncInt; 2])) -> [return: bb35, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#18).2: [AsyncInt; 2])) -> [return: bb35, unwind terminate(cleanup)]; } - bb35: { - coroutine_drop; + bb35 (cleanup): { + nop; -+ drop((((*_150) as variant#20).1: AsyncInt)) -> [return: bb36, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#20).1: AsyncInt)) -> [return: bb36, unwind terminate(cleanup)]; } bb36 (cleanup): { - StorageDead(_26); - goto -> bb37; + nop; -+ drop((((*_150) as variant#20).0: SyncInt)) -> [return: bb37, unwind terminate(cleanup)]; ++ drop((((*_140) as variant#20).0: SyncInt)) -> [return: bb37, unwind terminate(cleanup)]; } bb37 (cleanup): { @@ -605,24 +595,23 @@ - StorageDead(_19); - goto -> bb44; + bb41: { -+ _68 = move _2; ++ _58 = move _2; + goto -> bb90; } - bb42 (cleanup): { - goto -> bb43; + bb42: { -+ _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); + nop; -+ (((*_150) as variant#4).10: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb41, unwind: bb40]; ++ (((*_140) as variant#4).10: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(copy (_28.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35})) -> [return: bb41, unwind: bb40]; } - bb43 (cleanup): { - StorageDead(_18); - goto -> bb44; + bb43: { -+ _28 = &mut (((*_150) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); -+ _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb42, unwind: bb23]; ++ _29 = &mut (((*_140) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ _28 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _29) -> [return: bb42, unwind: bb23]; } - bb44 (cleanup): { @@ -644,7 +633,7 @@ - StorageDead(_11); - drop(_8) -> [return: bb47, unwind terminate(cleanup)]; + bb46: { -+ _77 = move _2; ++ _67 = move _2; + goto -> bb96; } @@ -652,17 +641,16 @@ - StorageDead(_8); - drop(_5) -> [return: bb48, unwind terminate(cleanup)]; + bb47: { -+ _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); + nop; -+ (((*_150) as variant#6).9: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb46, unwind: bb45]; ++ (((*_140) as variant#6).9: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(copy (_31.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb46, unwind: bb45]; } - bb48 (cleanup): { - StorageDead(_5); - drop(_4) -> [return: bb49, unwind terminate(cleanup)]; + bb48: { -+ _32 = &mut (((*_150) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); -+ _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb47, unwind: bb25]; ++ _32 = &mut (((*_140) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); ++ _31 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb47, unwind: bb25]; } - bb49 (cleanup): { @@ -683,23 +671,22 @@ - bb51 (cleanup): { - resume; + bb51: { -+ _86 = move _2; ++ _76 = move _2; + goto -> bb101; } bb52: { - StorageDead(_27); - goto -> bb10; -+ _38 = copy (_37.0: &mut AsyncReference<'_>); + nop; -+ (((*_150) as variant#8).8: impl std::future::Future) = async_drop_in_place::>(move _38) -> [return: bb51, unwind: bb50]; ++ (((*_140) as variant#8).8: impl std::future::Future) = async_drop_in_place::>(copy (_34.0: &mut AsyncReference<'_>)) -> [return: bb51, unwind: bb50]; } bb53: { - StorageDead(_27); - goto -> bb23; -+ _36 = &mut (((*_150) as variant#8).7: AsyncReference<'_>); -+ _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb52, unwind: bb27]; ++ _35 = &mut (((*_140) as variant#8).7: AsyncReference<'_>); ++ _34 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _35) -> [return: bb52, unwind: bb27]; } - bb54 (cleanup): { @@ -718,73 +705,69 @@ } bb56: { -- _30 = copy (_29.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}); - StorageLive(_27); -- _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(move _30) -> [return: bb55, unwind: bb54]; -+ _95 = move _2; +- _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(copy (_28.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35})) -> [return: bb55, unwind: bb54]; ++ _85 = move _2; + goto -> bb106; } bb57: { -- _28 = &mut _26; -- _29 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _28) -> [return: bb56, unwind: bb36]; -+ _42 = copy (_41.0: &mut AsyncInt); +- _29 = &mut _26; +- _28 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _29) -> [return: bb56, unwind: bb36]; + nop; -+ (((*_150) as variant#10).7: impl std::future::Future) = async_drop_in_place::(move _42) -> [return: bb56, unwind: bb55]; ++ (((*_140) as variant#10).7: impl std::future::Future) = async_drop_in_place::(copy (_37.0: &mut AsyncInt)) -> [return: bb56, unwind: bb55]; } bb58: { -- StorageDead(_31); +- StorageDead(_30); - goto -> bb12; -+ _40 = &mut (((*_150) as variant#10).6: AsyncInt); -+ _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb57, unwind: bb28]; ++ _38 = &mut (((*_140) as variant#10).6: AsyncInt); ++ _37 = Pin::<&mut AsyncInt>::new_unchecked(move _38) -> [return: bb57, unwind: bb28]; } bb59: { -- StorageDead(_31); +- StorageDead(_30); - goto -> bb25; + nop; + goto -> bb16; } bb60 (cleanup): { -- StorageDead(_31); +- StorageDead(_30); - goto -> bb38; + nop; + goto -> bb32; } bb61: { -- async drop(_24; poll=_31) -> [return: bb58, unwind: bb60, drop: bb59]; -+ _104 = move _2; +- async drop(_24; poll=_30) -> [return: bb58, unwind: bb60, drop: bb59]; ++ _94 = move _2; + goto -> bb111; } bb62: { -- _34 = copy (_33.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}); -- StorageLive(_31); -- _31 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(move _34) -> [return: bb61, unwind: bb60]; -+ _46 = copy (_45.0: &mut AsyncEnum); +- StorageLive(_30); +- _30 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(copy (_31.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb61, unwind: bb60]; + nop; -+ (((*_150) as variant#12).6: impl std::future::Future) = async_drop_in_place::(move _46) -> [return: bb61, unwind: bb60]; ++ (((*_140) as variant#12).6: impl std::future::Future) = async_drop_in_place::(copy (_40.0: &mut AsyncEnum)) -> [return: bb61, unwind: bb60]; } bb63: { - _32 = &mut _24; -- _33 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb62, unwind: bb38]; -+ _44 = &mut (((*_150) as variant#12).5: AsyncEnum); -+ _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb62, unwind: bb32]; +- _31 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb62, unwind: bb38]; ++ _41 = &mut (((*_140) as variant#12).5: AsyncEnum); ++ _40 = Pin::<&mut AsyncEnum>::new_unchecked(move _41) -> [return: bb62, unwind: bb32]; } bb64: { -- StorageDead(_35); +- StorageDead(_33); - goto -> bb14; + nop; + goto -> bb17; } - bb65: { -- StorageDead(_35); +- StorageDead(_33); - goto -> bb27; + bb65 (cleanup): { + nop; @@ -792,37 +775,35 @@ } - bb66 (cleanup): { -- StorageDead(_35); +- StorageDead(_33); - goto -> bb40; + bb66: { -+ _113 = move _2; ++ _103 = move _2; + goto -> bb116; } bb67: { -- async drop(_20; poll=_35) -> [return: bb64, unwind: bb66, drop: bb65]; -+ _50 = copy (_49.0: &mut SyncThenAsync); +- async drop(_20; poll=_33) -> [return: bb64, unwind: bb66, drop: bb65]; + nop; -+ (((*_150) as variant#14).5: impl std::future::Future) = async_drop_in_place::(move _50) -> [return: bb66, unwind: bb65]; ++ (((*_140) as variant#14).5: impl std::future::Future) = async_drop_in_place::(copy (_43.0: &mut SyncThenAsync)) -> [return: bb66, unwind: bb65]; } bb68: { -- _38 = copy (_37.0: &mut AsyncReference<'_>); -- StorageLive(_35); -- _35 = async_drop_in_place::>(move _38) -> [return: bb67, unwind: bb66]; -+ _48 = &mut (((*_150) as variant#14).4: SyncThenAsync); -+ _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb67, unwind: bb33]; +- StorageLive(_33); +- _33 = async_drop_in_place::>(copy (_34.0: &mut AsyncReference<'_>)) -> [return: bb67, unwind: bb66]; ++ _44 = &mut (((*_140) as variant#14).4: SyncThenAsync); ++ _43 = Pin::<&mut SyncThenAsync>::new_unchecked(move _44) -> [return: bb67, unwind: bb33]; } bb69: { -- _36 = &mut _20; -- _37 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _36) -> [return: bb68, unwind: bb40]; +- _35 = &mut _20; +- _34 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _35) -> [return: bb68, unwind: bb40]; + nop; + goto -> bb18; } - bb70: { -- StorageDead(_39); +- StorageDead(_36); - goto -> bb15; + bb70 (cleanup): { + nop; @@ -830,325 +811,314 @@ } bb71: { -- StorageDead(_39); +- StorageDead(_36); - goto -> bb28; -+ _122 = move _2; ++ _112 = move _2; + goto -> bb121; } - bb72 (cleanup): { -- StorageDead(_39); +- StorageDead(_36); - goto -> bb41; + bb72: { -+ _54 = copy (_53.0: &mut AsyncStruct); + nop; -+ (((*_150) as variant#16).4: impl std::future::Future) = async_drop_in_place::(move _54) -> [return: bb71, unwind: bb70]; ++ (((*_140) as variant#16).4: impl std::future::Future) = async_drop_in_place::(copy (_46.0: &mut AsyncStruct)) -> [return: bb71, unwind: bb70]; } bb73: { -- async drop(_19; poll=_39) -> [return: bb70, unwind: bb72, drop: bb71]; -+ _52 = &mut (((*_150) as variant#16).3: AsyncStruct); -+ _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb72, unwind: bb34]; +- async drop(_19; poll=_36) -> [return: bb70, unwind: bb72, drop: bb71]; ++ _47 = &mut (((*_140) as variant#16).3: AsyncStruct); ++ _46 = Pin::<&mut AsyncStruct>::new_unchecked(move _47) -> [return: bb72, unwind: bb34]; } bb74: { -- _42 = copy (_41.0: &mut AsyncInt); -- StorageLive(_39); -- _39 = async_drop_in_place::(move _42) -> [return: bb73, unwind: bb72]; +- StorageLive(_36); +- _36 = async_drop_in_place::(copy (_37.0: &mut AsyncInt)) -> [return: bb73, unwind: bb72]; + nop; + goto -> bb19; } - bb75: { -- _40 = &mut _19; -- _41 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb74, unwind: bb41]; +- _38 = &mut _19; +- _37 = Pin::<&mut AsyncInt>::new_unchecked(move _38) -> [return: bb74, unwind: bb41]; + bb75 (cleanup): { + nop; + goto -> bb35; } bb76: { -- StorageDead(_43); +- StorageDead(_39); - goto -> bb16; -+ _131 = move _2; ++ _121 = move _2; + goto -> bb126; } bb77: { -- StorageDead(_43); +- StorageDead(_39); - goto -> bb29; -+ _58 = copy (_57.0: &mut [AsyncInt; 2]); + nop; -+ (((*_150) as variant#18).3: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb76, unwind: bb75]; ++ (((*_140) as variant#18).3: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(copy (_49.0: &mut [AsyncInt; 2])) -> [return: bb76, unwind: bb75]; } - bb78 (cleanup): { -- StorageDead(_43); +- StorageDead(_39); - goto -> bb45; + bb78: { -+ _56 = &mut (((*_150) as variant#18).2: [AsyncInt; 2]); -+ _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb77, unwind: bb35]; ++ _50 = &mut (((*_140) as variant#18).2: [AsyncInt; 2]); ++ _49 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _50) -> [return: bb77, unwind: bb35]; } bb79: { -- async drop(_15; poll=_43) -> [return: bb76, unwind: bb78, drop: bb77]; +- async drop(_15; poll=_39) -> [return: bb76, unwind: bb78, drop: bb77]; + nop; + goto -> bb20; } - bb80: { -- _46 = copy (_45.0: &mut AsyncEnum); -- StorageLive(_43); -- _43 = async_drop_in_place::(move _46) -> [return: bb79, unwind: bb78]; +- StorageLive(_39); +- _39 = async_drop_in_place::(copy (_40.0: &mut AsyncEnum)) -> [return: bb79, unwind: bb78]; + bb80 (cleanup): { + nop; + goto -> bb36; } bb81: { -- _44 = &mut _15; -- _45 = Pin::<&mut AsyncEnum>::new_unchecked(move _44) -> [return: bb80, unwind: bb45]; -+ _140 = move _2; +- _41 = &mut _15; +- _40 = Pin::<&mut AsyncEnum>::new_unchecked(move _41) -> [return: bb80, unwind: bb45]; ++ _130 = move _2; + goto -> bb131; } bb82: { -- StorageDead(_47); +- StorageDead(_42); - goto -> bb17; -+ _62 = copy (_61.0: &mut AsyncInt); + nop; -+ (((*_150) as variant#20).2: impl std::future::Future) = async_drop_in_place::(move _62) -> [return: bb81, unwind: bb80]; ++ (((*_140) as variant#20).2: impl std::future::Future) = async_drop_in_place::(copy (_52.0: &mut AsyncInt)) -> [return: bb81, unwind: bb80]; } bb83: { -- StorageDead(_47); +- StorageDead(_42); - goto -> bb30; -+ _60 = &mut (((*_150) as variant#20).1: AsyncInt); -+ _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb82, unwind: bb36]; ++ _53 = &mut (((*_140) as variant#20).1: AsyncInt); ++ _52 = Pin::<&mut AsyncInt>::new_unchecked(move _53) -> [return: bb82, unwind: bb36]; } - bb84 (cleanup): { -- StorageDead(_47); +- StorageDead(_42); - goto -> bb46; + bb84: { -+ StorageDead(_63); ++ StorageDead(_54); + goto -> bb22; } - bb85: { -- async drop(_11; poll=_47) -> [return: bb82, unwind: bb84, drop: bb83]; +- async drop(_11; poll=_42) -> [return: bb82, unwind: bb84, drop: bb83]; + bb85 (cleanup): { -+ StorageDead(_63); ++ StorageDead(_54); + goto -> bb38; } bb86: { -- _50 = copy (_49.0: &mut SyncThenAsync); -- StorageLive(_47); -- _47 = async_drop_in_place::(move _50) -> [return: bb85, unwind: bb84]; +- StorageLive(_42); +- _42 = async_drop_in_place::(copy (_43.0: &mut SyncThenAsync)) -> [return: bb85, unwind: bb84]; + goto -> bb135; } bb87: { -- _48 = &mut _11; -- _49 = Pin::<&mut SyncThenAsync>::new_unchecked(move _48) -> [return: bb86, unwind: bb46]; -+ _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); -+ StorageLive(_63); -+ _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb86, unwind: bb85]; +- _44 = &mut _11; +- _43 = Pin::<&mut SyncThenAsync>::new_unchecked(move _44) -> [return: bb86, unwind: bb46]; ++ StorageLive(_54); ++ _54 = async_drop_in_place::<{async fn body of elaborate_drops()}>(copy (_55.0: &mut {async fn body of elaborate_drops()})) -> [return: bb86, unwind: bb85]; } bb88: { -- StorageDead(_51); +- StorageDead(_45); - goto -> bb18; -+ _64 = &mut (*_150); -+ _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb87, unwind: bb38]; ++ _56 = &mut (*_140); ++ _55 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _56) -> [return: bb87, unwind: bb38]; } bb89: { -- StorageDead(_51); +- StorageDead(_45); - goto -> bb31; + _0 = Poll::<()>::Pending; + StorageDead(_17); + StorageDead(_23); + StorageDead(_25); -+ discriminant((*_150)) = 3; ++ discriminant((*_140)) = 3; + return; } - bb90 (cleanup): { -- StorageDead(_51); +- StorageDead(_45); - goto -> bb47; + bb90: { -+ StorageLive(_70); -+ _69 = &mut (((*_150) as variant#4).10: impl std::future::Future); -+ _70 = Pin::<&mut impl Future>::new_unchecked(move _69) -> [return: bb93, unwind: bb136]; ++ StorageLive(_60); ++ _59 = &mut (((*_140) as variant#4).10: impl std::future::Future); ++ _60 = Pin::<&mut impl Future>::new_unchecked(move _59) -> [return: bb93, unwind: bb136]; } bb91: { -- async drop(_8; poll=_51) -> [return: bb88, unwind: bb90, drop: bb89]; +- async drop(_8; poll=_45) -> [return: bb88, unwind: bb90, drop: bb89]; + unreachable; } bb92: { -- _54 = copy (_53.0: &mut AsyncStruct); -- StorageLive(_51); -- _51 = async_drop_in_place::(move _54) -> [return: bb91, unwind: bb90]; -+ StorageDead(_70); -+ _71 = discriminant(_67); -+ switchInt(move _71) -> [0: bb39, 1: bb89, otherwise: bb91]; +- StorageLive(_45); +- _45 = async_drop_in_place::(copy (_46.0: &mut AsyncStruct)) -> [return: bb91, unwind: bb90]; ++ StorageDead(_60); ++ _61 = discriminant(_57); ++ switchInt(move _61) -> [0: bb39, 1: bb89, otherwise: bb91]; } bb93: { -- _52 = &mut _8; -- _53 = Pin::<&mut AsyncStruct>::new_unchecked(move _52) -> [return: bb92, unwind: bb47]; -+ _67 = as Future>::poll(move _70, move _68) -> [return: bb92, unwind: bb40]; +- _47 = &mut _8; +- _46 = Pin::<&mut AsyncStruct>::new_unchecked(move _47) -> [return: bb92, unwind: bb47]; ++ _57 = as Future>::poll(move _60, move _58) -> [return: bb92, unwind: bb40]; } bb94: { -- StorageDead(_55); +- StorageDead(_48); - goto -> bb19; + assert(const false, "`async fn` resumed after async drop") -> [success: bb94, unwind: bb136]; } bb95: { -- StorageDead(_55); +- StorageDead(_48); - goto -> bb32; + _0 = Poll::<()>::Pending; + StorageDead(_17); + StorageDead(_23); -+ discriminant((*_150)) = 5; ++ discriminant((*_140)) = 5; + return; } - bb96 (cleanup): { -- StorageDead(_55); +- StorageDead(_48); - goto -> bb48; + bb96: { -+ StorageLive(_79); -+ _78 = &mut (((*_150) as variant#6).9: impl std::future::Future); -+ _79 = Pin::<&mut impl Future>::new_unchecked(move _78) -> [return: bb98, unwind: bb136]; ++ StorageLive(_69); ++ _68 = &mut (((*_140) as variant#6).9: impl std::future::Future); ++ _69 = Pin::<&mut impl Future>::new_unchecked(move _68) -> [return: bb98, unwind: bb136]; } bb97: { -- async drop(_5; poll=_55) -> [return: bb94, unwind: bb96, drop: bb95]; -+ StorageDead(_79); -+ _80 = discriminant(_76); -+ switchInt(move _80) -> [0: bb44, 1: bb95, otherwise: bb91]; +- async drop(_5; poll=_48) -> [return: bb94, unwind: bb96, drop: bb95]; ++ StorageDead(_69); ++ _70 = discriminant(_66); ++ switchInt(move _70) -> [0: bb44, 1: bb95, otherwise: bb91]; } bb98: { -- _58 = copy (_57.0: &mut [AsyncInt; 2]); -- StorageLive(_55); -- _55 = async_drop_in_place::<[AsyncInt; 2]>(move _58) -> [return: bb97, unwind: bb96]; -+ _76 = as Future>::poll(move _79, move _77) -> [return: bb97, unwind: bb45]; +- StorageLive(_48); +- _48 = async_drop_in_place::<[AsyncInt; 2]>(copy (_49.0: &mut [AsyncInt; 2])) -> [return: bb97, unwind: bb96]; ++ _66 = as Future>::poll(move _69, move _67) -> [return: bb97, unwind: bb45]; } bb99: { -- _56 = &mut _5; -- _57 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _56) -> [return: bb98, unwind: bb48]; +- _50 = &mut _5; +- _49 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _50) -> [return: bb98, unwind: bb48]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb99, unwind: bb136]; } bb100: { -- StorageDead(_59); +- StorageDead(_51); - goto -> bb20; + _0 = Poll::<()>::Pending; + StorageDead(_17); -+ discriminant((*_150)) = 7; ++ discriminant((*_140)) = 7; + return; } bb101: { -- StorageDead(_59); +- StorageDead(_51); - goto -> bb33; -+ StorageLive(_88); -+ _87 = &mut (((*_150) as variant#8).8: impl std::future::Future); -+ _88 = Pin::<&mut impl Future>::new_unchecked(move _87) -> [return: bb103, unwind: bb136]; ++ StorageLive(_78); ++ _77 = &mut (((*_140) as variant#8).8: impl std::future::Future); ++ _78 = Pin::<&mut impl Future>::new_unchecked(move _77) -> [return: bb103, unwind: bb136]; } - bb102 (cleanup): { -- StorageDead(_59); +- StorageDead(_51); - goto -> bb49; + bb102: { -+ StorageDead(_88); -+ _89 = discriminant(_85); -+ switchInt(move _89) -> [0: bb49, 1: bb100, otherwise: bb91]; ++ StorageDead(_78); ++ _79 = discriminant(_75); ++ switchInt(move _79) -> [0: bb49, 1: bb100, otherwise: bb91]; } bb103: { -- async drop(_4; poll=_59) -> [return: bb100, unwind: bb102, drop: bb101]; -+ _85 = as Future>::poll(move _88, move _86) -> [return: bb102, unwind: bb50]; +- async drop(_4; poll=_51) -> [return: bb100, unwind: bb102, drop: bb101]; ++ _75 = as Future>::poll(move _78, move _76) -> [return: bb102, unwind: bb50]; } bb104: { -- _62 = copy (_61.0: &mut AsyncInt); -- StorageLive(_59); -- _59 = async_drop_in_place::(move _62) -> [return: bb103, unwind: bb102]; +- StorageLive(_51); +- _51 = async_drop_in_place::(copy (_52.0: &mut AsyncInt)) -> [return: bb103, unwind: bb102]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb104, unwind: bb136]; } bb105: { -- _60 = &mut _4; -- _61 = Pin::<&mut AsyncInt>::new_unchecked(move _60) -> [return: bb104, unwind: bb49]; +- _53 = &mut _4; +- _52 = Pin::<&mut AsyncInt>::new_unchecked(move _53) -> [return: bb104, unwind: bb49]; + _0 = Poll::<()>::Pending; + StorageDead(_17); -+ discriminant((*_150)) = 9; ++ discriminant((*_140)) = 9; + return; } bb106: { -- StorageDead(_63); +- StorageDead(_54); - goto -> bb22; -+ StorageLive(_97); -+ _96 = &mut (((*_150) as variant#10).7: impl std::future::Future); -+ _97 = Pin::<&mut impl Future>::new_unchecked(move _96) -> [return: bb108, unwind: bb136]; ++ StorageLive(_87); ++ _86 = &mut (((*_140) as variant#10).7: impl std::future::Future); ++ _87 = Pin::<&mut impl Future>::new_unchecked(move _86) -> [return: bb108, unwind: bb136]; } bb107: { -- StorageDead(_63); +- StorageDead(_54); - goto -> bb35; -+ StorageDead(_97); -+ _98 = discriminant(_94); -+ switchInt(move _98) -> [0: bb54, 1: bb105, otherwise: bb91]; ++ StorageDead(_87); ++ _88 = discriminant(_84); ++ switchInt(move _88) -> [0: bb54, 1: bb105, otherwise: bb91]; } - bb108 (cleanup): { -- StorageDead(_63); +- StorageDead(_54); - goto -> bb51; + bb108: { -+ _94 = as Future>::poll(move _97, move _95) -> [return: bb107, unwind: bb55]; ++ _84 = as Future>::poll(move _87, move _85) -> [return: bb107, unwind: bb55]; } bb109: { -- async drop(_1; poll=_63) -> [return: bb106, unwind: bb108, drop: bb107]; +- async drop(_1; poll=_54) -> [return: bb106, unwind: bb108, drop: bb107]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb109, unwind: bb136]; } bb110: { -- _66 = copy (_65.0: &mut {async fn body of elaborate_drops()}); -- StorageLive(_63); -- _63 = async_drop_in_place::<{async fn body of elaborate_drops()}>(move _66) -> [return: bb109, unwind: bb108]; +- StorageLive(_54); +- _54 = async_drop_in_place::<{async fn body of elaborate_drops()}>(copy (_55.0: &mut {async fn body of elaborate_drops()})) -> [return: bb109, unwind: bb108]; + _0 = Poll::<()>::Pending; -+ discriminant((*_150)) = 11; ++ discriminant((*_140)) = 11; + return; } bb111: { -- _64 = &mut _1; -- _65 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _64) -> [return: bb110, unwind: bb51]; -+ StorageLive(_106); -+ _105 = &mut (((*_150) as variant#12).6: impl std::future::Future); -+ _106 = Pin::<&mut impl Future>::new_unchecked(move _105) -> [return: bb113, unwind: bb136]; +- _56 = &mut _1; +- _55 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _56) -> [return: bb110, unwind: bb51]; ++ StorageLive(_96); ++ _95 = &mut (((*_140) as variant#12).6: impl std::future::Future); ++ _96 = Pin::<&mut impl Future>::new_unchecked(move _95) -> [return: bb113, unwind: bb136]; + } + + bb112: { -+ StorageDead(_106); -+ _107 = discriminant(_103); -+ switchInt(move _107) -> [0: bb59, 1: bb110, otherwise: bb91]; ++ StorageDead(_96); ++ _97 = discriminant(_93); ++ switchInt(move _97) -> [0: bb59, 1: bb110, otherwise: bb91]; + } + + bb113: { -+ _103 = as Future>::poll(move _106, move _104) -> [return: bb112, unwind: bb60]; ++ _93 = as Future>::poll(move _96, move _94) -> [return: bb112, unwind: bb60]; + } + + bb114: { @@ -1157,24 +1127,24 @@ + + bb115: { + _0 = Poll::<()>::Pending; -+ discriminant((*_150)) = 13; ++ discriminant((*_140)) = 13; + return; + } + + bb116: { -+ StorageLive(_115); -+ _114 = &mut (((*_150) as variant#14).5: impl std::future::Future); -+ _115 = Pin::<&mut impl Future>::new_unchecked(move _114) -> [return: bb118, unwind: bb136]; ++ StorageLive(_105); ++ _104 = &mut (((*_140) as variant#14).5: impl std::future::Future); ++ _105 = Pin::<&mut impl Future>::new_unchecked(move _104) -> [return: bb118, unwind: bb136]; + } + + bb117: { -+ StorageDead(_115); -+ _116 = discriminant(_112); -+ switchInt(move _116) -> [0: bb64, 1: bb115, otherwise: bb91]; ++ StorageDead(_105); ++ _106 = discriminant(_102); ++ switchInt(move _106) -> [0: bb64, 1: bb115, otherwise: bb91]; + } + + bb118: { -+ _112 = as Future>::poll(move _115, move _113) -> [return: bb117, unwind: bb65]; ++ _102 = as Future>::poll(move _105, move _103) -> [return: bb117, unwind: bb65]; + } + + bb119: { @@ -1183,24 +1153,24 @@ + + bb120: { + _0 = Poll::<()>::Pending; -+ discriminant((*_150)) = 15; ++ discriminant((*_140)) = 15; + return; + } + + bb121: { -+ StorageLive(_124); -+ _123 = &mut (((*_150) as variant#16).4: impl std::future::Future); -+ _124 = Pin::<&mut impl Future>::new_unchecked(move _123) -> [return: bb123, unwind: bb136]; ++ StorageLive(_114); ++ _113 = &mut (((*_140) as variant#16).4: impl std::future::Future); ++ _114 = Pin::<&mut impl Future>::new_unchecked(move _113) -> [return: bb123, unwind: bb136]; + } + + bb122: { -+ StorageDead(_124); -+ _125 = discriminant(_121); -+ switchInt(move _125) -> [0: bb69, 1: bb120, otherwise: bb91]; ++ StorageDead(_114); ++ _115 = discriminant(_111); ++ switchInt(move _115) -> [0: bb69, 1: bb120, otherwise: bb91]; + } + + bb123: { -+ _121 = as Future>::poll(move _124, move _122) -> [return: bb122, unwind: bb70]; ++ _111 = as Future>::poll(move _114, move _112) -> [return: bb122, unwind: bb70]; + } + + bb124: { @@ -1209,24 +1179,24 @@ + + bb125: { + _0 = Poll::<()>::Pending; -+ discriminant((*_150)) = 17; ++ discriminant((*_140)) = 17; + return; + } + + bb126: { -+ StorageLive(_133); -+ _132 = &mut (((*_150) as variant#18).3: impl std::future::Future); -+ _133 = Pin::<&mut impl Future>::new_unchecked(move _132) -> [return: bb128, unwind: bb136]; ++ StorageLive(_123); ++ _122 = &mut (((*_140) as variant#18).3: impl std::future::Future); ++ _123 = Pin::<&mut impl Future>::new_unchecked(move _122) -> [return: bb128, unwind: bb136]; + } + + bb127: { -+ StorageDead(_133); -+ _134 = discriminant(_130); -+ switchInt(move _134) -> [0: bb74, 1: bb125, otherwise: bb91]; ++ StorageDead(_123); ++ _124 = discriminant(_120); ++ switchInt(move _124) -> [0: bb74, 1: bb125, otherwise: bb91]; + } + + bb128: { -+ _130 = as Future>::poll(move _133, move _131) -> [return: bb127, unwind: bb75]; ++ _120 = as Future>::poll(move _123, move _121) -> [return: bb127, unwind: bb75]; + } + + bb129: { @@ -1235,24 +1205,24 @@ + + bb130: { + _0 = Poll::<()>::Pending; -+ discriminant((*_150)) = 19; ++ discriminant((*_140)) = 19; + return; + } + + bb131: { -+ StorageLive(_142); -+ _141 = &mut (((*_150) as variant#20).2: impl std::future::Future); -+ _142 = Pin::<&mut impl Future>::new_unchecked(move _141) -> [return: bb133, unwind: bb136]; ++ StorageLive(_132); ++ _131 = &mut (((*_140) as variant#20).2: impl std::future::Future); ++ _132 = Pin::<&mut impl Future>::new_unchecked(move _131) -> [return: bb133, unwind: bb136]; + } + + bb132: { -+ StorageDead(_142); -+ _143 = discriminant(_139); -+ switchInt(move _143) -> [0: bb79, 1: bb130, otherwise: bb91]; ++ StorageDead(_132); ++ _133 = discriminant(_129); ++ switchInt(move _133) -> [0: bb79, 1: bb130, otherwise: bb91]; + } + + bb133: { -+ _139 = as Future>::poll(move _142, move _140) -> [return: bb132, unwind: bb80]; ++ _129 = as Future>::poll(move _132, move _130) -> [return: bb132, unwind: bb80]; + } + + bb134: { @@ -1264,7 +1234,7 @@ + } + + bb136 (cleanup): { -+ discriminant((*_150)) = 2; ++ discriminant((*_140)) = 2; + resume; + } + @@ -1272,7 +1242,7 @@ + StorageLive(_17); + StorageLive(_23); + StorageLive(_25); -+ _68 = move _2; ++ _58 = move _2; + goto -> bb90; + } + @@ -1280,95 +1250,95 @@ + StorageLive(_17); + StorageLive(_23); + StorageLive(_25); -+ _72 = move _2; ++ _62 = move _2; + goto -> bb94; + } + + bb139: { + StorageLive(_17); + StorageLive(_23); -+ _77 = move _2; ++ _67 = move _2; + goto -> bb96; + } + + bb140: { + StorageLive(_17); + StorageLive(_23); -+ _81 = move _2; ++ _71 = move _2; + goto -> bb99; + } + + bb141: { + StorageLive(_17); -+ _86 = move _2; ++ _76 = move _2; + goto -> bb101; + } + + bb142: { + StorageLive(_17); -+ _90 = move _2; ++ _80 = move _2; + goto -> bb104; + } + + bb143: { + StorageLive(_17); -+ _95 = move _2; ++ _85 = move _2; + goto -> bb106; + } + + bb144: { + StorageLive(_17); -+ _99 = move _2; ++ _89 = move _2; + goto -> bb109; + } + + bb145: { -+ _104 = move _2; ++ _94 = move _2; + goto -> bb111; + } + + bb146: { -+ _108 = move _2; ++ _98 = move _2; + goto -> bb114; + } + + bb147: { -+ _113 = move _2; ++ _103 = move _2; + goto -> bb116; + } + + bb148: { -+ _117 = move _2; ++ _107 = move _2; + goto -> bb119; + } + + bb149: { -+ _122 = move _2; ++ _112 = move _2; + goto -> bb121; + } + + bb150: { -+ _126 = move _2; ++ _116 = move _2; + goto -> bb124; + } + + bb151: { -+ _131 = move _2; ++ _121 = move _2; + goto -> bb126; + } + + bb152: { -+ _135 = move _2; ++ _125 = move _2; + goto -> bb129; + } + + bb153: { -+ _140 = move _2; ++ _130 = move _2; + goto -> bb131; + } + + bb154: { -+ _144 = move _2; ++ _134 = move _2; + goto -> bb134; + } + @@ -1382,15 +1352,15 @@ + + bb157: { + nop; -+ (((*_150) as variant#20).0: SyncInt) = SyncInt(const 0_i32); ++ (((*_140) as variant#20).0: SyncInt) = SyncInt(const 0_i32); + nop; -+ (((*_150) as variant#20).1: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_140) as variant#20).1: AsyncInt) = AsyncInt(const 0_i32); + nop; + StorageLive(_6); + _6 = AsyncInt(const 1_i32); + StorageLive(_7); + _7 = AsyncInt(const 2_i32); -+ (((*_150) as variant#18).2: [AsyncInt; 2]) = [move _6, move _7]; ++ (((*_140) as variant#18).2: [AsyncInt; 2]) = [move _6, move _7]; + goto -> bb1; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff index 63d19fd2cf061..6997c2efaf3a7 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff @@ -8,13 +8,11 @@ let mut _0: (); let _3: SyncInt; + let mut _5: impl std::future::Future; -+ let mut _6: &mut AsyncInt; -+ let mut _7: std::pin::Pin<&mut AsyncInt>; -+ let mut _8: &mut AsyncInt; -+ let mut _9: impl std::future::Future; ++ let mut _6: std::pin::Pin<&mut AsyncInt>; ++ let mut _7: &mut AsyncInt; ++ let mut _8: impl std::future::Future; ++ let mut _9: std::pin::Pin<&mut {async fn body of simple()}>; + let mut _10: &mut {async fn body of simple()}; -+ let mut _11: std::pin::Pin<&mut {async fn body of simple()}>; -+ let mut _12: &mut {async fn body of simple()}; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -104,44 +102,42 @@ + } + + bb15: { -+ _8 = copy (_7.0: &mut AsyncInt); + StorageLive(_5); -+ _5 = async_drop_in_place::(move _8) -> [return: bb14, unwind: bb13]; ++ _5 = async_drop_in_place::(copy (_6.0: &mut AsyncInt)) -> [return: bb14, unwind: bb13]; + } + + bb16: { -+ _6 = &mut _4; -+ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb15, unwind: bb7]; ++ _7 = &mut _4; ++ _6 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb7]; + } + + bb17: { -+ StorageDead(_9); ++ StorageDead(_8); + goto -> bb3; + } + + bb18: { -+ StorageDead(_9); ++ StorageDead(_8); + goto -> bb6; + } + + bb19 (cleanup): { -+ StorageDead(_9); ++ StorageDead(_8); + goto -> bb9; + } + + bb20: { -+ async drop(_1; poll=_9) -> [return: bb17, unwind: bb19, drop: bb18]; ++ async drop(_1; poll=_8) -> [return: bb17, unwind: bb19, drop: bb18]; + } + + bb21: { -+ _12 = copy (_11.0: &mut {async fn body of simple()}); -+ StorageLive(_9); -+ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb20, unwind: bb19]; ++ StorageLive(_8); ++ _8 = async_drop_in_place::<{async fn body of simple()}>(copy (_9.0: &mut {async fn body of simple()})) -> [return: bb20, unwind: bb19]; + } + + bb22: { + _10 = &mut _1; -+ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb21, unwind: bb9]; ++ _9 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb21, unwind: bb9]; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff index 3cd434b00c498..640bb46dd6fcd 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff @@ -25,33 +25,31 @@ + let mut _0: std::task::Poll<()>; let _3: SyncInt; let mut _5: impl std::future::Future; - let mut _6: &mut AsyncInt; - let mut _7: std::pin::Pin<&mut AsyncInt>; - let mut _8: &mut AsyncInt; - let mut _9: impl std::future::Future; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: std::pin::Pin<&mut {async fn body of simple()}>; let mut _10: &mut {async fn body of simple()}; - let mut _11: std::pin::Pin<&mut {async fn body of simple()}>; - let mut _12: &mut {async fn body of simple()}; -+ let mut _13: std::task::Poll<()>; -+ let mut _14: &mut std::task::Context<'_>; -+ let mut _15: &mut impl std::future::Future; -+ let mut _16: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _17: isize; -+ let mut _18: &mut std::task::Context<'_>; -+ let mut _19: &mut impl std::future::Future; -+ let mut _20: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _21: isize; -+ let mut _22: (); -+ let mut _23: u32; -+ let mut _24: &mut {async fn body of simple()}; ++ let mut _11: std::task::Poll<()>; ++ let mut _12: &mut std::task::Context<'_>; ++ let mut _13: &mut impl std::future::Future; ++ let mut _14: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _15: isize; ++ let mut _16: &mut std::task::Context<'_>; ++ let mut _17: &mut impl std::future::Future; ++ let mut _18: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _19: isize; ++ let mut _20: (); ++ let mut _21: u32; ++ let mut _22: &mut {async fn body of simple()}; scope 1 { - debug sync_int => _3; -+ debug sync_int => (((*_24) as variant#4).0: SyncInt); ++ debug sync_int => (((*_22) as variant#4).0: SyncInt); + coroutine debug async_int => _s2; let _4: AsyncInt; scope 2 { - debug async_int => _4; -+ debug async_int => (((*_24) as variant#4).1: AsyncInt); ++ debug async_int => (((*_22) as variant#4).1: AsyncInt); } } @@ -62,16 +60,16 @@ - _4 = AsyncInt(const 0_i32); - _0 = const (); - goto -> bb15; -+ _24 = copy (_1.0: &mut {async fn body of simple()}); -+ _23 = discriminant((*_24)); -+ switchInt(move _23) -> [0: bb29, 1: bb28, 2: bb27, 3: bb25, 4: bb26, otherwise: bb19]; ++ _22 = copy (_1.0: &mut {async fn body of simple()}); ++ _21 = discriminant((*_22)); ++ switchInt(move _21) -> [0: bb29, 1: bb28, 2: bb27, 3: bb25, 4: bb26, otherwise: bb19]; } bb1: { - StorageDead(_4); - drop(_3) -> [return: bb2, unwind: bb8]; + nop; -+ drop((((*_24) as variant#4).0: SyncInt)) -> [return: bb2, unwind: bb5]; ++ drop((((*_22) as variant#4).0: SyncInt)) -> [return: bb2, unwind: bb5]; } bb2: { @@ -82,8 +80,8 @@ } bb3: { -+ _0 = Poll::<()>::Ready(move (((*_24) as variant#3).0: ())); -+ discriminant((*_24)) = 1; ++ _0 = Poll::<()>::Ready(move (((*_22) as variant#3).0: ())); ++ discriminant((*_22)) = 1; return; } @@ -92,7 +90,7 @@ - goto -> bb5; + bb4 (cleanup): { + nop; -+ drop((((*_24) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; ++ drop((((*_22) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; } - bb5: { @@ -126,97 +124,93 @@ - bb9 (cleanup): { - resume; + bb9: { -+ _14 = move _2; ++ _12 = move _2; + goto -> bb18; } bb10: { - StorageDead(_5); - goto -> bb1; -+ _8 = copy (_7.0: &mut AsyncInt); + nop; -+ (((*_24) as variant#4).2: impl std::future::Future) = async_drop_in_place::(move _8) -> [return: bb9, unwind: bb8]; ++ (((*_22) as variant#4).2: impl std::future::Future) = async_drop_in_place::(copy (_6.0: &mut AsyncInt)) -> [return: bb9, unwind: bb8]; } bb11: { - StorageDead(_5); - goto -> bb4; -+ _6 = &mut (((*_24) as variant#4).1: AsyncInt); -+ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb10, unwind: bb4]; ++ _7 = &mut (((*_22) as variant#4).1: AsyncInt); ++ _6 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb10, unwind: bb4]; } - bb12 (cleanup): { - StorageDead(_5); - goto -> bb7; + bb12: { -+ StorageDead(_9); ++ StorageDead(_8); + goto -> bb3; } - bb13: { - async drop(_4; poll=_5) -> [return: bb10, unwind: bb12, drop: bb11]; + bb13 (cleanup): { -+ StorageDead(_9); ++ StorageDead(_8); + goto -> bb6; } bb14: { -- _8 = copy (_7.0: &mut AsyncInt); - StorageLive(_5); -- _5 = async_drop_in_place::(move _8) -> [return: bb13, unwind: bb12]; +- _5 = async_drop_in_place::(copy (_6.0: &mut AsyncInt)) -> [return: bb13, unwind: bb12]; + goto -> bb23; } bb15: { -- _6 = &mut _4; -- _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb14, unwind: bb7]; -+ _12 = copy (_11.0: &mut {async fn body of simple()}); -+ StorageLive(_9); -+ _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb14, unwind: bb13]; +- _7 = &mut _4; +- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb14, unwind: bb7]; ++ StorageLive(_8); ++ _8 = async_drop_in_place::<{async fn body of simple()}>(copy (_9.0: &mut {async fn body of simple()})) -> [return: bb14, unwind: bb13]; } bb16: { -- StorageDead(_9); +- StorageDead(_8); - goto -> bb3; -+ _10 = &mut (*_24); -+ _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb15, unwind: bb6]; ++ _10 = &mut (*_22); ++ _9 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb15, unwind: bb6]; } bb17: { -- StorageDead(_9); +- StorageDead(_8); - goto -> bb6; + _0 = Poll::<()>::Pending; -+ discriminant((*_24)) = 3; ++ discriminant((*_22)) = 3; + return; } - bb18 (cleanup): { -- StorageDead(_9); +- StorageDead(_8); - goto -> bb9; + bb18: { -+ StorageLive(_16); -+ _15 = &mut (((*_24) as variant#4).2: impl std::future::Future); -+ _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb21, unwind: bb24]; ++ StorageLive(_14); ++ _13 = &mut (((*_22) as variant#4).2: impl std::future::Future); ++ _14 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb21, unwind: bb24]; } bb19: { -- async drop(_1; poll=_9) -> [return: bb16, unwind: bb18, drop: bb17]; +- async drop(_1; poll=_8) -> [return: bb16, unwind: bb18, drop: bb17]; + unreachable; } bb20: { -- _12 = copy (_11.0: &mut {async fn body of simple()}); -- StorageLive(_9); -- _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb19, unwind: bb18]; -+ StorageDead(_16); -+ _17 = discriminant(_13); -+ switchInt(move _17) -> [0: bb7, 1: bb17, otherwise: bb19]; +- StorageLive(_8); +- _8 = async_drop_in_place::<{async fn body of simple()}>(copy (_9.0: &mut {async fn body of simple()})) -> [return: bb19, unwind: bb18]; ++ StorageDead(_14); ++ _15 = discriminant(_11); ++ switchInt(move _15) -> [0: bb7, 1: bb17, otherwise: bb19]; } bb21: { - _10 = &mut _1; -- _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb20, unwind: bb9]; -+ _13 = as Future>::poll(move _16, move _14) -> [return: bb20, unwind: bb8]; +- _9 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb20, unwind: bb9]; ++ _11 = as Future>::poll(move _14, move _12) -> [return: bb20, unwind: bb8]; + } + + bb22: { @@ -228,17 +222,17 @@ + } + + bb24 (cleanup): { -+ discriminant((*_24)) = 2; ++ discriminant((*_22)) = 2; + resume; + } + + bb25: { -+ _14 = move _2; ++ _12 = move _2; + goto -> bb18; + } + + bb26: { -+ _18 = move _2; ++ _16 = move _2; + goto -> bb22; + } + @@ -252,10 +246,10 @@ + + bb29: { + nop; -+ (((*_24) as variant#4).0: SyncInt) = SyncInt(const 0_i32); ++ (((*_22) as variant#4).0: SyncInt) = SyncInt(const 0_i32); + nop; -+ (((*_24) as variant#4).1: AsyncInt) = AsyncInt(const 0_i32); -+ (((*_24) as variant#3).0: ()) = const (); ++ (((*_22) as variant#4).1: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_22) as variant#3).0: ()) = const (); + goto -> bb11; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir index 1296b494542fb..ae58869409262 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir @@ -7,22 +7,20 @@ yields () let mut _0: (); let _3: SyncInt; let mut _5: impl std::future::Future; - let mut _6: &mut AsyncInt; - let mut _7: std::pin::Pin<&mut AsyncInt>; - let mut _8: &mut AsyncInt; - let mut _9: impl std::future::Future; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: std::pin::Pin<&mut {async fn body of simple()}>; let mut _10: &mut {async fn body of simple()}; - let mut _11: std::pin::Pin<&mut {async fn body of simple()}>; - let mut _12: &mut {async fn body of simple()}; - let mut _13: std::task::Poll<()>; - let mut _14: &mut std::task::Context<'_>; - let mut _15: &mut impl std::future::Future; - let mut _16: std::pin::Pin<&mut impl std::future::Future>; - let mut _17: isize; - let mut _18: &mut std::task::Context<'_>; - let mut _19: &mut impl std::future::Future; - let mut _20: std::pin::Pin<&mut impl std::future::Future>; - let mut _21: isize; + let mut _11: std::task::Poll<()>; + let mut _12: &mut std::task::Context<'_>; + let mut _13: &mut impl std::future::Future; + let mut _14: std::pin::Pin<&mut impl std::future::Future>; + let mut _15: isize; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut impl std::future::Future; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: isize; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -98,33 +96,32 @@ yields () } bb13: { - _14 = move _2; + _12 = move _2; goto -> bb23; } bb14: { - _8 = copy (_7.0: &mut AsyncInt); StorageLive(_5); - _5 = async_drop_in_place::(move _8) -> [return: bb13, unwind: bb12]; + _5 = async_drop_in_place::(copy (_6.0: &mut AsyncInt)) -> [return: bb13, unwind: bb12]; } bb15: { - _6 = &mut _4; - _7 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb14, unwind: bb7]; + _7 = &mut _4; + _6 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb14, unwind: bb7]; } bb16: { - StorageDead(_9); + StorageDead(_8); goto -> bb3; } bb17: { - StorageDead(_9); + StorageDead(_8); goto -> bb6; } bb18 (cleanup): { - StorageDead(_9); + StorageDead(_8); goto -> bb9; } @@ -133,24 +130,23 @@ yields () } bb20: { - _12 = copy (_11.0: &mut {async fn body of simple()}); - StorageLive(_9); - _9 = async_drop_in_place::<{async fn body of simple()}>(move _12) -> [return: bb19, unwind: bb18]; + StorageLive(_8); + _8 = async_drop_in_place::<{async fn body of simple()}>(copy (_9.0: &mut {async fn body of simple()})) -> [return: bb19, unwind: bb18]; } bb21: { _10 = &mut _1; - _11 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb20, unwind: bb9]; + _9 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb20, unwind: bb9]; } bb22: { - _14 = yield(const false) -> [resume: bb23, drop: bb28]; + _12 = yield(const false) -> [resume: bb23, drop: bb28]; } bb23: { - StorageLive(_16); - _15 = &mut _5; - _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb26, unwind continue]; + StorageLive(_14); + _13 = &mut _5; + _14 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb26, unwind continue]; } bb24: { @@ -158,23 +154,23 @@ yields () } bb25: { - StorageDead(_16); - _17 = discriminant(_13); - switchInt(move _17) -> [0: bb10, 1: bb22, otherwise: bb24]; + StorageDead(_14); + _15 = discriminant(_11); + switchInt(move _15) -> [0: bb10, 1: bb22, otherwise: bb24]; } bb26: { - _13 = as Future>::poll(move _16, move _14) -> [return: bb25, unwind: bb12]; + _11 = as Future>::poll(move _14, move _12) -> [return: bb25, unwind: bb12]; } bb27: { - _18 = yield(const false) -> [resume: bb32, drop: bb28]; + _16 = yield(const false) -> [resume: bb32, drop: bb28]; } bb28: { - StorageLive(_20); - _19 = &mut _5; - _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb31, unwind continue]; + StorageLive(_18); + _17 = &mut _5; + _18 = Pin::<&mut impl Future>::new_unchecked(move _17) -> [return: bb31, unwind continue]; } bb29: { @@ -182,13 +178,13 @@ yields () } bb30: { - StorageDead(_20); - _21 = discriminant(_13); - switchInt(move _21) -> [0: bb11, 1: bb27, otherwise: bb29]; + StorageDead(_18); + _19 = discriminant(_11); + switchInt(move _19) -> [0: bb11, 1: bb27, otherwise: bb29]; } bb31: { - _13 = as Future>::poll(move _20, move _18) -> [return: bb30, unwind: bb12]; + _11 = as Future>::poll(move _18, move _16) -> [return: bb30, unwind: bb12]; } bb32: { diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir index 7bfe14da8f7fa..f67922017a1d6 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir @@ -5,37 +5,35 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte let mut _0: std::task::Poll<()>; let _3: SyncInt; let mut _5: impl std::future::Future; - let mut _6: &mut AsyncInt; - let mut _7: std::pin::Pin<&mut AsyncInt>; - let mut _8: &mut AsyncInt; - let mut _9: impl std::future::Future; + let mut _6: std::pin::Pin<&mut AsyncInt>; + let mut _7: &mut AsyncInt; + let mut _8: impl std::future::Future; + let mut _9: std::pin::Pin<&mut {async fn body of simple()}>; let mut _10: &mut {async fn body of simple()}; - let mut _11: std::pin::Pin<&mut {async fn body of simple()}>; - let mut _12: &mut {async fn body of simple()}; - let mut _13: std::task::Poll<()>; - let mut _14: &mut std::task::Context<'_>; - let mut _15: &mut impl std::future::Future; - let mut _16: std::pin::Pin<&mut impl std::future::Future>; - let mut _17: isize; - let mut _18: &mut std::task::Context<'_>; - let mut _19: &mut impl std::future::Future; - let mut _20: std::pin::Pin<&mut impl std::future::Future>; - let mut _21: isize; - let mut _22: (); - let mut _23: u32; - let mut _24: &mut {async fn body of simple()}; + let mut _11: std::task::Poll<()>; + let mut _12: &mut std::task::Context<'_>; + let mut _13: &mut impl std::future::Future; + let mut _14: std::pin::Pin<&mut impl std::future::Future>; + let mut _15: isize; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut impl std::future::Future; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: isize; + let mut _20: (); + let mut _21: u32; + let mut _22: &mut {async fn body of simple()}; scope 1 { - debug sync_int => (((*_24) as variant#4).0: SyncInt); + debug sync_int => (((*_22) as variant#4).0: SyncInt); let _4: AsyncInt; scope 2 { - debug async_int => (((*_24) as variant#4).1: AsyncInt); + debug async_int => (((*_22) as variant#4).1: AsyncInt); } } bb0: { - _24 = copy (_1.0: &mut {async fn body of simple()}); - _23 = discriminant((*_24)); - switchInt(move _23) -> [0: bb15, 2: bb20, 3: bb18, 4: bb19, otherwise: bb21]; + _22 = copy (_1.0: &mut {async fn body of simple()}); + _21 = discriminant((*_22)); + switchInt(move _21) -> [0: bb15, 2: bb20, 3: bb18, 4: bb19, otherwise: bb21]; } bb1: { @@ -55,7 +53,7 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte bb4 (cleanup): { nop; - drop((((*_24) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; + drop((((*_22) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; } bb5 (cleanup): { @@ -79,14 +77,14 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte bb9: { _0 = Poll::<()>::Pending; - discriminant((*_24)) = 4; + discriminant((*_22)) = 4; return; } bb10: { - StorageLive(_20); - _19 = &mut (((*_24) as variant#4).2: impl std::future::Future); - _20 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb13, unwind: bb17]; + StorageLive(_18); + _17 = &mut (((*_22) as variant#4).2: impl std::future::Future); + _18 = Pin::<&mut impl Future>::new_unchecked(move _17) -> [return: bb13, unwind: bb17]; } bb11: { @@ -94,13 +92,13 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte } bb12: { - StorageDead(_20); - _21 = discriminant(_13); - switchInt(move _21) -> [0: bb7, 1: bb9, otherwise: bb11]; + StorageDead(_18); + _19 = discriminant(_11); + switchInt(move _19) -> [0: bb7, 1: bb9, otherwise: bb11]; } bb13: { - _13 = as Future>::poll(move _20, move _18) -> [return: bb12, unwind: bb8]; + _11 = as Future>::poll(move _18, move _16) -> [return: bb12, unwind: bb8]; } bb14: { @@ -117,17 +115,17 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte } bb17 (cleanup): { - discriminant((*_24)) = 2; + discriminant((*_22)) = 2; resume; } bb18: { - _14 = move _2; + _12 = move _2; goto -> bb10; } bb19: { - _18 = move _2; + _16 = move _2; goto -> bb10; } diff --git a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir index 0e41de3eace5f..6e14fc04ec4ad 100644 --- a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir +++ b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir @@ -2,33 +2,32 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { debug _task_context => _2; - debug x => ((*_19).0: T); + debug x => ((*_18).0: T); let mut _0: std::task::Poll<()>; let _3: T; let mut _4: impl std::future::Future; - let mut _5: &mut T; - let mut _6: std::pin::Pin<&mut T>; - let mut _7: &mut T; - let mut _8: std::task::Poll<()>; - let mut _9: &mut std::task::Context<'_>; - let mut _10: &mut impl std::future::Future; - let mut _11: std::pin::Pin<&mut impl std::future::Future>; - let mut _12: isize; - let mut _13: &mut std::task::Context<'_>; - let mut _14: &mut impl std::future::Future; - let mut _15: std::pin::Pin<&mut impl std::future::Future>; - let mut _16: isize; - let mut _17: (); - let mut _18: u32; - let mut _19: &mut {async fn body of a()}; + let mut _5: std::pin::Pin<&mut T>; + let mut _6: &mut T; + let mut _7: std::task::Poll<()>; + let mut _8: &mut std::task::Context<'_>; + let mut _9: &mut impl std::future::Future; + let mut _10: std::pin::Pin<&mut impl std::future::Future>; + let mut _11: isize; + let mut _12: &mut std::task::Context<'_>; + let mut _13: &mut impl std::future::Future; + let mut _14: std::pin::Pin<&mut impl std::future::Future>; + let mut _15: isize; + let mut _16: (); + let mut _17: u32; + let mut _18: &mut {async fn body of a()}; scope 1 { - debug x => (((*_19) as variant#4).0: T); + debug x => (((*_18) as variant#4).0: T); } bb0: { - _19 = copy (_1.0: &mut {async fn body of a()}); - _18 = discriminant((*_19)); - switchInt(move _18) -> [0: bb10, 3: bb13, 4: bb14, otherwise: bb15]; + _18 = copy (_1.0: &mut {async fn body of a()}); + _17 = discriminant((*_18)); + switchInt(move _17) -> [0: bb10, 3: bb13, 4: bb14, otherwise: bb15]; } bb1: { @@ -48,14 +47,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) bb4: { _0 = Poll::<()>::Pending; - discriminant((*_19)) = 4; + discriminant((*_18)) = 4; return; } bb5: { - StorageLive(_15); - _14 = &mut (((*_19) as variant#4).1: impl std::future::Future); - _15 = Pin::<&mut impl Future>::new_unchecked(move _14) -> [return: bb8, unwind unreachable]; + StorageLive(_14); + _13 = &mut (((*_18) as variant#4).1: impl std::future::Future); + _14 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb8, unwind unreachable]; } bb6: { @@ -63,13 +62,13 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb7: { - StorageDead(_15); - _16 = discriminant(_8); - switchInt(move _16) -> [0: bb3, 1: bb4, otherwise: bb6]; + StorageDead(_14); + _15 = discriminant(_7); + switchInt(move _15) -> [0: bb3, 1: bb4, otherwise: bb6]; } bb8: { - _8 = as Future>::poll(move _15, move _13) -> [return: bb7, unwind unreachable]; + _7 = as Future>::poll(move _14, move _12) -> [return: bb7, unwind unreachable]; } bb9: { @@ -86,16 +85,16 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb12: { - drop(((*_19).0: T)) -> [return: bb11, unwind unreachable]; + drop(((*_18).0: T)) -> [return: bb11, unwind unreachable]; } bb13: { - _9 = move _2; + _8 = move _2; goto -> bb5; } bb14: { - _13 = move _2; + _12 = move _2; goto -> bb5; } diff --git a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir index cda8147afb495..b39a3dba1fcd0 100644 --- a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir +++ b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir @@ -2,33 +2,32 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { debug _task_context => _2; - debug x => ((*_19).0: T); + debug x => ((*_18).0: T); let mut _0: std::task::Poll<()>; let _3: T; let mut _4: impl std::future::Future; - let mut _5: &mut T; - let mut _6: std::pin::Pin<&mut T>; - let mut _7: &mut T; - let mut _8: std::task::Poll<()>; - let mut _9: &mut std::task::Context<'_>; - let mut _10: &mut impl std::future::Future; - let mut _11: std::pin::Pin<&mut impl std::future::Future>; - let mut _12: isize; - let mut _13: &mut std::task::Context<'_>; - let mut _14: &mut impl std::future::Future; - let mut _15: std::pin::Pin<&mut impl std::future::Future>; - let mut _16: isize; - let mut _17: (); - let mut _18: u32; - let mut _19: &mut {async fn body of a()}; + let mut _5: std::pin::Pin<&mut T>; + let mut _6: &mut T; + let mut _7: std::task::Poll<()>; + let mut _8: &mut std::task::Context<'_>; + let mut _9: &mut impl std::future::Future; + let mut _10: std::pin::Pin<&mut impl std::future::Future>; + let mut _11: isize; + let mut _12: &mut std::task::Context<'_>; + let mut _13: &mut impl std::future::Future; + let mut _14: std::pin::Pin<&mut impl std::future::Future>; + let mut _15: isize; + let mut _16: (); + let mut _17: u32; + let mut _18: &mut {async fn body of a()}; scope 1 { - debug x => (((*_19) as variant#4).0: T); + debug x => (((*_18) as variant#4).0: T); } bb0: { - _19 = copy (_1.0: &mut {async fn body of a()}); - _18 = discriminant((*_19)); - switchInt(move _18) -> [0: bb14, 2: bb20, 3: bb18, 4: bb19, otherwise: bb21]; + _18 = copy (_1.0: &mut {async fn body of a()}); + _17 = discriminant((*_18)); + switchInt(move _17) -> [0: bb14, 2: bb20, 3: bb18, 4: bb19, otherwise: bb21]; } bb1: { @@ -66,14 +65,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) bb8: { _0 = Poll::<()>::Pending; - discriminant((*_19)) = 4; + discriminant((*_18)) = 4; return; } bb9: { - StorageLive(_15); - _14 = &mut (((*_19) as variant#4).1: impl std::future::Future); - _15 = Pin::<&mut impl Future>::new_unchecked(move _14) -> [return: bb12, unwind: bb17]; + StorageLive(_14); + _13 = &mut (((*_18) as variant#4).1: impl std::future::Future); + _14 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb12, unwind: bb17]; } bb10: { @@ -81,13 +80,13 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb11: { - StorageDead(_15); - _16 = discriminant(_8); - switchInt(move _16) -> [0: bb5, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _15 = discriminant(_7); + switchInt(move _15) -> [0: bb5, 1: bb8, otherwise: bb10]; } bb12: { - _8 = as Future>::poll(move _15, move _13) -> [return: bb11, unwind: bb6]; + _7 = as Future>::poll(move _14, move _12) -> [return: bb11, unwind: bb6]; } bb13: { @@ -104,21 +103,21 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb16: { - drop(((*_19).0: T)) -> [return: bb15, unwind: bb4]; + drop(((*_18).0: T)) -> [return: bb15, unwind: bb4]; } bb17 (cleanup): { - discriminant((*_19)) = 2; + discriminant((*_18)) = 2; resume; } bb18: { - _9 = move _2; + _8 = move _2; goto -> bb9; } bb19: { - _13 = move _2; + _12 = move _2; goto -> bb9; } diff --git a/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir index 751721f7c4094..ecb77a4ab3a70 100644 --- a/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir @@ -14,15 +14,13 @@ yields () let mut _10: *mut Foo; let mut _11: bool; let mut _12: impl std::future::Future; - let mut _13: &mut Foo; - let mut _14: std::pin::Pin<&mut Foo>; - let mut _15: &mut Foo; - let mut _16: *mut Foo; - let mut _17: bool; - let mut _18: impl std::future::Future; + let mut _13: std::pin::Pin<&mut Foo>; + let mut _14: &mut Foo; + let mut _15: *mut Foo; + let mut _16: bool; + let mut _17: impl std::future::Future; + let mut _18: std::pin::Pin<&mut Foo>; let mut _19: &mut Foo; - let mut _20: std::pin::Pin<&mut Foo>; - let mut _21: &mut Foo; bb0: { _3 = move (_1.0: &mut [Foo; 1]); @@ -74,55 +72,53 @@ yields () } bb10: { - _15 = copy (_14.0: &mut Foo); StorageLive(_12); - _12 = async_drop_in_place::(move _15) -> [return: bb9, unwind: bb8]; + _12 = async_drop_in_place::(copy (_13.0: &mut Foo)) -> [return: bb9, unwind: bb8]; } bb11: { - _13 = &mut (*_10); - _14 = Pin::<&mut Foo>::new_unchecked(move _13) -> [return: bb10, unwind: bb4]; + _14 = &mut (*_10); + _13 = Pin::<&mut Foo>::new_unchecked(move _14) -> [return: bb10, unwind: bb4]; } bb12: { - _16 = &raw mut (*_5)[_7]; + _15 = &raw mut (*_5)[_7]; _7 = Add(move _7, const 1_usize); goto -> bb19; } bb13: { - _17 = Eq(copy _7, copy _6); - switchInt(move _17) -> [0: bb12, otherwise: bb1]; + _16 = Eq(copy _7, copy _6); + switchInt(move _16) -> [0: bb12, otherwise: bb1]; } bb14: { - StorageDead(_18); + StorageDead(_17); goto -> bb13; } bb15: { - StorageDead(_18); + StorageDead(_17); goto -> bb6; } bb16 (cleanup): { - StorageDead(_18); + StorageDead(_17); goto -> bb4; } bb17: { - async drop((*_16); poll=_18) -> [return: bb14, unwind: bb16, drop: bb15]; + async drop((*_15); poll=_17) -> [return: bb14, unwind: bb16, drop: bb15]; } bb18: { - _21 = copy (_20.0: &mut Foo); - StorageLive(_18); - _18 = async_drop_in_place::(move _21) -> [return: bb17, unwind: bb16]; + StorageLive(_17); + _17 = async_drop_in_place::(copy (_18.0: &mut Foo)) -> [return: bb17, unwind: bb16]; } bb19: { - _19 = &mut (*_16); - _20 = Pin::<&mut Foo>::new_unchecked(move _19) -> [return: bb18, unwind: bb4]; + _19 = &mut (*_15); + _18 = Pin::<&mut Foo>::new_unchecked(move _19) -> [return: bb18, unwind: bb4]; } bb20: { From 30782fc2a228a65773ec6c9665c8de63072ac0d9 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 08:22:26 +0000 Subject: [PATCH 10/12] Expand async drops during drop elaboration. This lets `StateTransform` focus on removing `Yield` terminators without adding new ones. --- compiler/rustc_hir/src/hir.rs | 7 + compiler/rustc_middle/src/mir/statement.rs | 12 +- compiler/rustc_middle/src/mir/syntax.rs | 25 +- compiler/rustc_mir_transform/src/coroutine.rs | 34 +- .../rustc_mir_transform/src/coroutine/drop.rs | 445 +--- .../rustc_mir_transform/src/elaborate_drop.rs | 374 ++- compiler/rustc_mir_transform/src/shim.rs | 3 +- compiler/rustc_mir_transform/src/validate.rs | 6 + ...sure#0}.AsyncEnum.MentionedItems.after.mir | 329 ++- ...-{closure#0}.AsyncEnum.StateTransform.diff | 596 +++-- ...osure#0}.AsyncInt.MentionedItems.after.mir | 106 +- ...e-{closure#0}.AsyncInt.StateTransform.diff | 219 +- ...syncReference_'__.MentionedItems.after.mir | 106 +- ...#0}.AsyncReference_'__.StateTransform.diff | 219 +- ...re#0}.AsyncStruct.MentionedItems.after.mir | 482 +++- ...closure#0}.AsyncStruct.StateTransform.diff | 834 ++++--- ...#0}.SyncThenAsync.MentionedItems.after.mir | 378 ++- ...osure#0}.SyncThenAsync.StateTransform.diff | 595 +++-- ...rop.double-{closure#0}.ElaborateDrops.diff | 224 +- ...rop.double-{closure#0}.StateTransform.diff | 479 ++-- ...osure#0}.coroutine_async_drop_expand.0.mir | 308 --- ...ble-{closure#0}.coroutine_drop_async.0.mir | 201 +- ...rate_drops-{closure#0}.ElaborateDrops.diff | 1062 +++++++-- ...rate_drops-{closure#0}.StateTransform.diff | 2017 +++++++++++------ tests/mir-opt/coroutine/async_drop.rs | 2 - ...rop.simple-{closure#0}.ElaborateDrops.diff | 106 +- ...rop.simple-{closure#0}.StateTransform.diff | 260 ++- ...osure#0}.coroutine_async_drop_expand.0.mir | 193 -- ...ple-{closure#0}.coroutine_drop_async.0.mir | 114 +- ...#0}.coroutine_drop_async.0.panic-abort.mir | 99 +- ...0}.coroutine_drop_async.0.panic-unwind.mir | 117 +- ...losure#0}.[Foo;1].MentionedItems.after.mir | 205 +- 32 files changed, 6693 insertions(+), 3464 deletions(-) delete mode 100644 tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir delete mode 100644 tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 59d1b4b5576ee..256176f4e6c6b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2327,6 +2327,13 @@ impl CoroutineKind { matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn)) } + pub fn is_async_desugaring(self) -> bool { + matches!( + self, + CoroutineKind::Desugared(CoroutineDesugaring::Async | CoroutineDesugaring::AsyncGen, _) + ) + } + pub fn to_plural_string(&self) -> String { match self { CoroutineKind::Desugared(d, CoroutineSource::Fn) => format!("{d:#}fn bodies"), diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 4c619f825fa8b..f25eaf3c6d32e 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -624,11 +624,7 @@ impl<'tcx> Operand<'tcx> { span: Span, ) -> Self { let ty = Ty::new_fn_def(tcx, def_id, args); - Operand::Constant(Box::new(ConstOperand { - span, - user_ty: None, - const_: Const::Val(ConstValue::ZeroSized, ty), - })) + Operand::zero_sized_constant(ty, span) } /// Convenience helper to make a constant that refers to the given `DefId` and args. Since this @@ -643,6 +639,12 @@ impl<'tcx> Operand<'tcx> { Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ })) } + /// Convenience helper to make a constant that refers to a zero-sized type. + pub fn zero_sized_constant(ty: Ty<'tcx>, span: Span) -> Self { + let const_ = Const::Val(ConstValue::ZeroSized, ty); + Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ })) + } + pub fn is_move(&self) -> bool { matches!(self, Operand::Move(..)) } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 07eaa085fabc9..1f5a8f1c2cdc6 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -760,21 +760,16 @@ pub enum TerminatorKind<'tcx> { /// meaning. /// /// Async drop processing: - /// In compiler/rustc_mir_build/src/build/scope.rs we detect possible async drop: - /// drop of object with `needs_async_drop`. - /// Async drop later, in StateTransform pass, may be expanded into additional yield-point - /// for poll-loop of async drop future. - /// So we need prepared 'drop' target block in the similar way as for `Yield` terminator - /// (see `drops.build_mir::` in scopes.rs). - /// In compiler/rustc_mir_transform/src/elaborate_drops.rs for object implementing `AsyncDrop` trait - /// we need to prepare async drop feature - resolve `AsyncDrop::drop` and codegen call. - /// `async_fut` is set to the corresponding local. - /// For coroutine drop we don't need this logic because coroutine drop works with the same - /// layout object as coroutine itself. So `async_fut` will be `None` for coroutine drop. - /// Both `drop` and `async_fut` fields are only used in compiler/rustc_mir_transform/src/coroutine.rs, - /// StateTransform pass. In `expand_async_drops` async drops are expanded - /// into one or two yield points with poll ready/pending switch. - /// When a coroutine has any internal async drop, the coroutine drop function will be async + /// MIR building detects possible async drops, and constructs a complete CFG. To correctly + /// handle the coroutine being dropped while itself drops, we need a 'drop' target + /// similar to `Yield` terminator (see `drops.build_mir::`). + /// + /// Drop elaboration later refines the set of useful async drops. If there is no need for an + /// async drop, it is downgraded to a sync drop by setting `drop` to `None` If this is an + /// actual async drop, it is expanded to an `await` loop over the `async_drop_in_place` or + /// `AsyncDrop::drop` coroutine. + /// + /// When a coroutine has any internal async drop, the coroutine drop function will be async /// (generated by `create_coroutine_drop_shim_async`, not `create_coroutine_drop_shim`). Drop { place: Place<'tcx>, diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 7eabd387c00ef..356e7a2d43f27 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -56,9 +56,9 @@ use std::ops; pub(super) use by_move_body::coroutine_by_move_body_def_id; use drop::{ - cleanup_async_drops, create_coroutine_drop_shim, create_coroutine_drop_shim_async, - create_coroutine_drop_shim_proxy_async, elaborate_coroutine_drops, expand_async_drops, - has_expandable_async_drops, insert_clean_drop, + create_coroutine_drop_shim, create_coroutine_drop_shim_async, + create_coroutine_drop_shim_proxy_async, elaborate_coroutine_drops, has_async_drops, + insert_clean_drop, }; use itertools::izip; use rustc_abi::{FieldIdx, VariantIdx}; @@ -70,7 +70,6 @@ use rustc_index::bit_set::{BitMatrix, DenseBitSet, GrowableBitSet}; use rustc_index::{Idx, IndexVec, indexvec}; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::util::Discr; use rustc_middle::ty::{ self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt, TypingMode, }; @@ -82,8 +81,8 @@ use rustc_mir_dataflow::impls::{ use rustc_mir_dataflow::{ Analysis, Results, ResultsCursor, ResultsVisitor, visit_reachable_results, }; +use rustc_span::Span; use rustc_span::def_id::{DefId, LocalDefId}; -use rustc_span::{DUMMY_SP, Span, dummy_spanned}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::TyCtxtInferExt as _; use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt}; @@ -169,7 +168,7 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx } const SELF_ARG: Local = Local::arg(0); -const CTX_ARG: Local = Local::arg(1); +pub(crate) const CTX_ARG: Local = Local::arg(1); /// A `yield` point in the coroutine. struct SuspensionPoint<'tcx> { @@ -585,7 +584,7 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body /// still using the `ResumeTy` indirection for the time being, and that indirection /// is removed here. After this transform, the coroutine body only knows about `&mut Context<'_>`. #[tracing::instrument(level = "trace", skip(tcx, body), ret)] -fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty<'tcx> { +fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let context_mut_ref = Ty::new_task_context(tcx); // replace the type of the `resume` argument @@ -615,7 +614,6 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty _ => {} } } - context_mut_ref } fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local { @@ -1510,24 +1508,12 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { // (finally in open_drop_for_tuple) before async drop expansion. // Async drops, produced by this drop elaboration, will be expanded, // and corresponding futures kept in layout. - let has_async_drops = matches!( - coroutine_kind, - CoroutineKind::Desugared(CoroutineDesugaring::Async | CoroutineDesugaring::AsyncGen, _) - ) && has_expandable_async_drops(tcx, body, coroutine_ty); + let coroutine_is_async = coroutine_kind.is_async_desugaring(); + let has_async_drops = has_async_drops(body); // Replace all occurrences of `ResumeTy` with `&mut Context<'_>` within async bodies. - if matches!( - coroutine_kind, - CoroutineKind::Desugared(CoroutineDesugaring::Async | CoroutineDesugaring::AsyncGen, _) - ) { - let context_mut_ref = transform_async_context(tcx, body); - expand_async_drops(tcx, body, context_mut_ref, coroutine_kind, coroutine_ty); - - if let Some(dumper) = MirDumper::new(tcx, "coroutine_async_drop_expand", body) { - dumper.dump_mir(body); - } - } else { - cleanup_async_drops(body); + if coroutine_is_async { + transform_async_context(tcx, body); } let always_live_locals = always_storage_live_locals(body); diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 3baf6b731f9f2..5a22d139a34a0 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -31,438 +31,37 @@ impl<'tcx> MutVisitor<'tcx> for FixReturnPendingVisitor<'tcx> { } } -// rv = call fut.poll() -fn build_poll_call<'tcx>( - tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, - poll_unit_place: &Place<'tcx>, - switch_block: BasicBlock, - fut_pin_place: &Place<'tcx>, - fut_ty: Ty<'tcx>, - context_ref_place: &Place<'tcx>, - unwind: UnwindAction, -) -> BasicBlock { - let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, DUMMY_SP); - let poll_fn = Ty::new_fn_def(tcx, poll_fn, [fut_ty]); - let poll_fn = Operand::Constant(Box::new(ConstOperand { - span: DUMMY_SP, - user_ty: None, - const_: Const::zero_sized(poll_fn), - })); - let call = TerminatorKind::Call { - func: poll_fn.clone(), - args: [ - dummy_spanned(Operand::Move(*fut_pin_place)), - dummy_spanned(Operand::Move(*context_ref_place)), - ] - .into(), - destination: *poll_unit_place, - target: Some(switch_block), - unwind, - call_source: CallSource::Misc, - fn_span: DUMMY_SP, - }; - insert_term_block(body, call) -} - -// pin_fut = Pin::new_unchecked(&mut fut) -fn build_pin_fut<'tcx>( - tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, - fut_place: Place<'tcx>, - unwind: UnwindAction, -) -> (BasicBlock, Place<'tcx>) { - let span = body.span; - let source_info = SourceInfo::outermost(span); - let fut_ty = fut_place.ty(&body.local_decls, tcx).ty; - let fut_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fut_ty); - let fut_ref_place = Place::from(body.local_decls.push(LocalDecl::new(fut_ref_ty, span))); - let pin_fut_new_unchecked_fn = - Ty::new_fn_def(tcx, tcx.require_lang_item(LangItem::PinNewUnchecked, span), [fut_ref_ty]); - let fut_pin_ty = pin_fut_new_unchecked_fn.fn_sig(tcx).output().skip_binder(); - let fut_pin_place = Place::from(body.local_decls.push(LocalDecl::new(fut_pin_ty, span))); - let pin_fut_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand { - span, - user_ty: None, - const_: Const::zero_sized(pin_fut_new_unchecked_fn), - })); - - let storage_live = Statement::new(source_info, StatementKind::StorageLive(fut_pin_place.local)); - - let fut_ref_assign = Statement::new( - source_info, - StatementKind::Assign(Box::new(( - fut_ref_place, - Rvalue::Ref( - tcx.lifetimes.re_erased, - BorrowKind::Mut { kind: MutBorrowKind::Default }, - fut_place, - ), - ))), - ); - - // call Pin::new_unchecked(&mut fut) - let pin_fut_bb = body.basic_blocks_mut().push(BasicBlockData::new_stmts( - [storage_live, fut_ref_assign].to_vec(), - Some(Terminator { - source_info, - kind: TerminatorKind::Call { - func: pin_fut_new_unchecked_fn, - args: [dummy_spanned(Operand::Move(fut_ref_place))].into(), - destination: fut_pin_place, - target: None, // will be fixed later - unwind, - call_source: CallSource::Misc, - fn_span: span, - }, - }), - false, - )); - (pin_fut_bb, fut_pin_place) -} - -// Build Poll switch for async drop -// match rv { -// Ready() => ready_block -// Pending => yield_block -//} -#[tracing::instrument(level = "trace", skip(tcx, body), ret)] -fn build_poll_switch<'tcx>( - tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, - poll_enum: Ty<'tcx>, - poll_unit_place: &Place<'tcx>, - fut_pin_place: &Place<'tcx>, - ready_block: BasicBlock, - yield_block: BasicBlock, -) -> BasicBlock { - let poll_enum_adt = poll_enum.ty_adt_def().unwrap(); - - let Discr { val: poll_ready_discr, ty: poll_discr_ty } = poll_enum - .discriminant_for_variant( - tcx, - poll_enum_adt - .variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, DUMMY_SP)), - ) - .unwrap(); - let poll_pending_discr = poll_enum - .discriminant_for_variant( - tcx, - poll_enum_adt - .variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, DUMMY_SP)), - ) - .unwrap() - .val; - let source_info = SourceInfo::outermost(body.span); - let poll_discr_place = - Place::from(body.local_decls.push(LocalDecl::new(poll_discr_ty, source_info.span))); - let discr_assign = Statement::new( - source_info, - StatementKind::Assign(Box::new((poll_discr_place, Rvalue::Discriminant(*poll_unit_place)))), - ); - let storage_dead = Statement::new(source_info, StatementKind::StorageDead(fut_pin_place.local)); - let unreachable_block = insert_term_block(body, TerminatorKind::Unreachable); - body.basic_blocks_mut().push(BasicBlockData::new_stmts( - [storage_dead, discr_assign].to_vec(), - Some(Terminator { - source_info, - kind: TerminatorKind::SwitchInt { - discr: Operand::Move(poll_discr_place), - targets: SwitchTargets::new( - [(poll_ready_discr, ready_block), (poll_pending_discr, yield_block)] - .into_iter(), - unreachable_block, - ), - }, - }), - false, - )) -} - -// Gather blocks, reachable through 'drop' targets of Yield and Drop terminators (chained) +/// Drop elaboration has transformed all async drops into `yield` loops. +/// The resulting coroutine needs `async drop` if it yields on a path +/// reachable through 'drop' targets of a Yield terminator. #[tracing::instrument(level = "trace", skip(body), ret)] -fn gather_dropline_blocks<'tcx>(body: &mut Body<'tcx>) -> DenseBitSet { +pub(super) fn has_async_drops<'tcx>(body: &mut Body<'tcx>) -> bool { + let mut has_async_drops = false; + let mut dropline: DenseBitSet = DenseBitSet::new_empty(body.basic_blocks.len()); for (bb, data) in traversal::reverse_postorder(body) { - if dropline.contains(bb) { - data.terminator().successors().for_each(|v| { - dropline.insert(v); - }); - } else { - match data.terminator().kind { - TerminatorKind::Yield { drop: Some(v), .. } => { - dropline.insert(v); - } - TerminatorKind::Drop { drop: Some(v), .. } => { - dropline.insert(v); - } - _ => (), - } + // Cleanup edges are not async drops. + if data.is_cleanup { + continue; } - } - dropline -} -/// Cleanup all async drops (reset to sync) -pub(super) fn cleanup_async_drops<'tcx>(body: &mut Body<'tcx>) { - for block in body.basic_blocks_mut() { - if let TerminatorKind::Drop { - place: _, - target: _, - unwind: _, - replace: _, - ref mut drop, - ref mut async_fut, - } = block.terminator_mut().kind - { - if drop.is_some() || async_fut.is_some() { - *drop = None; - *async_fut = None; + if let TerminatorKind::Yield { drop, .. } = data.terminator().kind { + if dropline.contains(bb) { + has_async_drops = true + } + if let Some(v) = drop { + dropline.insert(v); } } - } -} -pub(super) fn has_expandable_async_drops<'tcx>( - tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, - coroutine_ty: Ty<'tcx>, -) -> bool { - for bb in START_BLOCK..body.basic_blocks.next_index() { - // Drops in unwind path (cleanup blocks) are not expanded to async drops, only sync drops in unwind path - if body[bb].is_cleanup { - continue; - } - let TerminatorKind::Drop { place, target: _, unwind: _, replace: _, drop: _, async_fut } = - body[bb].terminator().kind - else { - continue; - }; - let place_ty = place.ty(&body.local_decls, tcx).ty; - if place_ty == coroutine_ty { - continue; - } - if async_fut.is_none() { - continue; + if dropline.contains(bb) { + data.terminator().successors().for_each(|v| { + dropline.insert(v); + }); } - return true; } - return false; -} - -/// Expand Drop terminator for async drops into mainline poll-switch and dropline poll-switch -#[tracing::instrument(level = "trace", skip(tcx, body), ret)] -pub(super) fn expand_async_drops<'tcx>( - tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, - context_mut_ref: Ty<'tcx>, - coroutine_kind: hir::CoroutineKind, - coroutine_ty: Ty<'tcx>, -) { - let dropline = gather_dropline_blocks(body); - // Clean drop and async_fut fields if potentially async drop is not expanded (stays sync) - let remove_asyncness = |block: &mut BasicBlockData<'tcx>| { - tracing::trace!("remove_asyncness"); - if let TerminatorKind::Drop { - place: _, - target: _, - unwind: _, - replace: _, - ref mut drop, - ref mut async_fut, - } = block.terminator_mut().kind - { - *drop = None; - *async_fut = None; - } - }; - for bb in START_BLOCK..body.basic_blocks.next_index() { - // Drops in unwind path (cleanup blocks) are not expanded to async drops, only sync drops in unwind path - if body[bb].is_cleanup { - remove_asyncness(&mut body[bb]); - continue; - } - let TerminatorKind::Drop { place, target, unwind, replace: _, drop, async_fut } = - body[bb].terminator().kind - else { - continue; - }; - - let place_ty = place.ty(&body.local_decls, tcx).ty; - if place_ty == coroutine_ty { - remove_asyncness(&mut body[bb]); - continue; - } - let Some(fut_local) = async_fut else { - remove_asyncness(&mut body[bb]); - continue; - }; - - let is_dropline_bb = dropline.contains(bb); - - if !is_dropline_bb && drop.is_none() { - remove_asyncness(&mut body[bb]); - continue; - } - - let fut_place = Place::from(fut_local); - let fut_ty = fut_place.ty(&body.local_decls, tcx).ty; - - // poll-code: - // state_call_drop: - // #bb_pin: fut_pin = Pin::new_unchecked(&mut fut) - // #bb_call: rv = call fut.poll() (or future_drop_poll(fut) for internal future drops) - // #bb_check: match (rv) - // pending => return rv (yield) - // ready => *continue_bb|drop_bb* - - let source_info = body[bb].terminator.as_ref().unwrap().source_info; - - // Compute Poll<> (aka Poll with void return) - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, source_info.span)); - let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); - let poll_decl = LocalDecl::new(poll_enum, source_info.span); - let poll_unit_place = Place::from(body.local_decls.push(poll_decl)); - - // First state-loop yield for mainline - let context_ref_place = - Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span))); - let arg = Rvalue::Use(Operand::Move(Place::from(CTX_ARG)), WithRetag::Yes); - body[bb].statements.push(Statement::new( - source_info, - StatementKind::Assign(Box::new((context_ref_place, arg))), - )); - let yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield - let (pin_bb, fut_pin_place) = - build_pin_fut(tcx, body, fut_place.clone(), UnwindAction::Continue); - let switch_block = build_poll_switch( - tcx, - body, - poll_enum, - &poll_unit_place, - &fut_pin_place, - target, - yield_block, - ); - let call_bb = build_poll_call( - tcx, - body, - &poll_unit_place, - switch_block, - &fut_pin_place, - fut_ty, - &context_ref_place, - unwind, - ); - - // Second state-loop yield for transition to dropline (when coroutine async drop started) - let mut dropline_transition_bb: Option = None; - let mut dropline_yield_bb: Option = None; - let mut dropline_context_ref: Option> = None; - let mut dropline_call_bb: Option = None; - if !is_dropline_bb { - let context_ref_place2: Place<'_> = Place::from( - body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)), - ); - let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield - let (pin_bb2, fut_pin_place2) = - build_pin_fut(tcx, body, fut_place, UnwindAction::Continue); - let drop_switch_block = build_poll_switch( - tcx, - body, - poll_enum, - &poll_unit_place, - &fut_pin_place2, - drop.unwrap(), - drop_yield_block, - ); - let drop_call_bb = build_poll_call( - tcx, - body, - &poll_unit_place, - drop_switch_block, - &fut_pin_place2, - fut_ty, - &context_ref_place2, - unwind, - ); - dropline_transition_bb = Some(pin_bb2); - dropline_yield_bb = Some(drop_yield_block); - dropline_context_ref = Some(context_ref_place2); - dropline_call_bb = Some(drop_call_bb); - } - - let value = - if matches!(coroutine_kind, CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) - { - // For AsyncGen we need `yield Poll::Pending` - let full_yield_ty = body.yield_ty().unwrap(); - let ty::Adt(_poll_adt, args) = *full_yield_ty.kind() else { bug!() }; - let ty::Adt(_option_adt, args) = *args.type_at(0).kind() else { bug!() }; - let yield_ty = args.type_at(0); - Operand::Constant(Box::new(ConstOperand { - span: source_info.span, - const_: Const::Unevaluated( - UnevaluatedConst::new( - tcx.require_lang_item(LangItem::AsyncGenPending, source_info.span), - tcx.mk_args(&[yield_ty.into()]), - ), - full_yield_ty, - ), - user_ty: None, - })) - } else { - // value needed only for return-yields or gen-coroutines, so just const here - Operand::Constant(Box::new(ConstOperand { - span: source_info.span, - user_ty: None, - const_: Const::from_bool(tcx, false), - })) - }; - - use rustc_middle::mir::AssertKind::ResumedAfterDrop; - let panic_bb = insert_panic_block(tcx, body, ResumedAfterDrop(coroutine_kind)); - - if is_dropline_bb { - body[yield_block].terminator_mut().kind = TerminatorKind::Yield { - value: value.clone(), - resume: panic_bb, - resume_arg: context_ref_place, - drop: Some(pin_bb), - }; - } else { - body[yield_block].terminator_mut().kind = TerminatorKind::Yield { - value: value.clone(), - resume: pin_bb, - resume_arg: context_ref_place, - drop: dropline_transition_bb, - }; - body[dropline_yield_bb.unwrap()].terminator_mut().kind = TerminatorKind::Yield { - value, - resume: panic_bb, - resume_arg: dropline_context_ref.unwrap(), - drop: dropline_transition_bb, - }; - } - - if let TerminatorKind::Call { ref mut target, .. } = body[pin_bb].terminator_mut().kind { - *target = Some(call_bb); - } else { - bug!() - } - if !is_dropline_bb { - if let TerminatorKind::Call { ref mut target, .. } = - body[dropline_transition_bb.unwrap()].terminator_mut().kind - { - *target = dropline_call_bb; - } else { - bug!() - } - } - - body[bb].terminator_mut().kind = TerminatorKind::Goto { target: pin_bb }; - } + has_async_drops } #[tracing::instrument(level = "trace", skip(tcx, body))] @@ -530,7 +129,6 @@ pub(super) fn insert_clean_drop<'tcx>( body: &mut Body<'tcx>, has_async_drops: bool, ) -> BasicBlock { - let source_info = SourceInfo::outermost(body.span); let return_block = if has_async_drops { insert_poll_ready_block(tcx, body) } else { @@ -552,8 +150,7 @@ pub(super) fn insert_clean_drop<'tcx>( }; // Create a block to destroy an unresumed coroutines. This can only destroy upvars. - body.basic_blocks_mut() - .push(BasicBlockData::new(Some(Terminator { source_info, kind: term }), false)) + insert_term_block(body, term) } #[tracing::instrument(level = "trace", skip(tcx, transform, body))] diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index df1ab00eacbfd..89e15049ed9db 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -2,15 +2,17 @@ use std::{fmt, iter, mem}; use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; use rustc_hir::lang_items::LangItem; +use rustc_hir::{CoroutineDesugaring, CoroutineKind}; use rustc_index::Idx; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::util::IntTypeExt; +use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, dummy_spanned}; use tracing::{debug, instrument}; +use crate::coroutine::CTX_ARG; use crate::patch::MirPatch; /// Describes how/if a value should be dropped. @@ -197,13 +199,30 @@ where self.elaborator.tcx() } - /// Generates three blocks: - /// * #1:pin_obj_bb: call Pin::new_unchecked(&mut obj) - /// * #2:call_drop_bb: fut = call obj.() OR call async_drop_in_place(obj) - /// * #3:drop_term_bb: drop (obj, fut, ...) - /// We keep async drop unexpanded to poll-loop here, to expand it later, at StateTransform - - /// into states expand. - /// call_destructor_only - to call only AsyncDrop::drop, not full async_drop_in_place glue + /// Async-drop `place: drop_ty`. + /// + /// Conceptually, we want to run `async_drop_in_place(&mut obj).await`. + /// + /// Await syntax does not exist in MIR, so we need to manually expand it into a poll-yield + /// loop, essentially: + /// ```mir + /// let fut = async_drop_in_place(&mut obj); + /// loop { + /// let pin_fut = Pin::new_unchecked(&mut fut); + /// match Future::poll(pin_fut, CTX_ARG) { + /// Poll::Ready => break, + /// Poll::Pending(..) => CTX_ARG = yield (), + /// } + /// } + /// // continue to `succ` + /// ``` + /// + /// We also need to ensure that async drop also happens on the coroutine drop path, ie. when + /// `yield` branches along its `drop` target. This requires a second loop, this time jumping to + /// `dropline`. + /// + /// Arguments: + /// `call_destructor_only`: call only `AsyncDrop::drop`, not full `async_drop_in_place` glue #[instrument(level = "debug", skip(self), ret)] fn build_async_drop( &mut self, @@ -257,20 +276,85 @@ where ) }); - // #3:drop_term_bb - let drop_term_bb = self.new_block( - unwind, - TerminatorKind::Drop { - place, - target: succ_with_dead, - unwind: unwind_with_dead.into_action(), - replace: false, - drop: dropline_with_dead, - async_fut: Some(fut), - }, + // The yielded value depends on the kind of coroutine, to match what AST lowering does. + let coroutine_kind = self.elaborator.body().coroutine_kind().unwrap(); + let yield_value = match coroutine_kind { + // For async gen, we need `yield Poll::Pending`. + CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => { + let full_yield_ty = self.elaborator.body().yield_ty().unwrap(); + let ty::Adt(_poll_adt, args) = *full_yield_ty.kind() else { bug!() }; + let ty::Adt(_option_adt, args) = *args.type_at(0).kind() else { bug!() }; + let yield_ty = args.type_at(0); + Operand::unevaluated_constant( + tcx, + tcx.require_lang_item(LangItem::AsyncGenPending, span), + tcx.mk_args(&[yield_ty.into()]), + span, + ) + } + // For regular async fn, we need `yield ()`. + CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => { + Operand::zero_sized_constant(tcx.types.unit, span) + } + // `is_async_drop` should have checked that. + _ => panic!("unexpected coroutine for async drop {coroutine_kind:?}"), + }; + + // The branching here is tricky and deserves some explanation. + // + // If we are in the drop code path, ie. we are currently dropping the coroutine. + // The state machine follows the `drop` branch in the `yield` terminator. + // To repeatedly poll the future, the `drop` branch must loop. + // Meanwhile, the `resume` branch corresponds to anomalous execution, + // trying to resume the coroutine while it is being dropped. So that branch panics + // (`panic_bb`). + let panic_bb = self.build_resumed_after_drop_abort_block(unwind_with_dead, coroutine_kind); + let (drop_pin_bb, drop_resume_bb, drop_drop_bb) = self.build_pin_poll_yield_loop( + CTX_ARG.into(), + fut.into(), + yield_value.clone(), + // If `dropline_with_dead` is set, it points to the continuation of the drop execution. + // Otherwise, we are already dropping the coroutine, and `succ_with_dead` does. + dropline_with_dead.unwrap_or(succ_with_dead), + unwind_with_dead, ); + self.elaborator + .patch() + .patch_terminator(drop_resume_bb, TerminatorKind::Goto { target: panic_bb }); + self.elaborator + .patch() + .patch_terminator(drop_drop_bb, TerminatorKind::Goto { target: drop_pin_bb }); + + // If we are in the regular code path, `dropline_with_dead` is `Some`. + // + // In that case, the logic is reversed. Normal execution branches on `resume` from the + // `yield` terminator. To repeatedly poll the future, that `resume` branch must loop. + // When the future is dropped, the `yield` terminator branches to `drop`, which follows to + // the previous loop `drop_pin_bb`. + let succ_yield_loop = if dropline_with_dead.is_some() { + let (pin_bb, resume_bb, drop_bb) = self.build_pin_poll_yield_loop( + CTX_ARG.into(), + fut.into(), + yield_value, + // `dropline_with_dead` is `Some`, so the previous loop point to it. + succ_with_dead, + unwind_with_dead, + ); + self.elaborator + .patch() + .patch_terminator(resume_bb, TerminatorKind::Goto { target: pin_bb }); + self.elaborator + .patch() + .patch_terminator(drop_bb, TerminatorKind::Goto { target: drop_pin_bb }); + pin_bb + } else { + // We were already in the drop line, so return the loop we created for it. + drop_pin_bb + }; - // #2:call_drop_bb >>> call AsyncDrop::drop(pin_obj) OR call async_drop_in_place(pin_obj.pointer) + // #2:call_drop_bb >>> + // call AsyncDrop::drop(pin_obj) + // OR call async_drop_in_place(pin_obj.pointer) let pin_adt_def = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); let pin_obj_ty = Ty::new_adt(tcx, pin_adt_def, tcx.mk_args(&[obj_ref_ty.into()])); // Where we store the result of Pin<&drop_ty>::new_unchecked(&mut place). @@ -283,13 +367,13 @@ where Operand::Copy(tcx.mk_place_field(pin_obj_local.into(), FieldIdx::ZERO, obj_ref_ty)) }; let call_drop_bb = self.new_block_with_statements( - unwind, + unwind_with_dead, vec![self.storage_live(fut)], TerminatorKind::Call { func: Operand::function_handle(tcx, async_drop_fn_def_id, [drop_ty.into()], span), args: [dummy_spanned(drop_arg)].into(), destination: fut.into(), - target: Some(drop_term_bb), + target: Some(succ_yield_loop), unwind: unwind_with_dead.into_action(), call_source: CallSource::Misc, fn_span: self.source_info.span, @@ -327,6 +411,232 @@ where ) } + fn build_resumed_after_drop_abort_block( + &mut self, + unwind: Unwind, + coroutine_kind: CoroutineKind, + ) -> BasicBlock { + let tcx = self.tcx(); + let panic_bb = self.new_block(unwind, TerminatorKind::Unreachable); + let msg = AssertMessage::ResumedAfterDrop(coroutine_kind); + let false_op = Operand::Constant(Box::new(ConstOperand { + span: self.source_info.span, + user_ty: None, + const_: Const::from_bool(tcx, false), + })); + self.elaborator.patch().patch_terminator( + panic_bb, + TerminatorKind::Assert { + cond: false_op, + expected: true, + msg: Box::new(msg), + target: panic_bb, + unwind: unwind.into_action(), + }, + ); + panic_bb + } + + /// Build a small MIR loop that pins and polls a future, yielding when + /// the future returns `Poll::Pending` and continuing to `ready_target` + /// when it returns `Poll::Ready`. + /// + /// Pseudo-code: + /// ```mir + /// pin_bb: + /// let pin_fut = Pin::new_unchecked(&mut fut_place); + /// match Future::poll(pin_fut, CTX_ARG) { + /// Poll::Ready => goto succ, + /// Poll::Pending(..) => CTX_ARG = yield () [resume: resume_bb, drop: drop_bb], + /// } + /// ``` + /// + /// Returns: the tuple `(pin_bb, resume_bb, drop_bb)`. + #[instrument(level = "trace", skip(self), ret)] + fn build_pin_poll_yield_loop( + &mut self, + resume_place: Place<'tcx>, + fut_place: Place<'tcx>, + yield_value: Operand<'tcx>, + succ: BasicBlock, + unwind: Unwind, + ) -> (BasicBlock, BasicBlock, BasicBlock) { + let tcx = self.tcx(); + let source_info = self.source_info; + + let resume_arg_ty = resume_place.ty(self.elaborator.body(), tcx).ty; + let context_ref_ty = Ty::new_task_context(tcx); + + let poll_adt_def = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, source_info.span)); + let poll_enum = Ty::new_adt(tcx, poll_adt_def, tcx.mk_args(&[tcx.types.unit.into()])); + + let fut_ty = self.elaborator.patch_ref().local_ty(fut_place.local); + let fut_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fut_ty); + + let pin_adt_def = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, source_info.span)); + let fut_pin_ty = Ty::new_adt(tcx, pin_adt_def, tcx.mk_args(&[fut_ref_ty.into()])); + + // Coroutine `transform_async_context` assumes that the local `resume_arg` to a yield + // is not used once, so create a special temp for it. + let yield_resume_local = self.new_temp(resume_arg_ty); + let resume_bb = self.new_block_with_statements( + unwind, + vec![ + self.assign( + resume_place, + Rvalue::Use(Operand::Move(yield_resume_local.into()), WithRetag::Yes), + ), + self.storage_dead(yield_resume_local), + ], + // This will be transformed by the caller. + TerminatorKind::Unreachable, + ); + let dropline_bb = self.new_block_with_statements( + unwind, + vec![ + self.assign( + resume_place, + Rvalue::Use(Operand::Move(yield_resume_local.into()), WithRetag::Yes), + ), + self.storage_dead(yield_resume_local), + ], + // This will be transformed by the caller. + TerminatorKind::Unreachable, + ); + let yield_bb = self.new_block_with_statements( + unwind, + vec![self.storage_live(yield_resume_local)], + TerminatorKind::Yield { + value: yield_value, + resume: resume_bb, + resume_arg: yield_resume_local.into(), + drop: Some(dropline_bb), + }, + ); + + let poll_unit_local = self.new_temp(poll_enum); + let switch_bb = { + let poll_ready_variant = + tcx.require_lang_item(LangItem::PollReady, self.source_info.span); + let poll_ready_variant_idx = poll_adt_def.variant_index_with_id(poll_ready_variant); + let poll_pending_variant = + tcx.require_lang_item(LangItem::PollPending, self.source_info.span); + let poll_pending_variant_idx = poll_adt_def.variant_index_with_id(poll_pending_variant); + + let Discr { val: poll_ready_discr, ty: poll_discr_ty } = + poll_enum.discriminant_for_variant(tcx, poll_ready_variant_idx).unwrap(); + let Discr { val: poll_pending_discr, ty: _ } = + poll_enum.discriminant_for_variant(tcx, poll_pending_variant_idx).unwrap(); + + let poll_discr_local = self.new_temp(poll_discr_ty); + let otherwise_bb = self.elaborator.patch().unreachable_no_cleanup_block(); + self.new_block_with_statements( + unwind, + vec![ + self.assign( + poll_discr_local.into(), + Rvalue::Discriminant(poll_unit_local.into()), + ), + ], + TerminatorKind::SwitchInt { + discr: Operand::Move(poll_discr_local.into()), + targets: SwitchTargets::new( + [ + // on `Ready`, exit the loop, jump to `succ` + (poll_ready_discr, succ), + // on `Pending`, yield and resume back into the loop + (poll_pending_discr, yield_bb), + ] + .into_iter(), + // otherwise: unreachable + otherwise_bb, + ), + }, + ) + }; + + let fut_pin_local = self.new_temp(fut_pin_ty); + let context_ref_local = self.new_temp(context_ref_ty); + + let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, source_info.span); + let poll_bb = self.new_block_with_statements( + unwind, + Vec::new(), + TerminatorKind::Call { + func: Operand::function_handle(tcx, poll_fn, [fut_ty.into()], source_info.span), + args: [ + dummy_spanned(Operand::Move(fut_pin_local.into())), + dummy_spanned(Operand::Move(context_ref_local.into())), + ] + .into(), + destination: poll_unit_local.into(), + target: Some(switch_bb), + unwind: unwind.into_action(), + call_source: CallSource::Misc, + fn_span: source_info.span, + }, + ); + + let get_context_fn = tcx.require_lang_item(LangItem::GetContext, source_info.span); + let get_context_bb = { + // Coroutine `transform_async_context` assumes that the local argument to `GetContext` + // is not used once, so create a special temp for it. + let entry_resume_local = self.new_temp(resume_arg_ty); + self.new_block_with_statements( + unwind, + vec![self.assign( + entry_resume_local.into(), + Rvalue::Use(Operand::Move(resume_place), WithRetag::Yes), + )], + TerminatorKind::Call { + func: Operand::function_handle( + tcx, + get_context_fn, + [tcx.lifetimes.re_erased.into(), tcx.lifetimes.re_erased.into()], + source_info.span, + ), + args: [dummy_spanned(Operand::Move(entry_resume_local.into()))].into(), + destination: context_ref_local.into(), + target: Some(poll_bb), + unwind: unwind.into_action(), + call_source: CallSource::Misc, + fn_span: source_info.span, + }, + ) + }; + + let fut_ref_local = self.new_temp(fut_ref_ty); + let fut_pin_new_unchecked_fn = + tcx.require_lang_item(LangItem::PinNewUnchecked, source_info.span); + let pin_bb = self.new_block_with_statements( + unwind, + vec![self.assign( + fut_ref_local.into(), + Rvalue::Ref( + tcx.lifetimes.re_erased, + BorrowKind::Mut { kind: MutBorrowKind::Default }, + fut_place, + ), + )], + TerminatorKind::Call { + func: Operand::function_handle( + tcx, + fut_pin_new_unchecked_fn, + [fut_ref_ty.into()], + source_info.span, + ), + args: [dummy_spanned(Operand::Move(fut_ref_local.into()))].into(), + destination: fut_pin_local.into(), + target: Some(get_context_bb), + unwind: unwind.into_action(), + call_source: CallSource::Misc, + fn_span: source_info.span, + }, + ); + + (pin_bb, resume_bb, dropline_bb) + } + fn build_drop(&mut self, bb: BasicBlock) { let drop_ty = self.place_ty(self.place); if !self.elaborator.patch_ref().block(self.elaborator.body(), bb).is_cleanup @@ -360,6 +670,21 @@ where /// Function to check if we can generate an async drop here fn check_if_can_async_drop(&mut self, drop_ty: Ty<'tcx>, call_destructor_only: bool) -> bool { + if !self.elaborator.allow_async_drops() + || !self + .elaborator + .body() + .coroutine + .as_ref() + .is_some_and(|ck| ck.coroutine_kind.is_async_desugaring()) + { + return false; + } + + if drop_ty == self.place_ty(Local::arg(0).into()) { + return false; + } + let is_async_drop_feature_enabled = if self.tcx().features().async_drop() { true } else { @@ -374,10 +699,7 @@ where // Short-circuit before calling needs_async_drop/is_async_drop, as those // require the `async_drop` lang item to exist (which may not be present // in minimal/custom core environments like cranelift's mini_core). - if !is_async_drop_feature_enabled - || !self.elaborator.body().coroutine.is_some() - || !self.elaborator.allow_async_drops() - { + if !is_async_drop_feature_enabled { return false; } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 49c899b3e8fe7..8efe536497ef5 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -156,7 +156,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< // Main pass required here is StateTransform to convert sync drop ladder // into coroutine. // Others are minimal passes as for sync drop glue shim - pm::run_passes( + pm::run_passes_no_validate( tcx, &mut body, &[ @@ -167,7 +167,6 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< &crate::coroutine::StateTransform, ], Some(MirPhase::Runtime(RuntimePhase::PostCleanup)), - pm::Optimizations::Allowed, ); run_optimization_passes(tcx, &mut body); debug!("make_shim({:?}) = {:?}", instance, body); diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 815b94dc510e8..3dca3f09db65d 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -367,6 +367,12 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { self.check_unwind_edge(location, *unwind); if let Some(drop) = drop { self.check_edge(location, *drop, EdgeKind::Normal); + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { + self.fail( + location, + "`async drop` should have been removed after drop elaboration", + ); + } } } TerminatorKind::Call { func, args, .. } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir index 4ed6ef4e10692..d0a63ff192e77 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir @@ -6,21 +6,56 @@ yields () let mut _0: (); let mut _3: &mut AsyncEnum; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncInt>; - let mut _6: &mut AsyncInt; - let mut _7: impl std::future::Future; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: isize; - let mut _11: isize; - let mut _12: isize; - let mut _13: impl std::future::Future; - let mut _14: std::pin::Pin<&mut AsyncEnum>; - let mut _15: &mut AsyncEnum; + let mut _5: std::future::ResumeTy; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; + let mut _10: std::future::ResumeTy; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; + let mut _15: std::future::ResumeTy; + let mut _16: std::task::Poll<()>; + let mut _17: isize; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: std::future::ResumeTy; + let mut _21: &mut impl std::future::Future; + let mut _22: std::future::ResumeTy; + let mut _23: std::task::Poll<()>; + let mut _24: isize; + let mut _25: std::pin::Pin<&mut impl std::future::Future>; + let mut _26: &mut std::task::Context<'_>; + let mut _27: std::future::ResumeTy; + let mut _28: &mut impl std::future::Future; + let mut _29: std::pin::Pin<&mut AsyncInt>; + let mut _30: &mut AsyncInt; + let mut _31: isize; + let mut _32: isize; + let mut _33: isize; + let mut _34: impl std::future::Future; + let mut _35: std::future::ResumeTy; + let mut _36: std::task::Poll<()>; + let mut _37: isize; + let mut _38: std::pin::Pin<&mut impl std::future::Future>; + let mut _39: &mut std::task::Context<'_>; + let mut _40: std::future::ResumeTy; + let mut _41: &mut impl std::future::Future; + let mut _42: std::future::ResumeTy; + let mut _43: std::task::Poll<()>; + let mut _44: isize; + let mut _45: std::pin::Pin<&mut impl std::future::Future>; + let mut _46: &mut std::task::Context<'_>; + let mut _47: std::future::ResumeTy; + let mut _48: &mut impl std::future::Future; + let mut _49: std::pin::Pin<&mut AsyncEnum>; + let mut _50: &mut AsyncEnum; bb0: { _3 = move (_1.0: &mut AsyncEnum); - goto -> bb29; + goto -> bb65; } bb1: { @@ -54,105 +89,289 @@ yields () } bb8: { - async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb6, unwind: bb7]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb8, unwind: bb7]; } bb9: { - StorageLive(_4); - _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7]; + _2 = move _5; + StorageDead(_5); + goto -> bb8; } bb10: { - _6 = &mut (((*_3) as A).0: AsyncInt); - _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb2]; + _2 = move _5; + StorageDead(_5); + goto -> bb16; } bb11: { - StorageDead(_7); - goto -> bb3; + StorageLive(_5); + _5 = yield(const ()) -> [resume: bb9, drop: bb10]; } bb12: { - StorageDead(_7); - goto -> bb1; + unreachable; } - bb13 (cleanup): { - StorageDead(_7); - goto -> bb2; + bb13: { + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb6, 1: bb11, otherwise: bb12]; } bb14: { - async drop((((*_3) as A).0: AsyncInt); poll=_7) -> [return: bb11, unwind: bb13, drop: bb12]; + _6 = as Future>::poll(move _8, move _9) -> [return: bb13, unwind: bb7]; } bb15: { - StorageLive(_7); - _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb14, unwind: bb13]; + _10 = move _2; + _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb14, unwind: bb7]; } bb16: { - _9 = &mut (((*_3) as A).0: AsyncInt); - _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb15, unwind: bb2]; + _11 = &mut _4; + _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb15, unwind: bb7]; } - bb17 (cleanup): { - drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + bb17: { + StorageLive(_4); + _4 = async_drop_in_place::(copy (_12.0: &mut AsyncInt)) -> [return: bb16, unwind: bb7]; } - bb18 (cleanup): { - drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + bb18: { + _13 = &mut (((*_3) as A).0: AsyncInt); + _12 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb17, unwind: bb2]; } bb19: { - drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; + StorageDead(_14); + goto -> bb3; } bb20: { - drop((((*_3) as B).0: SyncInt)) -> [return: bb3, unwind: bb2]; + StorageDead(_14); + goto -> bb1; } - bb21: { - _10 = discriminant((*_3)); - switchInt(move _10) -> [0: bb16, otherwise: bb20]; + bb21 (cleanup): { + StorageDead(_14); + goto -> bb2; } - bb22 (cleanup): { - _11 = discriminant((*_3)); - switchInt(move _11) -> [0: bb4, otherwise: bb17]; + bb22: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb21]; } bb23: { - _12 = discriminant((*_3)); - switchInt(move _12) -> [0: bb10, otherwise: bb19]; + _2 = move _15; + StorageDead(_15); + goto -> bb22; } bb24: { - StorageDead(_13); - goto -> bb21; + _2 = move _15; + StorageDead(_15); + goto -> bb29; } bb25: { - StorageDead(_13); - goto -> bb23; + StorageLive(_15); + _15 = yield(const ()) -> [resume: bb23, drop: bb24]; } - bb26 (cleanup): { - StorageDead(_13); - goto -> bb22; + bb26: { + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb20, 1: bb25, otherwise: bb12]; } bb27: { - async drop((*_3); poll=_13) -> [return: bb24, unwind: bb26, drop: bb25]; + _16 = as Future>::poll(move _18, move _19) -> [return: bb26, unwind: bb21]; } bb28: { - StorageLive(_13); - _13 = ::drop(move _14) -> [return: bb27, unwind: bb26]; + _20 = move _2; + _19 = std::future::get_context::<'_, '_>(move _20) -> [return: bb27, unwind: bb21]; } bb29: { - _15 = &mut (*_3); - _14 = Pin::<&mut AsyncEnum>::new_unchecked(move _15) -> [return: bb28, unwind: bb22]; + _21 = &mut _14; + _18 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb28, unwind: bb21]; + } + + bb30: { + _2 = move _22; + StorageDead(_22); + goto -> bb36; + } + + bb31: { + _2 = move _22; + StorageDead(_22); + goto -> bb29; + } + + bb32: { + StorageLive(_22); + _22 = yield(const ()) -> [resume: bb30, drop: bb31]; + } + + bb33: { + _24 = discriminant(_23); + switchInt(move _24) -> [0: bb19, 1: bb32, otherwise: bb12]; + } + + bb34: { + _23 = as Future>::poll(move _25, move _26) -> [return: bb33, unwind: bb21]; + } + + bb35: { + _27 = move _2; + _26 = std::future::get_context::<'_, '_>(move _27) -> [return: bb34, unwind: bb21]; + } + + bb36: { + _28 = &mut _14; + _25 = Pin::<&mut impl Future>::new_unchecked(move _28) -> [return: bb35, unwind: bb21]; + } + + bb37: { + StorageLive(_14); + _14 = async_drop_in_place::(copy (_29.0: &mut AsyncInt)) -> [return: bb36, unwind: bb21]; + } + + bb38: { + _30 = &mut (((*_3) as A).0: AsyncInt); + _29 = Pin::<&mut AsyncInt>::new_unchecked(move _30) -> [return: bb37, unwind: bb2]; + } + + bb39 (cleanup): { + drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb40 (cleanup): { + drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb41: { + drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; + } + + bb42: { + drop((((*_3) as B).0: SyncInt)) -> [return: bb3, unwind: bb2]; + } + + bb43: { + _31 = discriminant((*_3)); + switchInt(move _31) -> [0: bb38, otherwise: bb42]; + } + + bb44 (cleanup): { + _32 = discriminant((*_3)); + switchInt(move _32) -> [0: bb4, otherwise: bb39]; + } + + bb45: { + _33 = discriminant((*_3)); + switchInt(move _33) -> [0: bb18, otherwise: bb41]; + } + + bb46: { + StorageDead(_34); + goto -> bb43; + } + + bb47: { + StorageDead(_34); + goto -> bb45; + } + + bb48 (cleanup): { + StorageDead(_34); + goto -> bb44; + } + + bb49: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb49, unwind: bb48]; + } + + bb50: { + _2 = move _35; + StorageDead(_35); + goto -> bb49; + } + + bb51: { + _2 = move _35; + StorageDead(_35); + goto -> bb56; + } + + bb52: { + StorageLive(_35); + _35 = yield(const ()) -> [resume: bb50, drop: bb51]; + } + + bb53: { + _37 = discriminant(_36); + switchInt(move _37) -> [0: bb47, 1: bb52, otherwise: bb12]; + } + + bb54: { + _36 = as Future>::poll(move _38, move _39) -> [return: bb53, unwind: bb48]; + } + + bb55: { + _40 = move _2; + _39 = std::future::get_context::<'_, '_>(move _40) -> [return: bb54, unwind: bb48]; + } + + bb56: { + _41 = &mut _34; + _38 = Pin::<&mut impl Future>::new_unchecked(move _41) -> [return: bb55, unwind: bb48]; + } + + bb57: { + _2 = move _42; + StorageDead(_42); + goto -> bb63; + } + + bb58: { + _2 = move _42; + StorageDead(_42); + goto -> bb56; + } + + bb59: { + StorageLive(_42); + _42 = yield(const ()) -> [resume: bb57, drop: bb58]; + } + + bb60: { + _44 = discriminant(_43); + switchInt(move _44) -> [0: bb46, 1: bb59, otherwise: bb12]; + } + + bb61: { + _43 = as Future>::poll(move _45, move _46) -> [return: bb60, unwind: bb48]; + } + + bb62: { + _47 = move _2; + _46 = std::future::get_context::<'_, '_>(move _47) -> [return: bb61, unwind: bb48]; + } + + bb63: { + _48 = &mut _34; + _45 = Pin::<&mut impl Future>::new_unchecked(move _48) -> [return: bb62, unwind: bb48]; + } + + bb64: { + StorageLive(_34); + _34 = ::drop(move _49) -> [return: bb63, unwind: bb48]; + } + + bb65: { + _50 = &mut (*_3); + _49 = Pin::<&mut AsyncEnum>::new_unchecked(move _50) -> [return: bb64, unwind: bb44]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff index 3d85395372b4d..aedc5a0e9e9c4 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.diff @@ -26,284 +26,482 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut AsyncEnum; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncInt>; - let mut _6: &mut AsyncInt; - let mut _7: impl std::future::Future; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: isize; - let mut _11: isize; - let mut _12: isize; - let mut _13: impl std::future::Future; - let mut _14: std::pin::Pin<&mut AsyncEnum>; - let mut _15: &mut AsyncEnum; -+ let mut _16: std::task::Poll<()>; -+ let mut _17: &mut std::task::Context<'_>; -+ let mut _18: &mut impl std::future::Future; -+ let mut _19: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _20: isize; -+ let mut _21: std::task::Poll<()>; +- let mut _5: std::future::ResumeTy; ++ let mut _5: &mut std::task::Context<'_>; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; +- let mut _10: std::future::ResumeTy; ++ let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; +- let mut _15: std::future::ResumeTy; ++ let mut _15: &mut std::task::Context<'_>; + let mut _16: std::task::Poll<()>; + let mut _17: isize; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: &mut std::task::Context<'_>; +- let mut _20: std::future::ResumeTy; ++ let mut _20: &mut std::task::Context<'_>; + let mut _21: &mut impl std::future::Future; +- let mut _22: std::future::ResumeTy; + let mut _22: &mut std::task::Context<'_>; -+ let mut _23: &mut impl std::future::Future; -+ let mut _24: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _25: isize; -+ let mut _26: &mut std::task::Context<'_>; -+ let mut _27: &mut impl std::future::Future; -+ let mut _28: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _29: isize; -+ let mut _30: std::task::Poll<()>; -+ let mut _31: &mut std::task::Context<'_>; -+ let mut _32: &mut impl std::future::Future; -+ let mut _33: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _34: isize; + let mut _23: std::task::Poll<()>; + let mut _24: isize; + let mut _25: std::pin::Pin<&mut impl std::future::Future>; + let mut _26: &mut std::task::Context<'_>; +- let mut _27: std::future::ResumeTy; ++ let mut _27: &mut std::task::Context<'_>; + let mut _28: &mut impl std::future::Future; + let mut _29: std::pin::Pin<&mut AsyncInt>; + let mut _30: &mut AsyncInt; + let mut _31: isize; + let mut _32: isize; + let mut _33: isize; + let mut _34: impl std::future::Future; +- let mut _35: std::future::ResumeTy; + let mut _35: &mut std::task::Context<'_>; -+ let mut _36: &mut impl std::future::Future; -+ let mut _37: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _38: isize; -+ let mut _39: (); -+ let mut _40: u32; -+ let mut _41: &mut {async fn body of std::future::async_drop_in_place()}; -+ let mut _42: &mut AsyncEnum; -+ let mut _43: &mut AsyncEnum; -+ let mut _44: &mut AsyncEnum; -+ let mut _45: &mut AsyncEnum; -+ let mut _46: &mut AsyncEnum; -+ let mut _47: &mut AsyncEnum; -+ let mut _48: &mut AsyncEnum; + let mut _36: std::task::Poll<()>; + let mut _37: isize; + let mut _38: std::pin::Pin<&mut impl std::future::Future>; + let mut _39: &mut std::task::Context<'_>; +- let mut _40: std::future::ResumeTy; ++ let mut _40: &mut std::task::Context<'_>; + let mut _41: &mut impl std::future::Future; +- let mut _42: std::future::ResumeTy; ++ let mut _42: &mut std::task::Context<'_>; + let mut _43: std::task::Poll<()>; + let mut _44: isize; + let mut _45: std::pin::Pin<&mut impl std::future::Future>; + let mut _46: &mut std::task::Context<'_>; +- let mut _47: std::future::ResumeTy; ++ let mut _47: &mut std::task::Context<'_>; + let mut _48: &mut impl std::future::Future; + let mut _49: std::pin::Pin<&mut AsyncEnum>; + let mut _50: &mut AsyncEnum; ++ let mut _51: (); ++ let mut _52: u32; ++ let mut _53: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _54: &mut AsyncEnum; ++ let mut _55: &mut AsyncEnum; ++ let mut _56: &mut AsyncEnum; ++ let mut _57: &mut AsyncEnum; ++ let mut _58: &mut AsyncEnum; ++ let mut _59: &mut AsyncEnum; ++ let mut _60: &mut AsyncEnum; bb0: { - _3 = move (_1.0: &mut AsyncEnum); -- _15 = &mut (*_3); -- _14 = Pin::<&mut AsyncEnum>::new_unchecked(move _15) -> [return: bb23, unwind: bb18]; -+ _41 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); -+ _40 = discriminant((*_41)); -+ switchInt(move _40) -> [0: bb36, 1: bb35, 2: bb34, 3: bb29, 4: bb30, 5: bb31, 6: bb32, 7: bb33, otherwise: bb19]; +- _50 = &mut (*_3); +- _49 = Pin::<&mut AsyncEnum>::new_unchecked(move _50) -> [return: bb59, unwind: bb40]; ++ _53 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _52 = discriminant((*_53)); ++ switchInt(move _52) -> [0: bb42, 1: bb41, 2: bb40, 3: bb35, 4: bb36, 5: bb37, 6: bb38, 7: bb39, otherwise: bb7]; } bb1: { -+ _0 = Poll::<()>::Ready(move _39); -+ discriminant((*_41)) = 1; ++ _0 = Poll::<()>::Ready(move _51); ++ discriminant((*_53)) = 1; return; } bb2 (cleanup): { - resume; -+ goto -> bb28; ++ goto -> bb34; } bb3 (cleanup): { - drop((((*_3) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ _42 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); -+ drop((((*_42) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _54 = no_retag copy (((*_53) as variant#7).0: &mut AsyncEnum); ++ drop((((*_54) as A).0: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } - bb4: { +- bb4: { - StorageDead(_4); +- goto -> bb1; ++ bb4 (cleanup): { + nop; - goto -> bb1; ++ goto -> bb2; } - bb5 (cleanup): { +- bb5 (cleanup): { - StorageDead(_4); -+ nop; - goto -> bb2; +- goto -> bb2; ++ bb5: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb5, unwind: bb4]; } bb6: { -- async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb4, unwind: bb5]; -+ _22 = move _2; -+ goto -> bb18; +- assert(const false, "`async fn` resumed after async drop") -> [success: bb6, unwind: bb5]; ++ _2 = move _5; ++ StorageDead(_5); ++ goto -> bb5; } bb7: { -- StorageLive(_4); -- _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb6, unwind: bb5]; -+ nop; -+ (((*_41) as variant#5).0: impl std::future::Future) = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb6, unwind: bb5]; +- _2 = move _5; +- StorageDead(_5); +- goto -> bb6; ++ unreachable; } bb8: { -- _6 = &mut (((*_3) as A).0: AsyncInt); -- _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb7, unwind: bb2]; -+ _43 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); -+ _9 = &mut (((*_43) as A).0: AsyncInt); -+ _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb7, unwind: bb2]; +- _2 = move _5; +- StorageDead(_5); +- goto -> bb14; ++ nop; ++ goto -> bb1; } - bb9: { -- StorageDead(_7); -- goto -> bb1; +- StorageLive(_5); +- _5 = yield(const ()) -> [resume: bb7, drop: bb8]; + bb9 (cleanup): { -+ _44 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); -+ drop((((*_44) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ nop; ++ goto -> bb2; } bb10: { -- StorageDead(_7); -- goto -> bb1; -+ _45 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); -+ drop((((*_45) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; +- unreachable; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb10, unwind: bb9]; } - bb11 (cleanup): { -- StorageDead(_7); -- goto -> bb2; -+ _46 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); -+ _11 = discriminant((*_46)); -+ switchInt(move _11) -> [0: bb3, otherwise: bb9]; + bb11: { +- _7 = discriminant(_6); +- switchInt(move _7) -> [0: bb4, 1: bb9, otherwise: bb10]; ++ _2 = move _15; ++ StorageDead(_15); ++ goto -> bb10; } bb12: { -- async drop((((*_3) as A).0: AsyncInt); poll=_7) -> [return: bb9, unwind: bb11, drop: bb10]; -+ nop; -+ _47 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); -+ _10 = discriminant((*_47)); -+ switchInt(move _10) -> [0: bb8, otherwise: bb10]; +- _6 = as Future>::poll(move _8, move _9) -> [return: bb11, unwind: bb5]; ++ _2 = move _22; ++ StorageDead(_22); ++ goto -> bb17; } -- bb13: { -- StorageLive(_7); -- _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb12, unwind: bb11]; -+ bb13 (cleanup): { -+ nop; -+ goto -> bb11; + bb13: { +- _10 = move _2; +- _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb12, unwind: bb5]; ++ StorageLive(_22); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_22); ++ discriminant((*_53)) = 5; ++ return; } bb14: { -- _9 = &mut (((*_3) as A).0: AsyncInt); -- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb2]; -+ _31 = move _2; -+ goto -> bb24; +- _11 = &mut _4; +- _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb13, unwind: bb5]; ++ _24 = discriminant(_23); ++ switchInt(move _24) -> [0: bb8, 1: bb13, otherwise: bb7]; } -- bb15 (cleanup): { -- drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ bb15: { -+ nop; -+ (((*_41) as variant#7).1: impl std::future::Future) = ::drop(move _14) -> [return: bb14, unwind: bb13]; + bb15: { +- StorageLive(_4); +- _4 = async_drop_in_place::(copy (_12.0: &mut AsyncInt)) -> [return: bb14, unwind: bb5]; ++ _23 = as Future>::poll(move _25, move _26) -> [return: bb14, unwind: bb9]; } bb16: { -- drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb16, unwind: bb28]; +- _13 = &mut (((*_3) as A).0: AsyncInt); +- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb15, unwind: bb2]; ++ _27 = move _2; ++ _26 = move _27; ++ goto -> bb15; } bb17: { -- drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; -+ _0 = Poll::<()>::Pending; -+ discriminant((*_41)) = 4; -+ return; +- StorageDead(_14); +- goto -> bb1; ++ _28 = &mut (((*_53) as variant#5).0: impl std::future::Future); ++ _25 = Pin::<&mut impl Future>::new_unchecked(move _28) -> [return: bb16, unwind: bb9]; } -- bb18 (cleanup): { -- _11 = discriminant((*_3)); -- switchInt(move _11) -> [0: bb3, otherwise: bb15]; -+ bb18: { -+ StorageLive(_24); -+ _23 = &mut (((*_41) as variant#5).0: impl std::future::Future); -+ _24 = Pin::<&mut impl Future>::new_unchecked(move _23) -> [return: bb21, unwind: bb28]; + bb18: { +- StorageDead(_14); +- goto -> bb1; ++ nop; ++ (((*_53) as variant#5).0: impl std::future::Future) = async_drop_in_place::(copy (_29.0: &mut AsyncInt)) -> [return: bb17, unwind: bb9]; } - bb19: { -- StorageDead(_13); -- _10 = discriminant((*_3)); -- switchInt(move _10) -> [0: bb14, otherwise: bb17]; -+ unreachable; +- bb19 (cleanup): { +- StorageDead(_14); +- goto -> bb2; ++ bb19: { ++ _55 = no_retag copy (((*_53) as variant#7).0: &mut AsyncEnum); ++ _30 = &mut (((*_55) as A).0: AsyncInt); ++ _29 = Pin::<&mut AsyncInt>::new_unchecked(move _30) -> [return: bb18, unwind: bb2]; } - bb20: { -- StorageDead(_13); -- _12 = discriminant((*_3)); -- switchInt(move _12) -> [0: bb8, otherwise: bb16]; -+ StorageDead(_24); -+ _25 = discriminant(_21); -+ switchInt(move _25) -> [0: bb4, 1: bb17, otherwise: bb19]; +- bb20: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb20, unwind: bb19]; ++ bb20 (cleanup): { ++ _56 = no_retag copy (((*_53) as variant#7).0: &mut AsyncEnum); ++ drop((((*_56) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } -- bb21 (cleanup): { -- StorageDead(_13); -- goto -> bb18; -+ bb21: { -+ _21 = as Future>::poll(move _24, move _22) -> [return: bb20, unwind: bb5]; + bb21: { +- _2 = move _15; +- StorageDead(_15); +- goto -> bb20; ++ _57 = no_retag copy (((*_53) as variant#7).0: &mut AsyncEnum); ++ drop((((*_57) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; } - bb22: { -- async drop((*_3); poll=_13) -> [return: bb19, unwind: bb21, drop: bb20]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb28]; +- bb22: { +- _2 = move _15; +- StorageDead(_15); +- goto -> bb27; ++ bb22 (cleanup): { ++ _58 = no_retag copy (((*_53) as variant#7).0: &mut AsyncEnum); ++ _32 = discriminant((*_58)); ++ switchInt(move _32) -> [0: bb3, otherwise: bb20]; } bb23: { -- StorageLive(_13); -- _13 = ::drop(move _14) -> [return: bb22, unwind: bb21]; +- StorageLive(_15); +- _15 = yield(const ()) -> [resume: bb21, drop: bb22]; ++ nop; ++ _59 = no_retag copy (((*_53) as variant#7).0: &mut AsyncEnum); ++ _31 = discriminant((*_59)); ++ switchInt(move _31) -> [0: bb19, otherwise: bb21]; + } + +- bb24: { +- _17 = discriminant(_16); +- switchInt(move _17) -> [0: bb18, 1: bb23, otherwise: bb10]; ++ bb24 (cleanup): { ++ nop; ++ goto -> bb22; + } + + bb25: { +- _16 = as Future>::poll(move _18, move _19) -> [return: bb24, unwind: bb19]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb25, unwind: bb24]; + } + + bb26: { +- _20 = move _2; +- _19 = std::future::get_context::<'_, '_>(move _20) -> [return: bb25, unwind: bb19]; ++ _2 = move _35; ++ StorageDead(_35); ++ goto -> bb25; + } + + bb27: { +- _21 = &mut _14; +- _18 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb26, unwind: bb19]; ++ _2 = move _42; ++ StorageDead(_42); ++ goto -> bb32; + } + + bb28: { +- _2 = move _22; +- StorageDead(_22); +- goto -> bb34; ++ StorageLive(_42); + _0 = Poll::<()>::Pending; -+ discriminant((*_41)) = 6; ++ StorageDead(_42); ++ discriminant((*_53)) = 7; + return; -+ } -+ -+ bb24: { -+ StorageLive(_33); -+ _32 = &mut (((*_41) as variant#7).1: impl std::future::Future); -+ _33 = Pin::<&mut impl Future>::new_unchecked(move _32) -> [return: bb26, unwind: bb28]; -+ } -+ -+ bb25: { -+ StorageDead(_33); -+ _34 = discriminant(_30); -+ switchInt(move _34) -> [0: bb12, 1: bb23, otherwise: bb19]; -+ } -+ -+ bb26: { -+ _30 = as Future>::poll(move _33, move _31) -> [return: bb25, unwind: bb13]; -+ } -+ -+ bb27: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb27, unwind: bb28]; -+ } -+ -+ bb28 (cleanup): { -+ discriminant((*_41)) = 2; + } + + bb29: { +- _2 = move _22; +- StorageDead(_22); +- goto -> bb27; ++ _44 = discriminant(_43); ++ switchInt(move _44) -> [0: bb23, 1: bb28, otherwise: bb7]; + } + + bb30: { +- StorageLive(_22); +- _22 = yield(const ()) -> [resume: bb28, drop: bb29]; ++ _43 = as Future>::poll(move _45, move _46) -> [return: bb29, unwind: bb24]; + } + + bb31: { +- _24 = discriminant(_23); +- switchInt(move _24) -> [0: bb17, 1: bb30, otherwise: bb10]; ++ _47 = move _2; ++ _46 = move _47; ++ goto -> bb30; + } + + bb32: { +- _23 = as Future>::poll(move _25, move _26) -> [return: bb31, unwind: bb19]; ++ _48 = &mut (((*_53) as variant#7).1: impl std::future::Future); ++ _45 = Pin::<&mut impl Future>::new_unchecked(move _48) -> [return: bb31, unwind: bb24]; + } + + bb33: { +- _27 = move _2; +- _26 = std::future::get_context::<'_, '_>(move _27) -> [return: bb32, unwind: bb19]; ++ nop; ++ (((*_53) as variant#7).1: impl std::future::Future) = ::drop(move _49) -> [return: bb32, unwind: bb24]; + } + +- bb34: { +- _28 = &mut _14; +- _25 = Pin::<&mut impl Future>::new_unchecked(move _28) -> [return: bb33, unwind: bb19]; ++ bb34 (cleanup): { ++ discriminant((*_53)) = 2; + resume; -+ } -+ -+ bb29: { -+ _17 = move _2; -+ goto -> bb16; -+ } -+ -+ bb30: { + } + + bb35: { +- StorageLive(_14); +- _14 = async_drop_in_place::(copy (_29.0: &mut AsyncInt)) -> [return: bb34, unwind: bb19]; ++ StorageLive(_5); ++ _5 = move _2; ++ goto -> bb6; + } + + bb36: { +- _30 = &mut (((*_3) as A).0: AsyncInt); +- _29 = Pin::<&mut AsyncInt>::new_unchecked(move _30) -> [return: bb35, unwind: bb2]; ++ StorageLive(_15); ++ _15 = move _2; ++ goto -> bb11; + } + +- bb37 (cleanup): { +- drop((((*_3) as B).0: SyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ bb37: { ++ StorageLive(_22); + _22 = move _2; -+ goto -> bb18; -+ } -+ -+ bb31: { -+ _26 = move _2; -+ goto -> bb22; -+ } -+ -+ bb32: { -+ _31 = move _2; -+ goto -> bb24; -+ } -+ -+ bb33: { ++ goto -> bb12; + } + + bb38: { +- drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; ++ StorageLive(_35); + _35 = move _2; ++ goto -> bb26; + } + + bb39: { +- drop((((*_3) as B).0: SyncInt)) -> [return: bb1, unwind: bb2]; ++ StorageLive(_42); ++ _42 = move _2; + goto -> bb27; -+ } -+ -+ bb34: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb34, unwind continue]; -+ } -+ -+ bb35: { + } + +- bb40 (cleanup): { +- _32 = discriminant((*_3)); +- switchInt(move _32) -> [0: bb3, otherwise: bb37]; ++ bb40: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb40, unwind continue]; + } + + bb41: { +- StorageDead(_34); +- _31 = discriminant((*_3)); +- switchInt(move _31) -> [0: bb36, otherwise: bb39]; + _0 = Poll::<()>::Ready(const ()); + return; -+ } -+ -+ bb36: { -+ (((*_41) as variant#7).0: &mut AsyncEnum) = move ((*_41).0: &mut AsyncEnum); -+ _48 = no_retag copy (((*_41) as variant#7).0: &mut AsyncEnum); -+ _15 = &mut (*_48); -+ _14 = Pin::<&mut AsyncEnum>::new_unchecked(move _15) -> [return: bb15, unwind: bb11]; + } + + bb42: { +- StorageDead(_34); +- _33 = discriminant((*_3)); +- switchInt(move _33) -> [0: bb16, otherwise: bb38]; +- } +- +- bb43 (cleanup): { +- StorageDead(_34); +- goto -> bb40; +- } +- +- bb44: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb44, unwind: bb43]; +- } +- +- bb45: { +- _2 = move _35; +- StorageDead(_35); +- goto -> bb44; +- } +- +- bb46: { +- _2 = move _35; +- StorageDead(_35); +- goto -> bb51; +- } +- +- bb47: { +- StorageLive(_35); +- _35 = yield(const ()) -> [resume: bb45, drop: bb46]; +- } +- +- bb48: { +- _37 = discriminant(_36); +- switchInt(move _37) -> [0: bb42, 1: bb47, otherwise: bb10]; +- } +- +- bb49: { +- _36 = as Future>::poll(move _38, move _39) -> [return: bb48, unwind: bb43]; +- } +- +- bb50: { +- _40 = move _2; +- _39 = std::future::get_context::<'_, '_>(move _40) -> [return: bb49, unwind: bb43]; +- } +- +- bb51: { +- _41 = &mut _34; +- _38 = Pin::<&mut impl Future>::new_unchecked(move _41) -> [return: bb50, unwind: bb43]; +- } +- +- bb52: { +- _2 = move _42; +- StorageDead(_42); +- goto -> bb58; +- } +- +- bb53: { +- _2 = move _42; +- StorageDead(_42); +- goto -> bb51; +- } +- +- bb54: { +- StorageLive(_42); +- _42 = yield(const ()) -> [resume: bb52, drop: bb53]; +- } +- +- bb55: { +- _44 = discriminant(_43); +- switchInt(move _44) -> [0: bb41, 1: bb54, otherwise: bb10]; +- } +- +- bb56: { +- _43 = as Future>::poll(move _45, move _46) -> [return: bb55, unwind: bb43]; +- } +- +- bb57: { +- _47 = move _2; +- _46 = std::future::get_context::<'_, '_>(move _47) -> [return: bb56, unwind: bb43]; +- } +- +- bb58: { +- _48 = &mut _34; +- _45 = Pin::<&mut impl Future>::new_unchecked(move _48) -> [return: bb57, unwind: bb43]; +- } +- +- bb59: { +- StorageLive(_34); +- _34 = ::drop(move _49) -> [return: bb58, unwind: bb43]; ++ (((*_53) as variant#7).0: &mut AsyncEnum) = move ((*_53).0: &mut AsyncEnum); ++ _60 = no_retag copy (((*_53) as variant#7).0: &mut AsyncEnum); ++ _50 = &mut (*_60); ++ _49 = Pin::<&mut AsyncEnum>::new_unchecked(move _50) -> [return: bb33, unwind: bb22]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir index f426f51f303e5..da6f0f8015be8 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.MentionedItems.after.mir @@ -6,12 +6,26 @@ yields () let mut _0: (); let mut _3: &mut AsyncInt; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncInt>; - let mut _6: &mut AsyncInt; + let mut _5: std::future::ResumeTy; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; + let mut _10: std::future::ResumeTy; + let mut _11: &mut impl std::future::Future; + let mut _12: std::future::ResumeTy; + let mut _13: std::task::Poll<()>; + let mut _14: isize; + let mut _15: std::pin::Pin<&mut impl std::future::Future>; + let mut _16: &mut std::task::Context<'_>; + let mut _17: std::future::ResumeTy; + let mut _18: &mut impl std::future::Future; + let mut _19: std::pin::Pin<&mut AsyncInt>; + let mut _20: &mut AsyncInt; bb0: { _3 = move (_1.0: &mut AsyncInt); - goto -> bb9; + goto -> bb24; } bb1: { @@ -42,16 +56,92 @@ yields () } bb7: { - async drop((*_3); poll=_4) -> [return: bb4, unwind: bb6, drop: bb5]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb7, unwind: bb6]; } bb8: { - StorageLive(_4); - _4 = ::drop(move _5) -> [return: bb7, unwind: bb6]; + _2 = move _5; + StorageDead(_5); + goto -> bb7; } bb9: { - _6 = &mut (*_3); - _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb8, unwind: bb2]; + _2 = move _5; + StorageDead(_5); + goto -> bb15; + } + + bb10: { + StorageLive(_5); + _5 = yield(const ()) -> [resume: bb8, drop: bb9]; + } + + bb11: { + unreachable; + } + + bb12: { + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb5, 1: bb10, otherwise: bb11]; + } + + bb13: { + _6 = as Future>::poll(move _8, move _9) -> [return: bb12, unwind: bb6]; + } + + bb14: { + _10 = move _2; + _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb13, unwind: bb6]; + } + + bb15: { + _11 = &mut _4; + _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb14, unwind: bb6]; + } + + bb16: { + _2 = move _12; + StorageDead(_12); + goto -> bb22; + } + + bb17: { + _2 = move _12; + StorageDead(_12); + goto -> bb15; + } + + bb18: { + StorageLive(_12); + _12 = yield(const ()) -> [resume: bb16, drop: bb17]; + } + + bb19: { + _14 = discriminant(_13); + switchInt(move _14) -> [0: bb4, 1: bb18, otherwise: bb11]; + } + + bb20: { + _13 = as Future>::poll(move _15, move _16) -> [return: bb19, unwind: bb6]; + } + + bb21: { + _17 = move _2; + _16 = std::future::get_context::<'_, '_>(move _17) -> [return: bb20, unwind: bb6]; + } + + bb22: { + _18 = &mut _4; + _15 = Pin::<&mut impl Future>::new_unchecked(move _18) -> [return: bb21, unwind: bb6]; + } + + bb23: { + StorageLive(_4); + _4 = ::drop(move _19) -> [return: bb22, unwind: bb6]; + } + + bb24: { + _20 = &mut (*_3); + _19 = Pin::<&mut AsyncInt>::new_unchecked(move _20) -> [return: bb23, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff index 80cd8db89efc1..f3849286502ee 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncInt.StateTransform.diff @@ -20,39 +20,48 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut AsyncInt; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncInt>; - let mut _6: &mut AsyncInt; -+ let mut _7: std::task::Poll<()>; -+ let mut _8: &mut std::task::Context<'_>; -+ let mut _9: &mut impl std::future::Future; -+ let mut _10: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _11: isize; +- let mut _5: std::future::ResumeTy; ++ let mut _5: &mut std::task::Context<'_>; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; +- let mut _10: std::future::ResumeTy; ++ let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; +- let mut _12: std::future::ResumeTy; + let mut _12: &mut std::task::Context<'_>; -+ let mut _13: &mut impl std::future::Future; -+ let mut _14: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _15: isize; -+ let mut _16: (); -+ let mut _17: u32; -+ let mut _18: &mut {async fn body of std::future::async_drop_in_place()}; + let mut _13: std::task::Poll<()>; + let mut _14: isize; + let mut _15: std::pin::Pin<&mut impl std::future::Future>; + let mut _16: &mut std::task::Context<'_>; +- let mut _17: std::future::ResumeTy; ++ let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut impl std::future::Future; + let mut _19: std::pin::Pin<&mut AsyncInt>; + let mut _20: &mut AsyncInt; ++ let mut _21: (); ++ let mut _22: u32; ++ let mut _23: &mut {async fn body of std::future::async_drop_in_place()}; bb0: { - _3 = move (_1.0: &mut AsyncInt); -- _6 = &mut (*_3); -- _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb7, unwind: bb2]; -+ _18 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); -+ _17 = discriminant((*_18)); -+ switchInt(move _17) -> [0: bb18, 1: bb17, 2: bb16, 3: bb14, 4: bb15, otherwise: bb9]; +- _20 = &mut (*_3); +- _19 = Pin::<&mut AsyncInt>::new_unchecked(move _20) -> [return: bb22, unwind: bb2]; ++ _23 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _22 = discriminant((*_23)); ++ switchInt(move _22) -> [0: bb20, 1: bb19, 2: bb18, 3: bb16, 4: bb17, otherwise: bb7]; } bb1: { -+ _0 = Poll::<()>::Ready(move _16); -+ discriminant((*_18)) = 1; ++ _0 = Poll::<()>::Ready(move _21); ++ discriminant((*_23)) = 1; return; } bb2 (cleanup): { - resume; -+ goto -> bb13; ++ goto -> bb15; } bb3: { @@ -73,76 +82,128 @@ - StorageDead(_4); - goto -> bb2; + bb5: { -+ _8 = move _2; -+ goto -> bb8; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb5, unwind: bb4]; } bb6: { -- async drop((*_3); poll=_4) -> [return: bb3, unwind: bb5, drop: bb4]; -+ nop; -+ (((*_18) as variant#4).0: impl std::future::Future) = ::drop(move _5) -> [return: bb5, unwind: bb4]; +- assert(const false, "`async fn` resumed after async drop") -> [success: bb6, unwind: bb5]; ++ _2 = move _5; ++ StorageDead(_5); ++ goto -> bb5; } bb7: { -- StorageLive(_4); -- _4 = ::drop(move _5) -> [return: bb6, unwind: bb5]; +- _2 = move _5; +- StorageDead(_5); +- goto -> bb6; ++ unreachable; + } + + bb8: { +- _2 = move _5; +- StorageDead(_5); +- goto -> bb14; ++ _2 = move _12; ++ StorageDead(_12); ++ goto -> bb13; + } + + bb9: { +- StorageLive(_5); +- _5 = yield(const ()) -> [resume: bb7, drop: bb8]; ++ StorageLive(_12); + _0 = Poll::<()>::Pending; -+ discriminant((*_18)) = 3; ++ StorageDead(_12); ++ discriminant((*_23)) = 4; + return; -+ } -+ -+ bb8: { -+ StorageLive(_10); -+ _9 = &mut (((*_18) as variant#4).0: impl std::future::Future); -+ _10 = Pin::<&mut impl Future>::new_unchecked(move _9) -> [return: bb11, unwind: bb13]; -+ } -+ -+ bb9: { -+ unreachable; -+ } -+ -+ bb10: { -+ StorageDead(_10); -+ _11 = discriminant(_7); -+ switchInt(move _11) -> [0: bb3, 1: bb7, otherwise: bb9]; -+ } -+ -+ bb11: { -+ _7 = as Future>::poll(move _10, move _8) -> [return: bb10, unwind: bb4]; -+ } -+ -+ bb12: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb12, unwind: bb13]; -+ } -+ -+ bb13 (cleanup): { -+ discriminant((*_18)) = 2; + } + + bb10: { +- unreachable; ++ _14 = discriminant(_13); ++ switchInt(move _14) -> [0: bb3, 1: bb9, otherwise: bb7]; + } + + bb11: { +- _7 = discriminant(_6); +- switchInt(move _7) -> [0: bb4, 1: bb9, otherwise: bb10]; ++ _13 = as Future>::poll(move _15, move _16) -> [return: bb10, unwind: bb4]; + } + + bb12: { +- _6 = as Future>::poll(move _8, move _9) -> [return: bb11, unwind: bb5]; ++ _17 = move _2; ++ _16 = move _17; ++ goto -> bb11; + } + + bb13: { +- _10 = move _2; +- _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb12, unwind: bb5]; ++ _18 = &mut (((*_23) as variant#4).0: impl std::future::Future); ++ _15 = Pin::<&mut impl Future>::new_unchecked(move _18) -> [return: bb12, unwind: bb4]; + } + + bb14: { +- _11 = &mut _4; +- _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb13, unwind: bb5]; ++ nop; ++ (((*_23) as variant#4).0: impl std::future::Future) = ::drop(move _19) -> [return: bb13, unwind: bb4]; + } + +- bb15: { +- _2 = move _12; +- StorageDead(_12); +- goto -> bb21; ++ bb15 (cleanup): { ++ discriminant((*_23)) = 2; + resume; -+ } -+ -+ bb14: { -+ _8 = move _2; -+ goto -> bb8; -+ } -+ -+ bb15: { + } + + bb16: { +- _2 = move _12; +- StorageDead(_12); +- goto -> bb14; ++ StorageLive(_5); ++ _5 = move _2; ++ goto -> bb6; + } + + bb17: { + StorageLive(_12); +- _12 = yield(const ()) -> [resume: bb15, drop: bb16]; + _12 = move _2; -+ goto -> bb12; -+ } -+ -+ bb16: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb16, unwind continue]; -+ } -+ -+ bb17: { ++ goto -> bb8; + } + + bb18: { +- _14 = discriminant(_13); +- switchInt(move _14) -> [0: bb3, 1: bb17, otherwise: bb10]; ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb18, unwind continue]; + } + + bb19: { +- _13 = as Future>::poll(move _15, move _16) -> [return: bb18, unwind: bb5]; + _0 = Poll::<()>::Ready(const ()); + return; -+ } -+ -+ bb18: { -+ _3 = move ((*_18).0: &mut AsyncInt); -+ _6 = &mut (*_3); -+ _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb6, unwind: bb2]; + } + + bb20: { +- _17 = move _2; +- _16 = std::future::get_context::<'_, '_>(move _17) -> [return: bb19, unwind: bb5]; +- } +- +- bb21: { +- _18 = &mut _4; +- _15 = Pin::<&mut impl Future>::new_unchecked(move _18) -> [return: bb20, unwind: bb5]; +- } +- +- bb22: { +- StorageLive(_4); +- _4 = ::drop(move _19) -> [return: bb21, unwind: bb5]; ++ _3 = move ((*_23).0: &mut AsyncInt); ++ _20 = &mut (*_3); ++ _19 = Pin::<&mut AsyncInt>::new_unchecked(move _20) -> [return: bb14, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir index ccedee84d6fa5..bfb1aed61659a 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.MentionedItems.after.mir @@ -6,12 +6,26 @@ yields () let mut _0: (); let mut _3: &mut AsyncReference<'_>; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncReference<'_>>; - let mut _6: &mut AsyncReference<'_>; + let mut _5: std::future::ResumeTy; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; + let mut _10: std::future::ResumeTy; + let mut _11: &mut impl std::future::Future; + let mut _12: std::future::ResumeTy; + let mut _13: std::task::Poll<()>; + let mut _14: isize; + let mut _15: std::pin::Pin<&mut impl std::future::Future>; + let mut _16: &mut std::task::Context<'_>; + let mut _17: std::future::ResumeTy; + let mut _18: &mut impl std::future::Future; + let mut _19: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _20: &mut AsyncReference<'_>; bb0: { _3 = move (_1.0: &mut AsyncReference<'_>); - goto -> bb9; + goto -> bb24; } bb1: { @@ -42,16 +56,92 @@ yields () } bb7: { - async drop((*_3); poll=_4) -> [return: bb4, unwind: bb6, drop: bb5]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb7, unwind: bb6]; } bb8: { - StorageLive(_4); - _4 = as AsyncDrop>::drop(move _5) -> [return: bb7, unwind: bb6]; + _2 = move _5; + StorageDead(_5); + goto -> bb7; } bb9: { - _6 = &mut (*_3); - _5 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _6) -> [return: bb8, unwind: bb2]; + _2 = move _5; + StorageDead(_5); + goto -> bb15; + } + + bb10: { + StorageLive(_5); + _5 = yield(const ()) -> [resume: bb8, drop: bb9]; + } + + bb11: { + unreachable; + } + + bb12: { + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb5, 1: bb10, otherwise: bb11]; + } + + bb13: { + _6 = as Future>::poll(move _8, move _9) -> [return: bb12, unwind: bb6]; + } + + bb14: { + _10 = move _2; + _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb13, unwind: bb6]; + } + + bb15: { + _11 = &mut _4; + _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb14, unwind: bb6]; + } + + bb16: { + _2 = move _12; + StorageDead(_12); + goto -> bb22; + } + + bb17: { + _2 = move _12; + StorageDead(_12); + goto -> bb15; + } + + bb18: { + StorageLive(_12); + _12 = yield(const ()) -> [resume: bb16, drop: bb17]; + } + + bb19: { + _14 = discriminant(_13); + switchInt(move _14) -> [0: bb4, 1: bb18, otherwise: bb11]; + } + + bb20: { + _13 = as Future>::poll(move _15, move _16) -> [return: bb19, unwind: bb6]; + } + + bb21: { + _17 = move _2; + _16 = std::future::get_context::<'_, '_>(move _17) -> [return: bb20, unwind: bb6]; + } + + bb22: { + _18 = &mut _4; + _15 = Pin::<&mut impl Future>::new_unchecked(move _18) -> [return: bb21, unwind: bb6]; + } + + bb23: { + StorageLive(_4); + _4 = as AsyncDrop>::drop(move _19) -> [return: bb22, unwind: bb6]; + } + + bb24: { + _20 = &mut (*_3); + _19 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _20) -> [return: bb23, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff index 3f0291fe18c24..120028d1cabf0 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncReference_'__.StateTransform.diff @@ -20,39 +20,48 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut AsyncReference<'_>; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncReference<'_>>; - let mut _6: &mut AsyncReference<'_>; -+ let mut _7: std::task::Poll<()>; -+ let mut _8: &mut std::task::Context<'_>; -+ let mut _9: &mut impl std::future::Future; -+ let mut _10: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _11: isize; +- let mut _5: std::future::ResumeTy; ++ let mut _5: &mut std::task::Context<'_>; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; +- let mut _10: std::future::ResumeTy; ++ let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; +- let mut _12: std::future::ResumeTy; + let mut _12: &mut std::task::Context<'_>; -+ let mut _13: &mut impl std::future::Future; -+ let mut _14: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _15: isize; -+ let mut _16: (); -+ let mut _17: u32; -+ let mut _18: &mut {async fn body of std::future::async_drop_in_place>()}; + let mut _13: std::task::Poll<()>; + let mut _14: isize; + let mut _15: std::pin::Pin<&mut impl std::future::Future>; + let mut _16: &mut std::task::Context<'_>; +- let mut _17: std::future::ResumeTy; ++ let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut impl std::future::Future; + let mut _19: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _20: &mut AsyncReference<'_>; ++ let mut _21: (); ++ let mut _22: u32; ++ let mut _23: &mut {async fn body of std::future::async_drop_in_place>()}; bb0: { - _3 = move (_1.0: &mut AsyncReference<'_>); -- _6 = &mut (*_3); -- _5 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _6) -> [return: bb7, unwind: bb2]; -+ _18 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place>()}); -+ _17 = discriminant((*_18)); -+ switchInt(move _17) -> [0: bb18, 1: bb17, 2: bb16, 3: bb14, 4: bb15, otherwise: bb9]; +- _20 = &mut (*_3); +- _19 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _20) -> [return: bb22, unwind: bb2]; ++ _23 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place>()}); ++ _22 = discriminant((*_23)); ++ switchInt(move _22) -> [0: bb20, 1: bb19, 2: bb18, 3: bb16, 4: bb17, otherwise: bb7]; } bb1: { -+ _0 = Poll::<()>::Ready(move _16); -+ discriminant((*_18)) = 1; ++ _0 = Poll::<()>::Ready(move _21); ++ discriminant((*_23)) = 1; return; } bb2 (cleanup): { - resume; -+ goto -> bb13; ++ goto -> bb15; } bb3: { @@ -73,76 +82,128 @@ - StorageDead(_4); - goto -> bb2; + bb5: { -+ _8 = move _2; -+ goto -> bb8; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb5, unwind: bb4]; } bb6: { -- async drop((*_3); poll=_4) -> [return: bb3, unwind: bb5, drop: bb4]; -+ nop; -+ (((*_18) as variant#4).0: impl std::future::Future) = as AsyncDrop>::drop(move _5) -> [return: bb5, unwind: bb4]; +- assert(const false, "`async fn` resumed after async drop") -> [success: bb6, unwind: bb5]; ++ _2 = move _5; ++ StorageDead(_5); ++ goto -> bb5; } bb7: { -- StorageLive(_4); -- _4 = as AsyncDrop>::drop(move _5) -> [return: bb6, unwind: bb5]; +- _2 = move _5; +- StorageDead(_5); +- goto -> bb6; ++ unreachable; + } + + bb8: { +- _2 = move _5; +- StorageDead(_5); +- goto -> bb14; ++ _2 = move _12; ++ StorageDead(_12); ++ goto -> bb13; + } + + bb9: { +- StorageLive(_5); +- _5 = yield(const ()) -> [resume: bb7, drop: bb8]; ++ StorageLive(_12); + _0 = Poll::<()>::Pending; -+ discriminant((*_18)) = 3; ++ StorageDead(_12); ++ discriminant((*_23)) = 4; + return; -+ } -+ -+ bb8: { -+ StorageLive(_10); -+ _9 = &mut (((*_18) as variant#4).0: impl std::future::Future); -+ _10 = Pin::<&mut impl Future>::new_unchecked(move _9) -> [return: bb11, unwind: bb13]; -+ } -+ -+ bb9: { -+ unreachable; -+ } -+ -+ bb10: { -+ StorageDead(_10); -+ _11 = discriminant(_7); -+ switchInt(move _11) -> [0: bb3, 1: bb7, otherwise: bb9]; -+ } -+ -+ bb11: { -+ _7 = as Future>::poll(move _10, move _8) -> [return: bb10, unwind: bb4]; -+ } -+ -+ bb12: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb12, unwind: bb13]; -+ } -+ -+ bb13 (cleanup): { -+ discriminant((*_18)) = 2; + } + + bb10: { +- unreachable; ++ _14 = discriminant(_13); ++ switchInt(move _14) -> [0: bb3, 1: bb9, otherwise: bb7]; + } + + bb11: { +- _7 = discriminant(_6); +- switchInt(move _7) -> [0: bb4, 1: bb9, otherwise: bb10]; ++ _13 = as Future>::poll(move _15, move _16) -> [return: bb10, unwind: bb4]; + } + + bb12: { +- _6 = as Future>::poll(move _8, move _9) -> [return: bb11, unwind: bb5]; ++ _17 = move _2; ++ _16 = move _17; ++ goto -> bb11; + } + + bb13: { +- _10 = move _2; +- _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb12, unwind: bb5]; ++ _18 = &mut (((*_23) as variant#4).0: impl std::future::Future); ++ _15 = Pin::<&mut impl Future>::new_unchecked(move _18) -> [return: bb12, unwind: bb4]; + } + + bb14: { +- _11 = &mut _4; +- _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb13, unwind: bb5]; ++ nop; ++ (((*_23) as variant#4).0: impl std::future::Future) = as AsyncDrop>::drop(move _19) -> [return: bb13, unwind: bb4]; + } + +- bb15: { +- _2 = move _12; +- StorageDead(_12); +- goto -> bb21; ++ bb15 (cleanup): { ++ discriminant((*_23)) = 2; + resume; -+ } -+ -+ bb14: { -+ _8 = move _2; -+ goto -> bb8; -+ } -+ -+ bb15: { + } + + bb16: { +- _2 = move _12; +- StorageDead(_12); +- goto -> bb14; ++ StorageLive(_5); ++ _5 = move _2; ++ goto -> bb6; + } + + bb17: { + StorageLive(_12); +- _12 = yield(const ()) -> [resume: bb15, drop: bb16]; + _12 = move _2; -+ goto -> bb12; -+ } -+ -+ bb16: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb16, unwind continue]; -+ } -+ -+ bb17: { ++ goto -> bb8; + } + + bb18: { +- _14 = discriminant(_13); +- switchInt(move _14) -> [0: bb3, 1: bb17, otherwise: bb10]; ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb18, unwind continue]; + } + + bb19: { +- _13 = as Future>::poll(move _15, move _16) -> [return: bb18, unwind: bb5]; + _0 = Poll::<()>::Ready(const ()); + return; -+ } -+ -+ bb18: { -+ _3 = move ((*_18).0: &mut AsyncReference<'_>); -+ _6 = &mut (*_3); -+ _5 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _6) -> [return: bb6, unwind: bb2]; + } + + bb20: { +- _17 = move _2; +- _16 = std::future::get_context::<'_, '_>(move _17) -> [return: bb19, unwind: bb5]; +- } +- +- bb21: { +- _18 = &mut _4; +- _15 = Pin::<&mut impl Future>::new_unchecked(move _18) -> [return: bb20, unwind: bb5]; +- } +- +- bb22: { +- StorageLive(_4); +- _4 = as AsyncDrop>::drop(move _19) -> [return: bb21, unwind: bb5]; ++ _3 = move ((*_23).0: &mut AsyncReference<'_>); ++ _20 = &mut (*_3); ++ _19 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _20) -> [return: bb14, unwind: bb2]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir index 817fb07fec5fd..3a42ae5a1534e 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.MentionedItems.after.mir @@ -6,24 +6,80 @@ yields () let mut _0: (); let mut _3: &mut AsyncStruct; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncInt>; - let mut _6: &mut AsyncInt; - let mut _7: impl std::future::Future; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: impl std::future::Future; - let mut _11: std::pin::Pin<&mut AsyncInt>; - let mut _12: &mut AsyncInt; - let mut _13: impl std::future::Future; - let mut _14: std::pin::Pin<&mut AsyncInt>; - let mut _15: &mut AsyncInt; - let mut _16: impl std::future::Future; - let mut _17: std::pin::Pin<&mut AsyncStruct>; - let mut _18: &mut AsyncStruct; + let mut _5: std::future::ResumeTy; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; + let mut _10: std::future::ResumeTy; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; + let mut _15: std::future::ResumeTy; + let mut _16: std::task::Poll<()>; + let mut _17: isize; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: std::future::ResumeTy; + let mut _21: &mut impl std::future::Future; + let mut _22: std::pin::Pin<&mut AsyncInt>; + let mut _23: &mut AsyncInt; + let mut _24: impl std::future::Future; + let mut _25: std::future::ResumeTy; + let mut _26: std::task::Poll<()>; + let mut _27: isize; + let mut _28: std::pin::Pin<&mut impl std::future::Future>; + let mut _29: &mut std::task::Context<'_>; + let mut _30: std::future::ResumeTy; + let mut _31: &mut impl std::future::Future; + let mut _32: std::future::ResumeTy; + let mut _33: std::task::Poll<()>; + let mut _34: isize; + let mut _35: std::pin::Pin<&mut impl std::future::Future>; + let mut _36: &mut std::task::Context<'_>; + let mut _37: std::future::ResumeTy; + let mut _38: &mut impl std::future::Future; + let mut _39: std::pin::Pin<&mut AsyncInt>; + let mut _40: &mut AsyncInt; + let mut _41: impl std::future::Future; + let mut _42: std::future::ResumeTy; + let mut _43: std::task::Poll<()>; + let mut _44: isize; + let mut _45: std::pin::Pin<&mut impl std::future::Future>; + let mut _46: &mut std::task::Context<'_>; + let mut _47: std::future::ResumeTy; + let mut _48: &mut impl std::future::Future; + let mut _49: std::future::ResumeTy; + let mut _50: std::task::Poll<()>; + let mut _51: isize; + let mut _52: std::pin::Pin<&mut impl std::future::Future>; + let mut _53: &mut std::task::Context<'_>; + let mut _54: std::future::ResumeTy; + let mut _55: &mut impl std::future::Future; + let mut _56: std::pin::Pin<&mut AsyncInt>; + let mut _57: &mut AsyncInt; + let mut _58: impl std::future::Future; + let mut _59: std::future::ResumeTy; + let mut _60: std::task::Poll<()>; + let mut _61: isize; + let mut _62: std::pin::Pin<&mut impl std::future::Future>; + let mut _63: &mut std::task::Context<'_>; + let mut _64: std::future::ResumeTy; + let mut _65: &mut impl std::future::Future; + let mut _66: std::future::ResumeTy; + let mut _67: std::task::Poll<()>; + let mut _68: isize; + let mut _69: std::pin::Pin<&mut impl std::future::Future>; + let mut _70: &mut std::task::Context<'_>; + let mut _71: std::future::ResumeTy; + let mut _72: &mut impl std::future::Future; + let mut _73: std::pin::Pin<&mut AsyncStruct>; + let mut _74: &mut AsyncStruct; bb0: { _3 = move (_1.0: &mut AsyncStruct); - goto -> bb33; + goto -> bb90; } bb1: { @@ -57,127 +113,419 @@ yields () } bb8: { - async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb6, unwind: bb7]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb8, unwind: bb7]; } bb9: { - StorageLive(_4); - _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7]; + _2 = move _5; + StorageDead(_5); + goto -> bb8; } bb10: { - _6 = &mut ((*_3).2: AsyncInt); - _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb2]; + _2 = move _5; + StorageDead(_5); + goto -> bb16; } bb11: { - StorageDead(_7); - goto -> bb10; + StorageLive(_5); + _5 = yield(const ()) -> [resume: bb9, drop: bb10]; } - bb12 (cleanup): { - StorageDead(_7); - goto -> bb4; + bb12: { + unreachable; } bb13: { - async drop(((*_3).1: AsyncInt); poll=_7) -> [return: bb11, unwind: bb12]; + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb6, 1: bb11, otherwise: bb12]; } bb14: { - StorageLive(_7); - _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb13, unwind: bb12]; + _6 = as Future>::poll(move _8, move _9) -> [return: bb13, unwind: bb7]; } bb15: { - _9 = &mut ((*_3).1: AsyncInt); - _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb14, unwind: bb4]; + _10 = move _2; + _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb14, unwind: bb7]; } bb16: { - StorageDead(_10); - goto -> bb3; + _11 = &mut _4; + _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb15, unwind: bb7]; } bb17: { - StorageDead(_10); - goto -> bb1; + StorageLive(_4); + _4 = async_drop_in_place::(copy (_12.0: &mut AsyncInt)) -> [return: bb16, unwind: bb7]; } - bb18 (cleanup): { - StorageDead(_10); - goto -> bb2; + bb18: { + _13 = &mut ((*_3).2: AsyncInt); + _12 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb17, unwind: bb2]; } bb19: { - async drop(((*_3).2: AsyncInt); poll=_10) -> [return: bb16, unwind: bb18, drop: bb17]; + StorageDead(_14); + goto -> bb18; } - bb20: { - StorageLive(_10); - _10 = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb19, unwind: bb18]; + bb20 (cleanup): { + StorageDead(_14); + goto -> bb4; } bb21: { - _12 = &mut ((*_3).2: AsyncInt); - _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb20, unwind: bb2]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb21, unwind: bb20]; } bb22: { - StorageDead(_13); + _2 = move _15; + StorageDead(_15); goto -> bb21; } bb23: { - StorageDead(_13); - goto -> bb10; + _2 = move _15; + StorageDead(_15); + goto -> bb28; } - bb24 (cleanup): { - StorageDead(_13); - goto -> bb4; + bb24: { + StorageLive(_15); + _15 = yield(const ()) -> [resume: bb22, drop: bb23]; } bb25: { - async drop(((*_3).1: AsyncInt); poll=_13) -> [return: bb22, unwind: bb24, drop: bb23]; + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb19, 1: bb24, otherwise: bb12]; } bb26: { - StorageLive(_13); - _13 = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb25, unwind: bb24]; + _16 = as Future>::poll(move _18, move _19) -> [return: bb25, unwind: bb20]; } bb27: { - _15 = &mut ((*_3).1: AsyncInt); - _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb26, unwind: bb4]; + _20 = move _2; + _19 = std::future::get_context::<'_, '_>(move _20) -> [return: bb26, unwind: bb20]; } bb28: { - StorageDead(_16); - goto -> bb27; + _21 = &mut _14; + _18 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb27, unwind: bb20]; } bb29: { - StorageDead(_16); - goto -> bb15; + StorageLive(_14); + _14 = async_drop_in_place::(copy (_22.0: &mut AsyncInt)) -> [return: bb28, unwind: bb20]; } - bb30 (cleanup): { - StorageDead(_16); - goto -> bb5; + bb30: { + _23 = &mut ((*_3).1: AsyncInt); + _22 = Pin::<&mut AsyncInt>::new_unchecked(move _23) -> [return: bb29, unwind: bb4]; } bb31: { - async drop((*_3); poll=_16) -> [return: bb28, unwind: bb30, drop: bb29]; + StorageDead(_24); + goto -> bb3; } bb32: { - StorageLive(_16); - _16 = ::drop(move _17) -> [return: bb31, unwind: bb30]; + StorageDead(_24); + goto -> bb1; + } + + bb33 (cleanup): { + StorageDead(_24); + goto -> bb2; + } + + bb34: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb34, unwind: bb33]; + } + + bb35: { + _2 = move _25; + StorageDead(_25); + goto -> bb34; + } + + bb36: { + _2 = move _25; + StorageDead(_25); + goto -> bb41; + } + + bb37: { + StorageLive(_25); + _25 = yield(const ()) -> [resume: bb35, drop: bb36]; + } + + bb38: { + _27 = discriminant(_26); + switchInt(move _27) -> [0: bb32, 1: bb37, otherwise: bb12]; + } + + bb39: { + _26 = as Future>::poll(move _28, move _29) -> [return: bb38, unwind: bb33]; + } + + bb40: { + _30 = move _2; + _29 = std::future::get_context::<'_, '_>(move _30) -> [return: bb39, unwind: bb33]; + } + + bb41: { + _31 = &mut _24; + _28 = Pin::<&mut impl Future>::new_unchecked(move _31) -> [return: bb40, unwind: bb33]; + } + + bb42: { + _2 = move _32; + StorageDead(_32); + goto -> bb48; + } + + bb43: { + _2 = move _32; + StorageDead(_32); + goto -> bb41; + } + + bb44: { + StorageLive(_32); + _32 = yield(const ()) -> [resume: bb42, drop: bb43]; + } + + bb45: { + _34 = discriminant(_33); + switchInt(move _34) -> [0: bb31, 1: bb44, otherwise: bb12]; + } + + bb46: { + _33 = as Future>::poll(move _35, move _36) -> [return: bb45, unwind: bb33]; + } + + bb47: { + _37 = move _2; + _36 = std::future::get_context::<'_, '_>(move _37) -> [return: bb46, unwind: bb33]; + } + + bb48: { + _38 = &mut _24; + _35 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb47, unwind: bb33]; + } + + bb49: { + StorageLive(_24); + _24 = async_drop_in_place::(copy (_39.0: &mut AsyncInt)) -> [return: bb48, unwind: bb33]; + } + + bb50: { + _40 = &mut ((*_3).2: AsyncInt); + _39 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb49, unwind: bb2]; + } + + bb51: { + StorageDead(_41); + goto -> bb50; + } + + bb52: { + StorageDead(_41); + goto -> bb18; + } + + bb53 (cleanup): { + StorageDead(_41); + goto -> bb4; + } + + bb54: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb54, unwind: bb53]; + } + + bb55: { + _2 = move _42; + StorageDead(_42); + goto -> bb54; + } + + bb56: { + _2 = move _42; + StorageDead(_42); + goto -> bb61; + } + + bb57: { + StorageLive(_42); + _42 = yield(const ()) -> [resume: bb55, drop: bb56]; + } + + bb58: { + _44 = discriminant(_43); + switchInt(move _44) -> [0: bb52, 1: bb57, otherwise: bb12]; + } + + bb59: { + _43 = as Future>::poll(move _45, move _46) -> [return: bb58, unwind: bb53]; + } + + bb60: { + _47 = move _2; + _46 = std::future::get_context::<'_, '_>(move _47) -> [return: bb59, unwind: bb53]; + } + + bb61: { + _48 = &mut _41; + _45 = Pin::<&mut impl Future>::new_unchecked(move _48) -> [return: bb60, unwind: bb53]; + } + + bb62: { + _2 = move _49; + StorageDead(_49); + goto -> bb68; + } + + bb63: { + _2 = move _49; + StorageDead(_49); + goto -> bb61; + } + + bb64: { + StorageLive(_49); + _49 = yield(const ()) -> [resume: bb62, drop: bb63]; + } + + bb65: { + _51 = discriminant(_50); + switchInt(move _51) -> [0: bb51, 1: bb64, otherwise: bb12]; + } + + bb66: { + _50 = as Future>::poll(move _52, move _53) -> [return: bb65, unwind: bb53]; + } + + bb67: { + _54 = move _2; + _53 = std::future::get_context::<'_, '_>(move _54) -> [return: bb66, unwind: bb53]; + } + + bb68: { + _55 = &mut _41; + _52 = Pin::<&mut impl Future>::new_unchecked(move _55) -> [return: bb67, unwind: bb53]; + } + + bb69: { + StorageLive(_41); + _41 = async_drop_in_place::(copy (_56.0: &mut AsyncInt)) -> [return: bb68, unwind: bb53]; + } + + bb70: { + _57 = &mut ((*_3).1: AsyncInt); + _56 = Pin::<&mut AsyncInt>::new_unchecked(move _57) -> [return: bb69, unwind: bb4]; + } + + bb71: { + StorageDead(_58); + goto -> bb70; + } + + bb72: { + StorageDead(_58); + goto -> bb30; + } + + bb73 (cleanup): { + StorageDead(_58); + goto -> bb5; + } + + bb74: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb74, unwind: bb73]; + } + + bb75: { + _2 = move _59; + StorageDead(_59); + goto -> bb74; + } + + bb76: { + _2 = move _59; + StorageDead(_59); + goto -> bb81; + } + + bb77: { + StorageLive(_59); + _59 = yield(const ()) -> [resume: bb75, drop: bb76]; + } + + bb78: { + _61 = discriminant(_60); + switchInt(move _61) -> [0: bb72, 1: bb77, otherwise: bb12]; + } + + bb79: { + _60 = as Future>::poll(move _62, move _63) -> [return: bb78, unwind: bb73]; + } + + bb80: { + _64 = move _2; + _63 = std::future::get_context::<'_, '_>(move _64) -> [return: bb79, unwind: bb73]; + } + + bb81: { + _65 = &mut _58; + _62 = Pin::<&mut impl Future>::new_unchecked(move _65) -> [return: bb80, unwind: bb73]; + } + + bb82: { + _2 = move _66; + StorageDead(_66); + goto -> bb88; + } + + bb83: { + _2 = move _66; + StorageDead(_66); + goto -> bb81; + } + + bb84: { + StorageLive(_66); + _66 = yield(const ()) -> [resume: bb82, drop: bb83]; + } + + bb85: { + _68 = discriminant(_67); + switchInt(move _68) -> [0: bb71, 1: bb84, otherwise: bb12]; + } + + bb86: { + _67 = as Future>::poll(move _69, move _70) -> [return: bb85, unwind: bb73]; + } + + bb87: { + _71 = move _2; + _70 = std::future::get_context::<'_, '_>(move _71) -> [return: bb86, unwind: bb73]; + } + + bb88: { + _72 = &mut _58; + _69 = Pin::<&mut impl Future>::new_unchecked(move _72) -> [return: bb87, unwind: bb73]; + } + + bb89: { + StorageLive(_58); + _58 = ::drop(move _73) -> [return: bb88, unwind: bb73]; } - bb33: { - _18 = &mut (*_3); - _17 = Pin::<&mut AsyncStruct>::new_unchecked(move _18) -> [return: bb32, unwind: bb5]; + bb90: { + _74 = &mut (*_3); + _73 = Pin::<&mut AsyncStruct>::new_unchecked(move _74) -> [return: bb89, unwind: bb5]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff index 0e68c6c1eafa4..0de0be9675f9b 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncStruct.StateTransform.diff @@ -31,361 +31,679 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut AsyncStruct; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncInt>; - let mut _6: &mut AsyncInt; - let mut _7: impl std::future::Future; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: impl std::future::Future; - let mut _11: std::pin::Pin<&mut AsyncInt>; - let mut _12: &mut AsyncInt; - let mut _13: impl std::future::Future; - let mut _14: std::pin::Pin<&mut AsyncInt>; - let mut _15: &mut AsyncInt; - let mut _16: impl std::future::Future; - let mut _17: std::pin::Pin<&mut AsyncStruct>; - let mut _18: &mut AsyncStruct; -+ let mut _19: std::task::Poll<()>; +- let mut _5: std::future::ResumeTy; ++ let mut _5: &mut std::task::Context<'_>; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; +- let mut _10: std::future::ResumeTy; ++ let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; +- let mut _15: std::future::ResumeTy; ++ let mut _15: &mut std::task::Context<'_>; + let mut _16: std::task::Poll<()>; + let mut _17: isize; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: &mut std::task::Context<'_>; +- let mut _20: std::future::ResumeTy; + let mut _20: &mut std::task::Context<'_>; -+ let mut _21: &mut impl std::future::Future; -+ let mut _22: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _23: isize; -+ let mut _24: std::task::Poll<()>; + let mut _21: &mut impl std::future::Future; + let mut _22: std::pin::Pin<&mut AsyncInt>; + let mut _23: &mut AsyncInt; + let mut _24: impl std::future::Future; +- let mut _25: std::future::ResumeTy; + let mut _25: &mut std::task::Context<'_>; -+ let mut _26: &mut impl std::future::Future; -+ let mut _27: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _28: isize; -+ let mut _29: std::task::Poll<()>; + let mut _26: std::task::Poll<()>; + let mut _27: isize; + let mut _28: std::pin::Pin<&mut impl std::future::Future>; + let mut _29: &mut std::task::Context<'_>; +- let mut _30: std::future::ResumeTy; + let mut _30: &mut std::task::Context<'_>; -+ let mut _31: &mut impl std::future::Future; -+ let mut _32: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _33: isize; -+ let mut _34: &mut std::task::Context<'_>; -+ let mut _35: &mut impl std::future::Future; -+ let mut _36: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _37: isize; -+ let mut _38: std::task::Poll<()>; -+ let mut _39: &mut std::task::Context<'_>; -+ let mut _40: &mut impl std::future::Future; -+ let mut _41: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _42: isize; -+ let mut _43: &mut std::task::Context<'_>; -+ let mut _44: &mut impl std::future::Future; -+ let mut _45: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _46: isize; -+ let mut _47: std::task::Poll<()>; -+ let mut _48: &mut std::task::Context<'_>; -+ let mut _49: &mut impl std::future::Future; -+ let mut _50: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _51: isize; -+ let mut _52: &mut std::task::Context<'_>; -+ let mut _53: &mut impl std::future::Future; -+ let mut _54: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _55: isize; -+ let mut _56: (); -+ let mut _57: u32; -+ let mut _58: &mut {async fn body of std::future::async_drop_in_place()}; -+ let mut _59: &mut AsyncStruct; -+ let mut _60: &mut AsyncStruct; -+ let mut _61: &mut AsyncStruct; -+ let mut _62: &mut AsyncStruct; -+ let mut _63: &mut AsyncStruct; + let mut _31: &mut impl std::future::Future; +- let mut _32: std::future::ResumeTy; ++ let mut _32: &mut std::task::Context<'_>; + let mut _33: std::task::Poll<()>; + let mut _34: isize; + let mut _35: std::pin::Pin<&mut impl std::future::Future>; + let mut _36: &mut std::task::Context<'_>; +- let mut _37: std::future::ResumeTy; ++ let mut _37: &mut std::task::Context<'_>; + let mut _38: &mut impl std::future::Future; + let mut _39: std::pin::Pin<&mut AsyncInt>; + let mut _40: &mut AsyncInt; + let mut _41: impl std::future::Future; +- let mut _42: std::future::ResumeTy; ++ let mut _42: &mut std::task::Context<'_>; + let mut _43: std::task::Poll<()>; + let mut _44: isize; + let mut _45: std::pin::Pin<&mut impl std::future::Future>; + let mut _46: &mut std::task::Context<'_>; +- let mut _47: std::future::ResumeTy; ++ let mut _47: &mut std::task::Context<'_>; + let mut _48: &mut impl std::future::Future; +- let mut _49: std::future::ResumeTy; ++ let mut _49: &mut std::task::Context<'_>; + let mut _50: std::task::Poll<()>; + let mut _51: isize; + let mut _52: std::pin::Pin<&mut impl std::future::Future>; + let mut _53: &mut std::task::Context<'_>; +- let mut _54: std::future::ResumeTy; ++ let mut _54: &mut std::task::Context<'_>; + let mut _55: &mut impl std::future::Future; + let mut _56: std::pin::Pin<&mut AsyncInt>; + let mut _57: &mut AsyncInt; + let mut _58: impl std::future::Future; +- let mut _59: std::future::ResumeTy; ++ let mut _59: &mut std::task::Context<'_>; + let mut _60: std::task::Poll<()>; + let mut _61: isize; + let mut _62: std::pin::Pin<&mut impl std::future::Future>; + let mut _63: &mut std::task::Context<'_>; +- let mut _64: std::future::ResumeTy; ++ let mut _64: &mut std::task::Context<'_>; + let mut _65: &mut impl std::future::Future; +- let mut _66: std::future::ResumeTy; ++ let mut _66: &mut std::task::Context<'_>; + let mut _67: std::task::Poll<()>; + let mut _68: isize; + let mut _69: std::pin::Pin<&mut impl std::future::Future>; + let mut _70: &mut std::task::Context<'_>; +- let mut _71: std::future::ResumeTy; ++ let mut _71: &mut std::task::Context<'_>; + let mut _72: &mut impl std::future::Future; + let mut _73: std::pin::Pin<&mut AsyncStruct>; + let mut _74: &mut AsyncStruct; ++ let mut _75: (); ++ let mut _76: u32; ++ let mut _77: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _78: &mut AsyncStruct; ++ let mut _79: &mut AsyncStruct; ++ let mut _80: &mut AsyncStruct; ++ let mut _81: &mut AsyncStruct; ++ let mut _82: &mut AsyncStruct; bb0: { - _3 = move (_1.0: &mut AsyncStruct); -- _18 = &mut (*_3); -- _17 = Pin::<&mut AsyncStruct>::new_unchecked(move _18) -> [return: bb28, unwind: bb4]; -+ _58 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); -+ _57 = discriminant((*_58)); -+ switchInt(move _57) -> [0: bb46, 1: bb45, 2: bb44, 3: bb36, 4: bb37, 5: bb38, 6: bb39, 7: bb40, 8: bb41, 9: bb42, 10: bb43, otherwise: bb21]; +- _74 = &mut (*_3); +- _73 = Pin::<&mut AsyncStruct>::new_unchecked(move _74) -> [return: bb85, unwind: bb4]; ++ _77 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _76 = discriminant((*_77)); ++ switchInt(move _76) -> [0: bb56, 1: bb55, 2: bb54, 3: bb46, 4: bb47, 5: bb48, 6: bb49, 7: bb50, 8: bb51, 9: bb52, 10: bb53, otherwise: bb8]; } bb1: { -+ _0 = Poll::<()>::Ready(move _56); -+ discriminant((*_58)) = 1; ++ _0 = Poll::<()>::Ready(move _75); ++ discriminant((*_77)) = 1; return; } bb2 (cleanup): { - resume; -+ goto -> bb35; ++ goto -> bb45; } bb3 (cleanup): { - drop(((*_3).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ _59 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); -+ drop(((*_59).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _78 = no_retag copy (((*_77) as variant#10).0: &mut AsyncStruct); ++ drop(((*_78).2: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb4 (cleanup): { - drop(((*_3).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; -+ _60 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); -+ drop(((*_60).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; ++ _79 = no_retag copy (((*_77) as variant#10).0: &mut AsyncStruct); ++ drop(((*_79).1: AsyncInt)) -> [return: bb3, unwind terminate(cleanup)]; } - bb5: { +- bb5: { - StorageDead(_4); +- goto -> bb1; ++ bb5 (cleanup): { + nop; - goto -> bb1; ++ goto -> bb2; } - bb6 (cleanup): { +- bb6 (cleanup): { - StorageDead(_4); -+ nop; - goto -> bb2; +- goto -> bb2; ++ bb6: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb6, unwind: bb5]; } bb7: { -- async drop(((*_3).2: AsyncInt); poll=_4) -> [return: bb5, unwind: bb6]; -+ _30 = move _2; -+ goto -> bb20; +- assert(const false, "`async fn` resumed after async drop") -> [success: bb7, unwind: bb6]; ++ _2 = move _5; ++ StorageDead(_5); ++ goto -> bb6; } bb8: { -- StorageLive(_4); -- _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb7, unwind: bb6]; -+ nop; -+ (((*_58) as variant#6).0: impl std::future::Future) = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb7, unwind: bb6]; +- _2 = move _5; +- StorageDead(_5); +- goto -> bb7; ++ unreachable; } - bb9: { -- _6 = &mut ((*_3).2: AsyncInt); -- _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb8, unwind: bb2]; +- bb9: { +- _2 = move _5; +- StorageDead(_5); +- goto -> bb15; ++ bb9 (cleanup): { + nop; -+ _61 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); -+ _12 = &mut ((*_61).2: AsyncInt); -+ _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb8, unwind: bb2]; ++ goto -> bb3; } -- bb10: { -- StorageDead(_7); -- goto -> bb9; -+ bb10 (cleanup): { -+ nop; -+ goto -> bb3; + bb10: { +- StorageLive(_5); +- _5 = yield(const ()) -> [resume: bb8, drop: bb9]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb10, unwind: bb9]; } -- bb11 (cleanup): { -- StorageDead(_7); -- goto -> bb3; -+ bb11: { -+ _39 = move _2; -+ goto -> bb26; + bb11: { +- unreachable; ++ _2 = move _15; ++ StorageDead(_15); ++ goto -> bb10; } bb12: { -- async drop(((*_3).1: AsyncInt); poll=_7) -> [return: bb10, unwind: bb11]; +- _7 = discriminant(_6); +- switchInt(move _7) -> [0: bb5, 1: bb10, otherwise: bb11]; + nop; -+ (((*_58) as variant#8).1: impl std::future::Future) = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb11, unwind: bb10]; ++ goto -> bb1; } - bb13: { -- StorageLive(_7); -- _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb12, unwind: bb11]; +- bb13: { +- _6 = as Future>::poll(move _8, move _9) -> [return: bb12, unwind: bb6]; ++ bb13 (cleanup): { + nop; -+ _62 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); -+ _15 = &mut ((*_62).1: AsyncInt); -+ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb12, unwind: bb3]; ++ goto -> bb2; } -- bb14: { -- StorageDead(_10); -- goto -> bb1; -+ bb14 (cleanup): { -+ nop; -+ goto -> bb4; + bb14: { +- _10 = move _2; +- _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb13, unwind: bb6]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb13]; } bb15: { -- StorageDead(_10); -- goto -> bb1; -+ _48 = move _2; -+ goto -> bb31; +- _11 = &mut _4; +- _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb14, unwind: bb6]; ++ _2 = move _25; ++ StorageDead(_25); ++ goto -> bb14; } -- bb16 (cleanup): { -- StorageDead(_10); -- goto -> bb2; -+ bb16: { -+ nop; -+ (((*_58) as variant#10).1: impl std::future::Future) = ::drop(move _17) -> [return: bb15, unwind: bb14]; + bb16: { +- StorageLive(_4); +- _4 = async_drop_in_place::(copy (_12.0: &mut AsyncInt)) -> [return: bb15, unwind: bb6]; ++ _2 = move _32; ++ StorageDead(_32); ++ goto -> bb21; } bb17: { -- async drop(((*_3).2: AsyncInt); poll=_10) -> [return: bb14, unwind: bb16, drop: bb15]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb17, unwind: bb35]; +- _13 = &mut ((*_3).2: AsyncInt); +- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb16, unwind: bb2]; ++ StorageLive(_32); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_32); ++ discriminant((*_77)) = 6; ++ return; } bb18: { -- StorageLive(_10); -- _10 = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb17, unwind: bb16]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb18, unwind: bb35]; +- StorageDead(_14); +- goto -> bb17; ++ _34 = discriminant(_33); ++ switchInt(move _34) -> [0: bb12, 1: bb17, otherwise: bb8]; } - bb19: { -- StorageDead(_13); -- _12 = &mut ((*_3).2: AsyncInt); -- _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb18, unwind: bb2]; -+ _0 = Poll::<()>::Pending; -+ discriminant((*_58)) = 5; -+ return; +- bb19 (cleanup): { +- StorageDead(_14); +- goto -> bb3; ++ bb19: { ++ _33 = as Future>::poll(move _35, move _36) -> [return: bb18, unwind: bb13]; } bb20: { -- StorageDead(_13); -- goto -> bb9; -+ StorageLive(_32); -+ _31 = &mut (((*_58) as variant#6).0: impl std::future::Future); -+ _32 = Pin::<&mut impl Future>::new_unchecked(move _31) -> [return: bb23, unwind: bb35]; +- assert(const false, "`async fn` resumed after async drop") -> [success: bb20, unwind: bb19]; ++ _37 = move _2; ++ _36 = move _37; ++ goto -> bb19; } -- bb21 (cleanup): { -- StorageDead(_13); -- goto -> bb3; -+ bb21: { -+ unreachable; + bb21: { +- _2 = move _15; +- StorageDead(_15); +- goto -> bb20; ++ _38 = &mut (((*_77) as variant#6).0: impl std::future::Future); ++ _35 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb20, unwind: bb13]; } bb22: { -- async drop(((*_3).1: AsyncInt); poll=_13) -> [return: bb19, unwind: bb21, drop: bb20]; -+ StorageDead(_32); -+ _33 = discriminant(_29); -+ switchInt(move _33) -> [0: bb5, 1: bb19, otherwise: bb21]; +- _2 = move _15; +- StorageDead(_15); +- goto -> bb27; ++ nop; ++ (((*_77) as variant#6).0: impl std::future::Future) = async_drop_in_place::(copy (_39.0: &mut AsyncInt)) -> [return: bb21, unwind: bb13]; } bb23: { -- StorageLive(_13); -- _13 = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb22, unwind: bb21]; -+ _29 = as Future>::poll(move _32, move _30) -> [return: bb22, unwind: bb6]; +- StorageLive(_15); +- _15 = yield(const ()) -> [resume: bb21, drop: bb22]; ++ nop; ++ _80 = no_retag copy (((*_77) as variant#10).0: &mut AsyncStruct); ++ _40 = &mut ((*_80).2: AsyncInt); ++ _39 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb22, unwind: bb2]; } - bb24: { -- StorageDead(_16); -- _15 = &mut ((*_3).1: AsyncInt); -- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb23, unwind: bb3]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb24, unwind: bb35]; +- bb24: { +- _17 = discriminant(_16); +- switchInt(move _17) -> [0: bb18, 1: bb23, otherwise: bb11]; ++ bb24 (cleanup): { ++ nop; ++ goto -> bb3; } bb25: { -- StorageDead(_16); -- _9 = &mut ((*_3).1: AsyncInt); -- _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb3]; -+ _0 = Poll::<()>::Pending; -+ discriminant((*_58)) = 7; -+ return; +- _16 = as Future>::poll(move _18, move _19) -> [return: bb24, unwind: bb19]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb25, unwind: bb24]; } -- bb26 (cleanup): { -- StorageDead(_16); -- goto -> bb4; -+ bb26: { -+ StorageLive(_41); -+ _40 = &mut (((*_58) as variant#8).1: impl std::future::Future); -+ _41 = Pin::<&mut impl Future>::new_unchecked(move _40) -> [return: bb28, unwind: bb35]; + bb26: { +- _20 = move _2; +- _19 = std::future::get_context::<'_, '_>(move _20) -> [return: bb25, unwind: bb19]; ++ _2 = move _42; ++ StorageDead(_42); ++ goto -> bb25; } bb27: { -- async drop((*_3); poll=_16) -> [return: bb24, unwind: bb26, drop: bb25]; -+ StorageDead(_41); -+ _42 = discriminant(_38); -+ switchInt(move _42) -> [0: bb9, 1: bb25, otherwise: bb21]; +- _21 = &mut _14; +- _18 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb26, unwind: bb19]; ++ _2 = move _49; ++ StorageDead(_49); ++ goto -> bb32; } bb28: { -- StorageLive(_16); -- _16 = ::drop(move _17) -> [return: bb27, unwind: bb26]; -+ _38 = as Future>::poll(move _41, move _39) -> [return: bb27, unwind: bb10]; -+ } -+ -+ bb29: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb29, unwind: bb35]; -+ } -+ -+ bb30: { +- StorageLive(_14); +- _14 = async_drop_in_place::(copy (_22.0: &mut AsyncInt)) -> [return: bb27, unwind: bb19]; ++ StorageLive(_49); + _0 = Poll::<()>::Pending; -+ discriminant((*_58)) = 9; ++ StorageDead(_49); ++ discriminant((*_77)) = 8; + return; -+ } -+ + } + + bb29: { +- StorageDead(_24); +- goto -> bb1; ++ _51 = discriminant(_50); ++ switchInt(move _51) -> [0: bb23, 1: bb28, otherwise: bb8]; + } + + bb30: { +- StorageDead(_24); +- goto -> bb1; ++ _50 = as Future>::poll(move _52, move _53) -> [return: bb29, unwind: bb24]; + } + +- bb31 (cleanup): { +- StorageDead(_24); +- goto -> bb2; + bb31: { -+ StorageLive(_50); -+ _49 = &mut (((*_58) as variant#10).1: impl std::future::Future); -+ _50 = Pin::<&mut impl Future>::new_unchecked(move _49) -> [return: bb33, unwind: bb35]; -+ } -+ -+ bb32: { -+ StorageDead(_50); -+ _51 = discriminant(_47); -+ switchInt(move _51) -> [0: bb13, 1: bb30, otherwise: bb21]; -+ } -+ -+ bb33: { -+ _47 = as Future>::poll(move _50, move _48) -> [return: bb32, unwind: bb14]; -+ } -+ -+ bb34: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb34, unwind: bb35]; -+ } -+ ++ _54 = move _2; ++ _53 = move _54; ++ goto -> bb30; + } + + bb32: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb32, unwind: bb31]; ++ _55 = &mut (((*_77) as variant#8).1: impl std::future::Future); ++ _52 = Pin::<&mut impl Future>::new_unchecked(move _55) -> [return: bb31, unwind: bb24]; + } + + bb33: { +- _2 = move _25; +- StorageDead(_25); +- goto -> bb32; ++ nop; ++ (((*_77) as variant#8).1: impl std::future::Future) = async_drop_in_place::(copy (_56.0: &mut AsyncInt)) -> [return: bb32, unwind: bb24]; + } + + bb34: { +- _2 = move _25; +- StorageDead(_25); +- goto -> bb39; ++ nop; ++ _81 = no_retag copy (((*_77) as variant#10).0: &mut AsyncStruct); ++ _57 = &mut ((*_81).1: AsyncInt); ++ _56 = Pin::<&mut AsyncInt>::new_unchecked(move _57) -> [return: bb33, unwind: bb3]; + } + +- bb35: { +- StorageLive(_25); +- _25 = yield(const ()) -> [resume: bb33, drop: bb34]; + bb35 (cleanup): { -+ discriminant((*_58)) = 2; ++ nop; ++ goto -> bb4; + } + + bb36: { +- _27 = discriminant(_26); +- switchInt(move _27) -> [0: bb30, 1: bb35, otherwise: bb11]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb36, unwind: bb35]; + } + + bb37: { +- _26 = as Future>::poll(move _28, move _29) -> [return: bb36, unwind: bb31]; ++ _2 = move _59; ++ StorageDead(_59); ++ goto -> bb36; + } + + bb38: { +- _30 = move _2; +- _29 = std::future::get_context::<'_, '_>(move _30) -> [return: bb37, unwind: bb31]; ++ _2 = move _66; ++ StorageDead(_66); ++ goto -> bb43; + } + + bb39: { +- _31 = &mut _24; +- _28 = Pin::<&mut impl Future>::new_unchecked(move _31) -> [return: bb38, unwind: bb31]; ++ StorageLive(_66); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_66); ++ discriminant((*_77)) = 10; ++ return; + } + + bb40: { +- _2 = move _32; +- StorageDead(_32); +- goto -> bb46; ++ _68 = discriminant(_67); ++ switchInt(move _68) -> [0: bb34, 1: bb39, otherwise: bb8]; + } + + bb41: { +- _2 = move _32; +- StorageDead(_32); +- goto -> bb39; ++ _67 = as Future>::poll(move _69, move _70) -> [return: bb40, unwind: bb35]; + } + + bb42: { +- StorageLive(_32); +- _32 = yield(const ()) -> [resume: bb40, drop: bb41]; ++ _71 = move _2; ++ _70 = move _71; ++ goto -> bb41; + } + + bb43: { +- _34 = discriminant(_33); +- switchInt(move _34) -> [0: bb29, 1: bb42, otherwise: bb11]; ++ _72 = &mut (((*_77) as variant#10).1: impl std::future::Future); ++ _69 = Pin::<&mut impl Future>::new_unchecked(move _72) -> [return: bb42, unwind: bb35]; + } + + bb44: { +- _33 = as Future>::poll(move _35, move _36) -> [return: bb43, unwind: bb31]; ++ nop; ++ (((*_77) as variant#10).1: impl std::future::Future) = ::drop(move _73) -> [return: bb43, unwind: bb35]; + } + +- bb45: { +- _37 = move _2; +- _36 = std::future::get_context::<'_, '_>(move _37) -> [return: bb44, unwind: bb31]; ++ bb45 (cleanup): { ++ discriminant((*_77)) = 2; + resume; -+ } -+ -+ bb36: { -+ _20 = move _2; -+ goto -> bb17; -+ } -+ -+ bb37: { + } + + bb46: { +- _38 = &mut _24; +- _35 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb45, unwind: bb31]; ++ StorageLive(_5); ++ _5 = move _2; ++ goto -> bb7; + } + + bb47: { +- StorageLive(_24); +- _24 = async_drop_in_place::(copy (_39.0: &mut AsyncInt)) -> [return: bb46, unwind: bb31]; ++ StorageLive(_15); ++ _15 = move _2; ++ goto -> bb11; + } + + bb48: { +- StorageDead(_41); +- _40 = &mut ((*_3).2: AsyncInt); +- _39 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb47, unwind: bb2]; ++ StorageLive(_25); + _25 = move _2; -+ goto -> bb18; -+ } -+ -+ bb38: { -+ _30 = move _2; -+ goto -> bb20; -+ } -+ -+ bb39: { -+ _34 = move _2; -+ goto -> bb24; -+ } -+ -+ bb40: { -+ _39 = move _2; ++ goto -> bb15; + } + + bb49: { +- StorageDead(_41); +- goto -> bb17; ++ StorageLive(_32); ++ _32 = move _2; ++ goto -> bb16; + } + +- bb50 (cleanup): { +- StorageDead(_41); +- goto -> bb3; ++ bb50: { ++ StorageLive(_42); ++ _42 = move _2; + goto -> bb26; -+ } -+ -+ bb41: { -+ _43 = move _2; -+ goto -> bb29; -+ } -+ -+ bb42: { -+ _48 = move _2; -+ goto -> bb31; -+ } -+ -+ bb43: { -+ _52 = move _2; -+ goto -> bb34; -+ } -+ -+ bb44: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb44, unwind continue]; -+ } -+ -+ bb45: { + } + + bb51: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb51, unwind: bb50]; ++ StorageLive(_49); ++ _49 = move _2; ++ goto -> bb27; + } + + bb52: { +- _2 = move _42; +- StorageDead(_42); +- goto -> bb51; ++ StorageLive(_59); ++ _59 = move _2; ++ goto -> bb37; + } + + bb53: { +- _2 = move _42; +- StorageDead(_42); +- goto -> bb58; ++ StorageLive(_66); ++ _66 = move _2; ++ goto -> bb38; + } + + bb54: { +- StorageLive(_42); +- _42 = yield(const ()) -> [resume: bb52, drop: bb53]; ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb54, unwind continue]; + } + + bb55: { +- _44 = discriminant(_43); +- switchInt(move _44) -> [0: bb49, 1: bb54, otherwise: bb11]; + _0 = Poll::<()>::Ready(const ()); + return; -+ } -+ -+ bb46: { -+ (((*_58) as variant#10).0: &mut AsyncStruct) = move ((*_58).0: &mut AsyncStruct); -+ _63 = no_retag copy (((*_58) as variant#10).0: &mut AsyncStruct); -+ _18 = &mut (*_63); -+ _17 = Pin::<&mut AsyncStruct>::new_unchecked(move _18) -> [return: bb16, unwind: bb4]; + } + + bb56: { +- _43 = as Future>::poll(move _45, move _46) -> [return: bb55, unwind: bb50]; +- } +- +- bb57: { +- _47 = move _2; +- _46 = std::future::get_context::<'_, '_>(move _47) -> [return: bb56, unwind: bb50]; +- } +- +- bb58: { +- _48 = &mut _41; +- _45 = Pin::<&mut impl Future>::new_unchecked(move _48) -> [return: bb57, unwind: bb50]; +- } +- +- bb59: { +- _2 = move _49; +- StorageDead(_49); +- goto -> bb65; +- } +- +- bb60: { +- _2 = move _49; +- StorageDead(_49); +- goto -> bb58; +- } +- +- bb61: { +- StorageLive(_49); +- _49 = yield(const ()) -> [resume: bb59, drop: bb60]; +- } +- +- bb62: { +- _51 = discriminant(_50); +- switchInt(move _51) -> [0: bb48, 1: bb61, otherwise: bb11]; +- } +- +- bb63: { +- _50 = as Future>::poll(move _52, move _53) -> [return: bb62, unwind: bb50]; +- } +- +- bb64: { +- _54 = move _2; +- _53 = std::future::get_context::<'_, '_>(move _54) -> [return: bb63, unwind: bb50]; +- } +- +- bb65: { +- _55 = &mut _41; +- _52 = Pin::<&mut impl Future>::new_unchecked(move _55) -> [return: bb64, unwind: bb50]; +- } +- +- bb66: { +- StorageLive(_41); +- _41 = async_drop_in_place::(copy (_56.0: &mut AsyncInt)) -> [return: bb65, unwind: bb50]; +- } +- +- bb67: { +- StorageDead(_58); +- _57 = &mut ((*_3).1: AsyncInt); +- _56 = Pin::<&mut AsyncInt>::new_unchecked(move _57) -> [return: bb66, unwind: bb3]; +- } +- +- bb68: { +- StorageDead(_58); +- _23 = &mut ((*_3).1: AsyncInt); +- _22 = Pin::<&mut AsyncInt>::new_unchecked(move _23) -> [return: bb28, unwind: bb3]; +- } +- +- bb69 (cleanup): { +- StorageDead(_58); +- goto -> bb4; +- } +- +- bb70: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb70, unwind: bb69]; +- } +- +- bb71: { +- _2 = move _59; +- StorageDead(_59); +- goto -> bb70; +- } +- +- bb72: { +- _2 = move _59; +- StorageDead(_59); +- goto -> bb77; +- } +- +- bb73: { +- StorageLive(_59); +- _59 = yield(const ()) -> [resume: bb71, drop: bb72]; +- } +- +- bb74: { +- _61 = discriminant(_60); +- switchInt(move _61) -> [0: bb68, 1: bb73, otherwise: bb11]; +- } +- +- bb75: { +- _60 = as Future>::poll(move _62, move _63) -> [return: bb74, unwind: bb69]; +- } +- +- bb76: { +- _64 = move _2; +- _63 = std::future::get_context::<'_, '_>(move _64) -> [return: bb75, unwind: bb69]; +- } +- +- bb77: { +- _65 = &mut _58; +- _62 = Pin::<&mut impl Future>::new_unchecked(move _65) -> [return: bb76, unwind: bb69]; +- } +- +- bb78: { +- _2 = move _66; +- StorageDead(_66); +- goto -> bb84; +- } +- +- bb79: { +- _2 = move _66; +- StorageDead(_66); +- goto -> bb77; +- } +- +- bb80: { +- StorageLive(_66); +- _66 = yield(const ()) -> [resume: bb78, drop: bb79]; +- } +- +- bb81: { +- _68 = discriminant(_67); +- switchInt(move _68) -> [0: bb67, 1: bb80, otherwise: bb11]; +- } +- +- bb82: { +- _67 = as Future>::poll(move _69, move _70) -> [return: bb81, unwind: bb69]; +- } +- +- bb83: { +- _71 = move _2; +- _70 = std::future::get_context::<'_, '_>(move _71) -> [return: bb82, unwind: bb69]; +- } +- +- bb84: { +- _72 = &mut _58; +- _69 = Pin::<&mut impl Future>::new_unchecked(move _72) -> [return: bb83, unwind: bb69]; +- } +- +- bb85: { +- StorageLive(_58); +- _58 = ::drop(move _73) -> [return: bb84, unwind: bb69]; ++ (((*_77) as variant#10).0: &mut AsyncStruct) = move ((*_77).0: &mut AsyncStruct); ++ _82 = no_retag copy (((*_77) as variant#10).0: &mut AsyncStruct); ++ _74 = &mut (*_82); ++ _73 = Pin::<&mut AsyncStruct>::new_unchecked(move _74) -> [return: bb44, unwind: bb4]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir index d4173722e4313..b5d451bbdc4a1 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.MentionedItems.after.mir @@ -6,23 +6,65 @@ yields () let mut _0: (); let mut _3: &mut SyncThenAsync; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncInt>; - let mut _6: &mut AsyncInt; - let mut _7: impl std::future::Future; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: impl std::future::Future; - let mut _11: std::pin::Pin<&mut AsyncInt>; - let mut _12: &mut AsyncInt; - let mut _13: impl std::future::Future; - let mut _14: std::pin::Pin<&mut AsyncInt>; - let mut _15: &mut AsyncInt; - let mut _16: &mut SyncThenAsync; - let mut _17: (); + let mut _5: std::future::ResumeTy; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; + let mut _10: std::future::ResumeTy; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; + let mut _15: std::future::ResumeTy; + let mut _16: std::task::Poll<()>; + let mut _17: isize; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: std::future::ResumeTy; + let mut _21: &mut impl std::future::Future; + let mut _22: std::pin::Pin<&mut AsyncInt>; + let mut _23: &mut AsyncInt; + let mut _24: impl std::future::Future; + let mut _25: std::future::ResumeTy; + let mut _26: std::task::Poll<()>; + let mut _27: isize; + let mut _28: std::pin::Pin<&mut impl std::future::Future>; + let mut _29: &mut std::task::Context<'_>; + let mut _30: std::future::ResumeTy; + let mut _31: &mut impl std::future::Future; + let mut _32: std::future::ResumeTy; + let mut _33: std::task::Poll<()>; + let mut _34: isize; + let mut _35: std::pin::Pin<&mut impl std::future::Future>; + let mut _36: &mut std::task::Context<'_>; + let mut _37: std::future::ResumeTy; + let mut _38: &mut impl std::future::Future; + let mut _39: std::pin::Pin<&mut AsyncInt>; + let mut _40: &mut AsyncInt; + let mut _41: impl std::future::Future; + let mut _42: std::future::ResumeTy; + let mut _43: std::task::Poll<()>; + let mut _44: isize; + let mut _45: std::pin::Pin<&mut impl std::future::Future>; + let mut _46: &mut std::task::Context<'_>; + let mut _47: std::future::ResumeTy; + let mut _48: &mut impl std::future::Future; + let mut _49: std::future::ResumeTy; + let mut _50: std::task::Poll<()>; + let mut _51: isize; + let mut _52: std::pin::Pin<&mut impl std::future::Future>; + let mut _53: &mut std::task::Context<'_>; + let mut _54: std::future::ResumeTy; + let mut _55: &mut impl std::future::Future; + let mut _56: std::pin::Pin<&mut AsyncInt>; + let mut _57: &mut AsyncInt; + let mut _58: &mut SyncThenAsync; + let mut _59: (); bb0: { _3 = move (_1.0: &mut SyncThenAsync); - goto -> bb31; + goto -> bb74; } bb1: { @@ -60,111 +102,331 @@ yields () } bb9: { - async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb7, unwind: bb8]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb9, unwind: bb8]; } bb10: { - StorageLive(_4); - _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb9, unwind: bb8]; + _2 = move _5; + StorageDead(_5); + goto -> bb9; } bb11: { - _6 = &mut ((*_3).3: AsyncInt); - _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb10, unwind: bb2]; + _2 = move _5; + StorageDead(_5); + goto -> bb17; } bb12: { - drop(((*_3).2: SyncInt)) -> [return: bb11, unwind: bb4]; + StorageLive(_5); + _5 = yield(const ()) -> [resume: bb10, drop: bb11]; } bb13: { - StorageDead(_7); - goto -> bb12; + unreachable; } - bb14 (cleanup): { - StorageDead(_7); - goto -> bb5; + bb14: { + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb7, 1: bb12, otherwise: bb13]; } bb15: { - async drop(((*_3).1: AsyncInt); poll=_7) -> [return: bb13, unwind: bb14]; + _6 = as Future>::poll(move _8, move _9) -> [return: bb14, unwind: bb8]; } bb16: { - StorageLive(_7); - _7 = async_drop_in_place::(copy (_8.0: &mut AsyncInt)) -> [return: bb15, unwind: bb14]; + _10 = move _2; + _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb15, unwind: bb8]; } bb17: { - _9 = &mut ((*_3).1: AsyncInt); - _8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb16, unwind: bb5]; + _11 = &mut _4; + _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb16, unwind: bb8]; } bb18: { - StorageDead(_10); - goto -> bb3; + StorageLive(_4); + _4 = async_drop_in_place::(copy (_12.0: &mut AsyncInt)) -> [return: bb17, unwind: bb8]; } bb19: { - StorageDead(_10); - goto -> bb1; + _13 = &mut ((*_3).3: AsyncInt); + _12 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb18, unwind: bb2]; } - bb20 (cleanup): { - StorageDead(_10); - goto -> bb2; + bb20: { + drop(((*_3).2: SyncInt)) -> [return: bb19, unwind: bb4]; } bb21: { - async drop(((*_3).3: AsyncInt); poll=_10) -> [return: bb18, unwind: bb20, drop: bb19]; + StorageDead(_14); + goto -> bb20; } - bb22: { - StorageLive(_10); - _10 = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb21, unwind: bb20]; + bb22 (cleanup): { + StorageDead(_14); + goto -> bb5; } bb23: { - _12 = &mut ((*_3).3: AsyncInt); - _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb22, unwind: bb2]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb23, unwind: bb22]; } bb24: { - drop(((*_3).2: SyncInt)) -> [return: bb23, unwind: bb4]; + _2 = move _15; + StorageDead(_15); + goto -> bb23; } bb25: { - StorageDead(_13); - goto -> bb24; + _2 = move _15; + StorageDead(_15); + goto -> bb30; } bb26: { - StorageDead(_13); - goto -> bb12; + StorageLive(_15); + _15 = yield(const ()) -> [resume: bb24, drop: bb25]; } - bb27 (cleanup): { - StorageDead(_13); - goto -> bb5; + bb27: { + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb21, 1: bb26, otherwise: bb13]; } bb28: { - async drop(((*_3).1: AsyncInt); poll=_13) -> [return: bb25, unwind: bb27, drop: bb26]; + _16 = as Future>::poll(move _18, move _19) -> [return: bb27, unwind: bb22]; } bb29: { - StorageLive(_13); - _13 = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb28, unwind: bb27]; + _20 = move _2; + _19 = std::future::get_context::<'_, '_>(move _20) -> [return: bb28, unwind: bb22]; } bb30: { - _15 = &mut ((*_3).1: AsyncInt); - _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb29, unwind: bb5]; + _21 = &mut _14; + _18 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb29, unwind: bb22]; } bb31: { - _16 = &mut (*_3); - _17 = ::drop(move _16) -> [return: bb30, unwind: bb6]; + StorageLive(_14); + _14 = async_drop_in_place::(copy (_22.0: &mut AsyncInt)) -> [return: bb30, unwind: bb22]; + } + + bb32: { + _23 = &mut ((*_3).1: AsyncInt); + _22 = Pin::<&mut AsyncInt>::new_unchecked(move _23) -> [return: bb31, unwind: bb5]; + } + + bb33: { + StorageDead(_24); + goto -> bb3; + } + + bb34: { + StorageDead(_24); + goto -> bb1; + } + + bb35 (cleanup): { + StorageDead(_24); + goto -> bb2; + } + + bb36: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb36, unwind: bb35]; + } + + bb37: { + _2 = move _25; + StorageDead(_25); + goto -> bb36; + } + + bb38: { + _2 = move _25; + StorageDead(_25); + goto -> bb43; + } + + bb39: { + StorageLive(_25); + _25 = yield(const ()) -> [resume: bb37, drop: bb38]; + } + + bb40: { + _27 = discriminant(_26); + switchInt(move _27) -> [0: bb34, 1: bb39, otherwise: bb13]; + } + + bb41: { + _26 = as Future>::poll(move _28, move _29) -> [return: bb40, unwind: bb35]; + } + + bb42: { + _30 = move _2; + _29 = std::future::get_context::<'_, '_>(move _30) -> [return: bb41, unwind: bb35]; + } + + bb43: { + _31 = &mut _24; + _28 = Pin::<&mut impl Future>::new_unchecked(move _31) -> [return: bb42, unwind: bb35]; + } + + bb44: { + _2 = move _32; + StorageDead(_32); + goto -> bb50; + } + + bb45: { + _2 = move _32; + StorageDead(_32); + goto -> bb43; + } + + bb46: { + StorageLive(_32); + _32 = yield(const ()) -> [resume: bb44, drop: bb45]; + } + + bb47: { + _34 = discriminant(_33); + switchInt(move _34) -> [0: bb33, 1: bb46, otherwise: bb13]; + } + + bb48: { + _33 = as Future>::poll(move _35, move _36) -> [return: bb47, unwind: bb35]; + } + + bb49: { + _37 = move _2; + _36 = std::future::get_context::<'_, '_>(move _37) -> [return: bb48, unwind: bb35]; + } + + bb50: { + _38 = &mut _24; + _35 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb49, unwind: bb35]; + } + + bb51: { + StorageLive(_24); + _24 = async_drop_in_place::(copy (_39.0: &mut AsyncInt)) -> [return: bb50, unwind: bb35]; + } + + bb52: { + _40 = &mut ((*_3).3: AsyncInt); + _39 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb51, unwind: bb2]; + } + + bb53: { + drop(((*_3).2: SyncInt)) -> [return: bb52, unwind: bb4]; + } + + bb54: { + StorageDead(_41); + goto -> bb53; + } + + bb55: { + StorageDead(_41); + goto -> bb20; + } + + bb56 (cleanup): { + StorageDead(_41); + goto -> bb5; + } + + bb57: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb57, unwind: bb56]; + } + + bb58: { + _2 = move _42; + StorageDead(_42); + goto -> bb57; + } + + bb59: { + _2 = move _42; + StorageDead(_42); + goto -> bb64; + } + + bb60: { + StorageLive(_42); + _42 = yield(const ()) -> [resume: bb58, drop: bb59]; + } + + bb61: { + _44 = discriminant(_43); + switchInt(move _44) -> [0: bb55, 1: bb60, otherwise: bb13]; + } + + bb62: { + _43 = as Future>::poll(move _45, move _46) -> [return: bb61, unwind: bb56]; + } + + bb63: { + _47 = move _2; + _46 = std::future::get_context::<'_, '_>(move _47) -> [return: bb62, unwind: bb56]; + } + + bb64: { + _48 = &mut _41; + _45 = Pin::<&mut impl Future>::new_unchecked(move _48) -> [return: bb63, unwind: bb56]; + } + + bb65: { + _2 = move _49; + StorageDead(_49); + goto -> bb71; + } + + bb66: { + _2 = move _49; + StorageDead(_49); + goto -> bb64; + } + + bb67: { + StorageLive(_49); + _49 = yield(const ()) -> [resume: bb65, drop: bb66]; + } + + bb68: { + _51 = discriminant(_50); + switchInt(move _51) -> [0: bb54, 1: bb67, otherwise: bb13]; + } + + bb69: { + _50 = as Future>::poll(move _52, move _53) -> [return: bb68, unwind: bb56]; + } + + bb70: { + _54 = move _2; + _53 = std::future::get_context::<'_, '_>(move _54) -> [return: bb69, unwind: bb56]; + } + + bb71: { + _55 = &mut _41; + _52 = Pin::<&mut impl Future>::new_unchecked(move _55) -> [return: bb70, unwind: bb56]; + } + + bb72: { + StorageLive(_41); + _41 = async_drop_in_place::(copy (_56.0: &mut AsyncInt)) -> [return: bb71, unwind: bb56]; + } + + bb73: { + _57 = &mut ((*_3).1: AsyncInt); + _56 = Pin::<&mut AsyncInt>::new_unchecked(move _57) -> [return: bb72, unwind: bb5]; + } + + bb74: { + _58 = &mut (*_3); + _59 = ::drop(move _58) -> [return: bb73, unwind: bb6]; } } diff --git a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff index d706d27e83238..1247a7f995101 100644 --- a/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.SyncThenAsync.StateTransform.diff @@ -26,280 +26,481 @@ + let mut _0: std::task::Poll<()>; let mut _3: &mut SyncThenAsync; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut AsyncInt>; - let mut _6: &mut AsyncInt; - let mut _7: impl std::future::Future; - let mut _8: std::pin::Pin<&mut AsyncInt>; - let mut _9: &mut AsyncInt; - let mut _10: impl std::future::Future; - let mut _11: std::pin::Pin<&mut AsyncInt>; - let mut _12: &mut AsyncInt; - let mut _13: impl std::future::Future; - let mut _14: std::pin::Pin<&mut AsyncInt>; - let mut _15: &mut AsyncInt; - let mut _16: &mut SyncThenAsync; - let mut _17: (); -+ let mut _18: std::task::Poll<()>; -+ let mut _19: &mut std::task::Context<'_>; -+ let mut _20: &mut impl std::future::Future; -+ let mut _21: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _22: isize; -+ let mut _23: std::task::Poll<()>; -+ let mut _24: &mut std::task::Context<'_>; -+ let mut _25: &mut impl std::future::Future; -+ let mut _26: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _27: isize; -+ let mut _28: &mut std::task::Context<'_>; -+ let mut _29: &mut impl std::future::Future; -+ let mut _30: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _31: isize; -+ let mut _32: std::task::Poll<()>; -+ let mut _33: &mut std::task::Context<'_>; -+ let mut _34: &mut impl std::future::Future; -+ let mut _35: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _36: isize; +- let mut _5: std::future::ResumeTy; ++ let mut _5: &mut std::task::Context<'_>; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; +- let mut _10: std::future::ResumeTy; ++ let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut AsyncInt>; + let mut _13: &mut AsyncInt; + let mut _14: impl std::future::Future; + let mut _15: std::future::ResumeTy; + let mut _16: std::task::Poll<()>; + let mut _17: isize; + let mut _18: std::pin::Pin<&mut impl std::future::Future>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: std::future::ResumeTy; + let mut _21: &mut impl std::future::Future; + let mut _22: std::pin::Pin<&mut AsyncInt>; + let mut _23: &mut AsyncInt; + let mut _24: impl std::future::Future; +- let mut _25: std::future::ResumeTy; ++ let mut _25: &mut std::task::Context<'_>; + let mut _26: std::task::Poll<()>; + let mut _27: isize; + let mut _28: std::pin::Pin<&mut impl std::future::Future>; + let mut _29: &mut std::task::Context<'_>; +- let mut _30: std::future::ResumeTy; ++ let mut _30: &mut std::task::Context<'_>; + let mut _31: &mut impl std::future::Future; +- let mut _32: std::future::ResumeTy; ++ let mut _32: &mut std::task::Context<'_>; + let mut _33: std::task::Poll<()>; + let mut _34: isize; + let mut _35: std::pin::Pin<&mut impl std::future::Future>; + let mut _36: &mut std::task::Context<'_>; +- let mut _37: std::future::ResumeTy; + let mut _37: &mut std::task::Context<'_>; -+ let mut _38: &mut impl std::future::Future; -+ let mut _39: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _40: isize; -+ let mut _41: (); -+ let mut _42: u32; -+ let mut _43: &mut {async fn body of std::future::async_drop_in_place()}; -+ let mut _44: &mut SyncThenAsync; -+ let mut _45: &mut SyncThenAsync; -+ let mut _46: &mut SyncThenAsync; -+ let mut _47: &mut SyncThenAsync; -+ let mut _48: &mut SyncThenAsync; -+ let mut _49: &mut SyncThenAsync; -+ let mut _50: &mut SyncThenAsync; + let mut _38: &mut impl std::future::Future; + let mut _39: std::pin::Pin<&mut AsyncInt>; + let mut _40: &mut AsyncInt; + let mut _41: impl std::future::Future; +- let mut _42: std::future::ResumeTy; ++ let mut _42: &mut std::task::Context<'_>; + let mut _43: std::task::Poll<()>; + let mut _44: isize; + let mut _45: std::pin::Pin<&mut impl std::future::Future>; + let mut _46: &mut std::task::Context<'_>; +- let mut _47: std::future::ResumeTy; ++ let mut _47: &mut std::task::Context<'_>; + let mut _48: &mut impl std::future::Future; +- let mut _49: std::future::ResumeTy; ++ let mut _49: &mut std::task::Context<'_>; + let mut _50: std::task::Poll<()>; + let mut _51: isize; + let mut _52: std::pin::Pin<&mut impl std::future::Future>; + let mut _53: &mut std::task::Context<'_>; +- let mut _54: std::future::ResumeTy; ++ let mut _54: &mut std::task::Context<'_>; + let mut _55: &mut impl std::future::Future; + let mut _56: std::pin::Pin<&mut AsyncInt>; + let mut _57: &mut AsyncInt; + let mut _58: &mut SyncThenAsync; + let mut _59: (); ++ let mut _60: (); ++ let mut _61: u32; ++ let mut _62: &mut {async fn body of std::future::async_drop_in_place()}; ++ let mut _63: &mut SyncThenAsync; ++ let mut _64: &mut SyncThenAsync; ++ let mut _65: &mut SyncThenAsync; ++ let mut _66: &mut SyncThenAsync; ++ let mut _67: &mut SyncThenAsync; ++ let mut _68: &mut SyncThenAsync; ++ let mut _69: &mut SyncThenAsync; bb0: { - _3 = move (_1.0: &mut SyncThenAsync); -- _16 = &mut (*_3); -- _17 = ::drop(move _16) -> [return: bb22, unwind: bb5]; -+ _43 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); -+ _42 = discriminant((*_43)); -+ switchInt(move _42) -> [0: bb36, 1: bb35, 2: bb34, 3: bb29, 4: bb30, 5: bb31, 6: bb32, 7: bb33, otherwise: bb19]; +- _58 = &mut (*_3); +- _59 = ::drop(move _58) -> [return: bb58, unwind: bb5]; ++ _62 = copy (_1.0: &mut {async fn body of std::future::async_drop_in_place()}); ++ _61 = discriminant((*_62)); ++ switchInt(move _61) -> [0: bb42, 1: bb41, 2: bb40, 3: bb35, 4: bb36, 5: bb37, 6: bb38, 7: bb39, otherwise: bb9]; } bb1: { -+ _0 = Poll::<()>::Ready(move _41); -+ discriminant((*_43)) = 1; ++ _0 = Poll::<()>::Ready(move _60); ++ discriminant((*_62)) = 1; return; } bb2 (cleanup): { - resume; -+ goto -> bb28; ++ goto -> bb34; } bb3 (cleanup): { - drop(((*_3).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; -+ _44 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_44).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; ++ _63 = no_retag copy (((*_62) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_63).3: AsyncInt)) -> [return: bb2, unwind terminate(cleanup)]; } bb4 (cleanup): { - drop(((*_3).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; -+ _45 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_45).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; ++ _64 = no_retag copy (((*_62) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_64).2: SyncInt)) -> [return: bb3, unwind terminate(cleanup)]; } bb5 (cleanup): { - drop(((*_3).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; -+ _46 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_46).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; ++ _65 = no_retag copy (((*_62) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_65).1: AsyncInt)) -> [return: bb4, unwind terminate(cleanup)]; } - bb6: { +- bb6: { - StorageDead(_4); +- goto -> bb1; ++ bb6 (cleanup): { + nop; - goto -> bb1; ++ goto -> bb2; } - bb7 (cleanup): { +- bb7 (cleanup): { - StorageDead(_4); -+ nop; - goto -> bb2; +- goto -> bb2; ++ bb7: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb7, unwind: bb6]; } bb8: { -- async drop(((*_3).3: AsyncInt); poll=_4) -> [return: bb6, unwind: bb7]; -+ _24 = move _2; -+ goto -> bb18; +- assert(const false, "`async fn` resumed after async drop") -> [success: bb8, unwind: bb7]; ++ _2 = move _5; ++ StorageDead(_5); ++ goto -> bb7; } bb9: { -- StorageLive(_4); -- _4 = async_drop_in_place::(copy (_5.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7]; -+ nop; -+ (((*_43) as variant#5).0: impl std::future::Future) = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7]; +- _2 = move _5; +- StorageDead(_5); +- goto -> bb8; ++ unreachable; } bb10: { -- _6 = &mut ((*_3).3: AsyncInt); -- _5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb2]; -+ _47 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); -+ _12 = &mut ((*_47).3: AsyncInt); -+ _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb9, unwind: bb2]; +- _2 = move _5; +- StorageDead(_5); +- goto -> bb16; ++ nop; ++ goto -> bb1; } - bb11: { -- StorageDead(_10); -- goto -> bb1; +- bb11: { +- StorageLive(_5); +- _5 = yield(const ()) -> [resume: bb9, drop: bb10]; ++ bb11 (cleanup): { + nop; -+ _48 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); -+ drop(((*_48).2: SyncInt)) -> [return: bb10, unwind: bb3]; ++ goto -> bb2; } -- bb12: { -- StorageDead(_10); -- goto -> bb1; -+ bb12 (cleanup): { -+ nop; -+ goto -> bb4; + bb12: { +- unreachable; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb12, unwind: bb11]; } -- bb13 (cleanup): { -- StorageDead(_10); -- goto -> bb2; -+ bb13: { -+ _33 = move _2; -+ goto -> bb24; + bb13: { +- _7 = discriminant(_6); +- switchInt(move _7) -> [0: bb6, 1: bb11, otherwise: bb12]; ++ _2 = move _25; ++ StorageDead(_25); ++ goto -> bb12; } bb14: { -- async drop(((*_3).3: AsyncInt); poll=_10) -> [return: bb11, unwind: bb13, drop: bb12]; -+ nop; -+ (((*_43) as variant#7).1: impl std::future::Future) = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb13, unwind: bb12]; +- _6 = as Future>::poll(move _8, move _9) -> [return: bb13, unwind: bb7]; ++ _2 = move _32; ++ StorageDead(_32); ++ goto -> bb19; } bb15: { -- StorageLive(_10); -- _10 = async_drop_in_place::(copy (_11.0: &mut AsyncInt)) -> [return: bb14, unwind: bb13]; -+ _49 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); -+ _15 = &mut ((*_49).1: AsyncInt); -+ _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb14, unwind: bb4]; +- _10 = move _2; +- _9 = std::future::get_context::<'_, '_>(move _10) -> [return: bb14, unwind: bb7]; ++ StorageLive(_32); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_32); ++ discriminant((*_62)) = 5; ++ return; } bb16: { -- _12 = &mut ((*_3).3: AsyncInt); -- _11 = Pin::<&mut AsyncInt>::new_unchecked(move _12) -> [return: bb15, unwind: bb2]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb16, unwind: bb28]; +- _11 = &mut _4; +- _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb15, unwind: bb7]; ++ _34 = discriminant(_33); ++ switchInt(move _34) -> [0: bb10, 1: bb15, otherwise: bb9]; } bb17: { -- StorageDead(_13); -- drop(((*_3).2: SyncInt)) -> [return: bb16, unwind: bb3]; -+ _0 = Poll::<()>::Pending; -+ discriminant((*_43)) = 4; -+ return; +- StorageLive(_4); +- _4 = async_drop_in_place::(copy (_12.0: &mut AsyncInt)) -> [return: bb16, unwind: bb7]; ++ _33 = as Future>::poll(move _35, move _36) -> [return: bb16, unwind: bb11]; } bb18: { -- StorageDead(_13); -- drop(((*_3).2: SyncInt)) -> [return: bb10, unwind: bb3]; -+ StorageLive(_26); -+ _25 = &mut (((*_43) as variant#5).0: impl std::future::Future); -+ _26 = Pin::<&mut impl Future>::new_unchecked(move _25) -> [return: bb21, unwind: bb28]; +- _13 = &mut ((*_3).3: AsyncInt); +- _12 = Pin::<&mut AsyncInt>::new_unchecked(move _13) -> [return: bb17, unwind: bb2]; ++ _37 = move _2; ++ _36 = move _37; ++ goto -> bb17; } -- bb19 (cleanup): { -- StorageDead(_13); -- goto -> bb4; -+ bb19: { -+ unreachable; + bb19: { +- StorageDead(_24); +- goto -> bb1; ++ _38 = &mut (((*_62) as variant#5).0: impl std::future::Future); ++ _35 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb18, unwind: bb11]; } bb20: { -- async drop(((*_3).1: AsyncInt); poll=_13) -> [return: bb17, unwind: bb19, drop: bb18]; -+ StorageDead(_26); -+ _27 = discriminant(_23); -+ switchInt(move _27) -> [0: bb6, 1: bb17, otherwise: bb19]; +- StorageDead(_24); +- goto -> bb1; ++ nop; ++ (((*_62) as variant#5).0: impl std::future::Future) = async_drop_in_place::(copy (_39.0: &mut AsyncInt)) -> [return: bb19, unwind: bb11]; } - bb21: { -- StorageLive(_13); -- _13 = async_drop_in_place::(copy (_14.0: &mut AsyncInt)) -> [return: bb20, unwind: bb19]; -+ _23 = as Future>::poll(move _26, move _24) -> [return: bb20, unwind: bb7]; +- bb21 (cleanup): { +- StorageDead(_24); +- goto -> bb2; ++ bb21: { ++ _66 = no_retag copy (((*_62) as variant#7).0: &mut SyncThenAsync); ++ _40 = &mut ((*_66).3: AsyncInt); ++ _39 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb20, unwind: bb2]; } bb22: { -- _15 = &mut ((*_3).1: AsyncInt); -- _14 = Pin::<&mut AsyncInt>::new_unchecked(move _15) -> [return: bb21, unwind: bb4]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb28]; -+ } -+ -+ bb23: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb21]; ++ nop; ++ _67 = no_retag copy (((*_62) as variant#7).0: &mut SyncThenAsync); ++ drop(((*_67).2: SyncInt)) -> [return: bb21, unwind: bb3]; + } + +- bb23: { +- _2 = move _25; +- StorageDead(_25); +- goto -> bb22; ++ bb23 (cleanup): { ++ nop; ++ goto -> bb4; + } + + bb24: { +- _2 = move _25; +- StorageDead(_25); +- goto -> bb29; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb24, unwind: bb23]; + } + + bb25: { +- StorageLive(_25); +- _25 = yield(const ()) -> [resume: bb23, drop: bb24]; ++ _2 = move _42; ++ StorageDead(_42); ++ goto -> bb24; + } + + bb26: { +- _27 = discriminant(_26); +- switchInt(move _27) -> [0: bb20, 1: bb25, otherwise: bb12]; ++ _2 = move _49; ++ StorageDead(_49); ++ goto -> bb31; + } + + bb27: { +- _26 = as Future>::poll(move _28, move _29) -> [return: bb26, unwind: bb21]; ++ StorageLive(_49); + _0 = Poll::<()>::Pending; -+ discriminant((*_43)) = 6; ++ StorageDead(_49); ++ discriminant((*_62)) = 7; + return; -+ } -+ -+ bb24: { -+ StorageLive(_35); -+ _34 = &mut (((*_43) as variant#7).1: impl std::future::Future); -+ _35 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb26, unwind: bb28]; -+ } -+ -+ bb25: { -+ StorageDead(_35); -+ _36 = discriminant(_32); -+ switchInt(move _36) -> [0: bb11, 1: bb23, otherwise: bb19]; -+ } -+ -+ bb26: { -+ _32 = as Future>::poll(move _35, move _33) -> [return: bb25, unwind: bb12]; -+ } -+ -+ bb27: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb27, unwind: bb28]; -+ } -+ -+ bb28 (cleanup): { -+ discriminant((*_43)) = 2; + } + + bb28: { +- _30 = move _2; +- _29 = std::future::get_context::<'_, '_>(move _30) -> [return: bb27, unwind: bb21]; ++ _51 = discriminant(_50); ++ switchInt(move _51) -> [0: bb22, 1: bb27, otherwise: bb9]; + } + + bb29: { +- _31 = &mut _24; +- _28 = Pin::<&mut impl Future>::new_unchecked(move _31) -> [return: bb28, unwind: bb21]; ++ _50 = as Future>::poll(move _52, move _53) -> [return: bb28, unwind: bb23]; + } + + bb30: { +- _2 = move _32; +- StorageDead(_32); +- goto -> bb36; ++ _54 = move _2; ++ _53 = move _54; ++ goto -> bb29; + } + + bb31: { +- _2 = move _32; +- StorageDead(_32); +- goto -> bb29; ++ _55 = &mut (((*_62) as variant#7).1: impl std::future::Future); ++ _52 = Pin::<&mut impl Future>::new_unchecked(move _55) -> [return: bb30, unwind: bb23]; + } + + bb32: { +- StorageLive(_32); +- _32 = yield(const ()) -> [resume: bb30, drop: bb31]; ++ nop; ++ (((*_62) as variant#7).1: impl std::future::Future) = async_drop_in_place::(copy (_56.0: &mut AsyncInt)) -> [return: bb31, unwind: bb23]; + } + + bb33: { +- _34 = discriminant(_33); +- switchInt(move _34) -> [0: bb19, 1: bb32, otherwise: bb12]; ++ _68 = no_retag copy (((*_62) as variant#7).0: &mut SyncThenAsync); ++ _57 = &mut ((*_68).1: AsyncInt); ++ _56 = Pin::<&mut AsyncInt>::new_unchecked(move _57) -> [return: bb32, unwind: bb4]; + } + +- bb34: { +- _33 = as Future>::poll(move _35, move _36) -> [return: bb33, unwind: bb21]; ++ bb34 (cleanup): { ++ discriminant((*_62)) = 2; + resume; -+ } -+ -+ bb29: { -+ _19 = move _2; -+ goto -> bb16; -+ } -+ -+ bb30: { -+ _24 = move _2; -+ goto -> bb18; -+ } -+ -+ bb31: { -+ _28 = move _2; -+ goto -> bb22; -+ } -+ -+ bb32: { -+ _33 = move _2; -+ goto -> bb24; -+ } -+ -+ bb33: { -+ _37 = move _2; -+ goto -> bb27; -+ } -+ -+ bb34: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb34, unwind continue]; -+ } -+ -+ bb35: { + } + + bb35: { +- _37 = move _2; +- _36 = std::future::get_context::<'_, '_>(move _37) -> [return: bb34, unwind: bb21]; ++ StorageLive(_5); ++ _5 = move _2; ++ goto -> bb8; + } + + bb36: { +- _38 = &mut _24; +- _35 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb35, unwind: bb21]; ++ StorageLive(_25); ++ _25 = move _2; ++ goto -> bb13; + } + + bb37: { +- StorageLive(_24); +- _24 = async_drop_in_place::(copy (_39.0: &mut AsyncInt)) -> [return: bb36, unwind: bb21]; ++ StorageLive(_32); ++ _32 = move _2; ++ goto -> bb14; + } + + bb38: { +- _40 = &mut ((*_3).3: AsyncInt); +- _39 = Pin::<&mut AsyncInt>::new_unchecked(move _40) -> [return: bb37, unwind: bb2]; ++ StorageLive(_42); ++ _42 = move _2; ++ goto -> bb25; + } + + bb39: { +- StorageDead(_41); +- drop(((*_3).2: SyncInt)) -> [return: bb38, unwind: bb3]; ++ StorageLive(_49); ++ _49 = move _2; ++ goto -> bb26; + } + + bb40: { +- StorageDead(_41); +- drop(((*_3).2: SyncInt)) -> [return: bb18, unwind: bb3]; ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb40, unwind continue]; + } + +- bb41 (cleanup): { +- StorageDead(_41); +- goto -> bb4; ++ bb41: { + _0 = Poll::<()>::Ready(const ()); + return; -+ } -+ -+ bb36: { -+ (((*_43) as variant#7).0: &mut SyncThenAsync) = move ((*_43).0: &mut SyncThenAsync); -+ _50 = no_retag copy (((*_43) as variant#7).0: &mut SyncThenAsync); -+ _16 = &mut (*_50); -+ _17 = ::drop(move _16) -> [return: bb15, unwind: bb5]; + } + + bb42: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb42, unwind: bb41]; +- } +- +- bb43: { +- _2 = move _42; +- StorageDead(_42); +- goto -> bb42; +- } +- +- bb44: { +- _2 = move _42; +- StorageDead(_42); +- goto -> bb49; +- } +- +- bb45: { +- StorageLive(_42); +- _42 = yield(const ()) -> [resume: bb43, drop: bb44]; +- } +- +- bb46: { +- _44 = discriminant(_43); +- switchInt(move _44) -> [0: bb40, 1: bb45, otherwise: bb12]; +- } +- +- bb47: { +- _43 = as Future>::poll(move _45, move _46) -> [return: bb46, unwind: bb41]; +- } +- +- bb48: { +- _47 = move _2; +- _46 = std::future::get_context::<'_, '_>(move _47) -> [return: bb47, unwind: bb41]; +- } +- +- bb49: { +- _48 = &mut _41; +- _45 = Pin::<&mut impl Future>::new_unchecked(move _48) -> [return: bb48, unwind: bb41]; +- } +- +- bb50: { +- _2 = move _49; +- StorageDead(_49); +- goto -> bb56; +- } +- +- bb51: { +- _2 = move _49; +- StorageDead(_49); +- goto -> bb49; +- } +- +- bb52: { +- StorageLive(_49); +- _49 = yield(const ()) -> [resume: bb50, drop: bb51]; +- } +- +- bb53: { +- _51 = discriminant(_50); +- switchInt(move _51) -> [0: bb39, 1: bb52, otherwise: bb12]; +- } +- +- bb54: { +- _50 = as Future>::poll(move _52, move _53) -> [return: bb53, unwind: bb41]; +- } +- +- bb55: { +- _54 = move _2; +- _53 = std::future::get_context::<'_, '_>(move _54) -> [return: bb54, unwind: bb41]; +- } +- +- bb56: { +- _55 = &mut _41; +- _52 = Pin::<&mut impl Future>::new_unchecked(move _55) -> [return: bb55, unwind: bb41]; +- } +- +- bb57: { +- StorageLive(_41); +- _41 = async_drop_in_place::(copy (_56.0: &mut AsyncInt)) -> [return: bb56, unwind: bb41]; +- } +- +- bb58: { +- _57 = &mut ((*_3).1: AsyncInt); +- _56 = Pin::<&mut AsyncInt>::new_unchecked(move _57) -> [return: bb57, unwind: bb4]; ++ (((*_62) as variant#7).0: &mut SyncThenAsync) = move ((*_62).0: &mut SyncThenAsync); ++ _69 = no_retag copy (((*_62) as variant#7).0: &mut SyncThenAsync); ++ _58 = &mut (*_69); ++ _59 = ::drop(move _58) -> [return: bb33, unwind: bb5]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff index f7df7875c0fb0..b11d65b4da8b8 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.ElaborateDrops.diff @@ -8,14 +8,39 @@ let mut _0: (); let _3: SyncInt; + let mut _6: impl std::future::Future; -+ let mut _7: std::pin::Pin<&mut AsyncInt>; -+ let mut _8: &mut AsyncInt; -+ let mut _9: impl std::future::Future; -+ let mut _10: std::pin::Pin<&mut AsyncInt>; -+ let mut _11: &mut AsyncInt; -+ let mut _12: impl std::future::Future; -+ let mut _13: std::pin::Pin<&mut {async fn body of double()}>; -+ let mut _14: &mut {async fn body of double()}; ++ let mut _7: std::future::ResumeTy; ++ let mut _8: std::task::Poll<()>; ++ let mut _9: isize; ++ let mut _10: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _11: &mut std::task::Context<'_>; ++ let mut _12: std::future::ResumeTy; ++ let mut _13: &mut impl std::future::Future; ++ let mut _14: std::future::ResumeTy; ++ let mut _15: std::task::Poll<()>; ++ let mut _16: isize; ++ let mut _17: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _18: &mut std::task::Context<'_>; ++ let mut _19: std::future::ResumeTy; ++ let mut _20: &mut impl std::future::Future; ++ let mut _21: std::pin::Pin<&mut AsyncInt>; ++ let mut _22: &mut AsyncInt; ++ let mut _23: impl std::future::Future; ++ let mut _24: std::future::ResumeTy; ++ let mut _25: std::task::Poll<()>; ++ let mut _26: isize; ++ let mut _27: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _28: &mut std::task::Context<'_>; ++ let mut _29: std::future::ResumeTy; ++ let mut _30: &mut impl std::future::Future; ++ let mut _31: std::future::ResumeTy; ++ let mut _32: std::task::Poll<()>; ++ let mut _33: isize; ++ let mut _34: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _35: &mut std::task::Context<'_>; ++ let mut _36: std::future::ResumeTy; ++ let mut _37: &mut impl std::future::Future; ++ let mut _38: std::pin::Pin<&mut AsyncInt>; ++ let mut _39: &mut AsyncInt; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -37,13 +62,13 @@ _5 = AsyncInt(const 0_i32); _0 = const (); - drop(_5) -> [return: bb1, unwind: bb9, drop: bb5]; -+ goto -> bb20; ++ goto -> bb35; } bb1: { StorageDead(_5); - drop(_4) -> [return: bb2, unwind: bb10, drop: bb6]; -+ goto -> bb26; ++ goto -> bb55; } bb2: { @@ -54,7 +79,7 @@ bb3: { StorageDead(_3); - drop(_1) -> [return: bb4, drop: bb8, unwind continue]; -+ goto -> bb32; ++ drop(_1) -> [return: bb4, unwind: bb12]; } bb4: { @@ -130,75 +155,194 @@ + } + + bb18: { -+ async drop(_5; poll=_6) -> [return: bb15, unwind: bb17, drop: bb16]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb18, unwind: bb17]; + } + + bb19: { -+ StorageLive(_6); -+ _6 = async_drop_in_place::(copy (_7.0: &mut AsyncInt)) -> [return: bb18, unwind: bb17]; ++ _2 = move _7; ++ StorageDead(_7); ++ goto -> bb18; + } + + bb20: { -+ _8 = &mut _5; -+ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _8) -> [return: bb19, unwind: bb9]; ++ _2 = move _7; ++ StorageDead(_7); ++ goto -> bb26; + } + + bb21: { -+ StorageDead(_9); -+ goto -> bb2; ++ StorageLive(_7); ++ _7 = yield(const ()) -> [resume: bb19, drop: bb20]; + } + + bb22: { -+ StorageDead(_9); -+ goto -> bb6; ++ unreachable; + } + -+ bb23 (cleanup): { -+ StorageDead(_9); -+ goto -> bb10; ++ bb23: { ++ _9 = discriminant(_8); ++ switchInt(move _9) -> [0: bb16, 1: bb21, otherwise: bb22]; + } + + bb24: { -+ async drop(_4; poll=_9) -> [return: bb21, unwind: bb23, drop: bb22]; ++ _8 = as Future>::poll(move _10, move _11) -> [return: bb23, unwind: bb17]; + } + + bb25: { -+ StorageLive(_9); -+ _9 = async_drop_in_place::(copy (_10.0: &mut AsyncInt)) -> [return: bb24, unwind: bb23]; ++ _12 = move _2; ++ _11 = std::future::get_context::<'_, '_>(move _12) -> [return: bb24, unwind: bb17]; + } + + bb26: { -+ _11 = &mut _4; -+ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb25, unwind: bb10]; ++ _13 = &mut _6; ++ _10 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb25, unwind: bb17]; + } + + bb27: { -+ StorageDead(_12); -+ goto -> bb4; ++ _2 = move _14; ++ StorageDead(_14); ++ goto -> bb33; + } + + bb28: { -+ StorageDead(_12); -+ goto -> bb8; ++ _2 = move _14; ++ StorageDead(_14); ++ goto -> bb26; + } + -+ bb29 (cleanup): { -+ StorageDead(_12); -+ goto -> bb12; ++ bb29: { ++ StorageLive(_14); ++ _14 = yield(const ()) -> [resume: bb27, drop: bb28]; + } + + bb30: { -+ async drop(_1; poll=_12) -> [return: bb27, unwind: bb29, drop: bb28]; ++ _16 = discriminant(_15); ++ switchInt(move _16) -> [0: bb15, 1: bb29, otherwise: bb22]; + } + + bb31: { -+ StorageLive(_12); -+ _12 = async_drop_in_place::<{async fn body of double()}>(copy (_13.0: &mut {async fn body of double()})) -> [return: bb30, unwind: bb29]; ++ _15 = as Future>::poll(move _17, move _18) -> [return: bb30, unwind: bb17]; + } + + bb32: { -+ _14 = &mut _1; -+ _13 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _14) -> [return: bb31, unwind: bb12]; ++ _19 = move _2; ++ _18 = std::future::get_context::<'_, '_>(move _19) -> [return: bb31, unwind: bb17]; ++ } ++ ++ bb33: { ++ _20 = &mut _6; ++ _17 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb32, unwind: bb17]; ++ } ++ ++ bb34: { ++ StorageLive(_6); ++ _6 = async_drop_in_place::(copy (_21.0: &mut AsyncInt)) -> [return: bb33, unwind: bb17]; ++ } ++ ++ bb35: { ++ _22 = &mut _5; ++ _21 = Pin::<&mut AsyncInt>::new_unchecked(move _22) -> [return: bb34, unwind: bb9]; ++ } ++ ++ bb36: { ++ StorageDead(_23); ++ goto -> bb2; ++ } ++ ++ bb37: { ++ StorageDead(_23); ++ goto -> bb6; ++ } ++ ++ bb38 (cleanup): { ++ StorageDead(_23); ++ goto -> bb10; ++ } ++ ++ bb39: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb39, unwind: bb38]; ++ } ++ ++ bb40: { ++ _2 = move _24; ++ StorageDead(_24); ++ goto -> bb39; ++ } ++ ++ bb41: { ++ _2 = move _24; ++ StorageDead(_24); ++ goto -> bb46; ++ } ++ ++ bb42: { ++ StorageLive(_24); ++ _24 = yield(const ()) -> [resume: bb40, drop: bb41]; ++ } ++ ++ bb43: { ++ _26 = discriminant(_25); ++ switchInt(move _26) -> [0: bb37, 1: bb42, otherwise: bb22]; ++ } ++ ++ bb44: { ++ _25 = as Future>::poll(move _27, move _28) -> [return: bb43, unwind: bb38]; ++ } ++ ++ bb45: { ++ _29 = move _2; ++ _28 = std::future::get_context::<'_, '_>(move _29) -> [return: bb44, unwind: bb38]; ++ } ++ ++ bb46: { ++ _30 = &mut _23; ++ _27 = Pin::<&mut impl Future>::new_unchecked(move _30) -> [return: bb45, unwind: bb38]; ++ } ++ ++ bb47: { ++ _2 = move _31; ++ StorageDead(_31); ++ goto -> bb53; ++ } ++ ++ bb48: { ++ _2 = move _31; ++ StorageDead(_31); ++ goto -> bb46; ++ } ++ ++ bb49: { ++ StorageLive(_31); ++ _31 = yield(const ()) -> [resume: bb47, drop: bb48]; ++ } ++ ++ bb50: { ++ _33 = discriminant(_32); ++ switchInt(move _33) -> [0: bb36, 1: bb49, otherwise: bb22]; ++ } ++ ++ bb51: { ++ _32 = as Future>::poll(move _34, move _35) -> [return: bb50, unwind: bb38]; ++ } ++ ++ bb52: { ++ _36 = move _2; ++ _35 = std::future::get_context::<'_, '_>(move _36) -> [return: bb51, unwind: bb38]; ++ } ++ ++ bb53: { ++ _37 = &mut _23; ++ _34 = Pin::<&mut impl Future>::new_unchecked(move _37) -> [return: bb52, unwind: bb38]; ++ } ++ ++ bb54: { ++ StorageLive(_23); ++ _23 = async_drop_in_place::(copy (_38.0: &mut AsyncInt)) -> [return: bb53, unwind: bb38]; ++ } ++ ++ bb55: { ++ _39 = &mut _4; ++ _38 = Pin::<&mut AsyncInt>::new_unchecked(move _39) -> [return: bb54, unwind: bb10]; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff index 14cb91c056b96..b59d810d5366a 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.StateTransform.diff @@ -16,10 +16,10 @@ + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], -+ Suspend0 (3): [_s0, _s1, _s2, _s3, _s4], -+ Suspend1 (4): [_s1, _s2, _s3, _s4], -+ Suspend2 (5): [_s0, _s1, _s2, _s5], -+ Suspend3 (6): [_s1, _s2, _s5], ++ Suspend0 (3): [_s1, _s2, _s3, _s4], ++ Suspend1 (4): [_s0, _s1, _s2, _s3, _s4], ++ Suspend2 (5): [_s1, _s2, _s5], ++ Suspend3 (6): [_s0, _s1, _s2, _s5], + } + storage_conflicts = BitMatrix(6x6) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s0, _s4), (_s0, _s5), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s1, _s4), (_s1, _s5), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s2, _s4), (_s2, _s5), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3), (_s3, _s4), (_s4, _s0), (_s4, _s1), (_s4, _s2), (_s4, _s3), (_s4, _s4), (_s5, _s0), (_s5, _s1), (_s5, _s2), (_s5, _s5)} + } @@ -29,48 +29,63 @@ + let mut _0: std::task::Poll<()>; let _3: SyncInt; let mut _6: impl std::future::Future; - let mut _7: std::pin::Pin<&mut AsyncInt>; - let mut _8: &mut AsyncInt; - let mut _9: impl std::future::Future; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; - let mut _12: impl std::future::Future; - let mut _13: std::pin::Pin<&mut {async fn body of double()}>; - let mut _14: &mut {async fn body of double()}; -+ let mut _15: std::task::Poll<()>; -+ let mut _16: &mut std::task::Context<'_>; -+ let mut _17: &mut impl std::future::Future; -+ let mut _18: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _19: isize; -+ let mut _20: &mut std::task::Context<'_>; -+ let mut _21: &mut impl std::future::Future; -+ let mut _22: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _23: isize; -+ let mut _24: std::task::Poll<()>; -+ let mut _25: &mut std::task::Context<'_>; -+ let mut _26: &mut impl std::future::Future; -+ let mut _27: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _28: isize; +- let mut _7: std::future::ResumeTy; ++ let mut _7: &mut std::task::Context<'_>; + let mut _8: std::task::Poll<()>; + let mut _9: isize; + let mut _10: std::pin::Pin<&mut impl std::future::Future>; + let mut _11: &mut std::task::Context<'_>; +- let mut _12: std::future::ResumeTy; ++ let mut _12: &mut std::task::Context<'_>; + let mut _13: &mut impl std::future::Future; +- let mut _14: std::future::ResumeTy; ++ let mut _14: &mut std::task::Context<'_>; + let mut _15: std::task::Poll<()>; + let mut _16: isize; + let mut _17: std::pin::Pin<&mut impl std::future::Future>; + let mut _18: &mut std::task::Context<'_>; +- let mut _19: std::future::ResumeTy; ++ let mut _19: &mut std::task::Context<'_>; + let mut _20: &mut impl std::future::Future; + let mut _21: std::pin::Pin<&mut AsyncInt>; + let mut _22: &mut AsyncInt; + let mut _23: impl std::future::Future; +- let mut _24: std::future::ResumeTy; ++ let mut _24: &mut std::task::Context<'_>; + let mut _25: std::task::Poll<()>; + let mut _26: isize; + let mut _27: std::pin::Pin<&mut impl std::future::Future>; + let mut _28: &mut std::task::Context<'_>; +- let mut _29: std::future::ResumeTy; + let mut _29: &mut std::task::Context<'_>; -+ let mut _30: &mut impl std::future::Future; -+ let mut _31: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _32: isize; -+ let mut _33: (); -+ let mut _34: u32; -+ let mut _35: &mut {async fn body of double()}; + let mut _30: &mut impl std::future::Future; +- let mut _31: std::future::ResumeTy; ++ let mut _31: &mut std::task::Context<'_>; + let mut _32: std::task::Poll<()>; + let mut _33: isize; + let mut _34: std::pin::Pin<&mut impl std::future::Future>; + let mut _35: &mut std::task::Context<'_>; +- let mut _36: std::future::ResumeTy; ++ let mut _36: &mut std::task::Context<'_>; + let mut _37: &mut impl std::future::Future; + let mut _38: std::pin::Pin<&mut AsyncInt>; + let mut _39: &mut AsyncInt; ++ let mut _40: (); ++ let mut _41: u32; ++ let mut _42: &mut {async fn body of double()}; scope 1 { - debug sync_int => _3; -+ debug sync_int => (((*_35) as variant#6).0: SyncInt); ++ debug sync_int => (((*_42) as variant#6).1: SyncInt); + coroutine debug async_int => _s2; let _4: AsyncInt; scope 2 { - debug async_int => _4; -+ debug async_int => (((*_35) as variant#6).1: AsyncInt); ++ debug async_int => (((*_42) as variant#6).2: AsyncInt); + coroutine debug async_int_again => _s3; let _5: AsyncInt; scope 3 { - debug async_int_again => _5; -+ debug async_int_again => (((*_35) as variant#4).2: AsyncInt); ++ debug async_int_again => (((*_42) as variant#4).3: AsyncInt); } } } @@ -83,36 +98,36 @@ - StorageLive(_5); - _5 = AsyncInt(const 0_i32); - _0 = const (); -- goto -> bb18; -+ _35 = copy (_1.0: &mut {async fn body of double()}); -+ _34 = discriminant((*_35)); -+ switchInt(move _34) -> [0: bb43, 1: bb42, 2: bb41, 3: bb37, 4: bb38, 5: bb39, 6: bb40, otherwise: bb26]; +- goto -> bb33; ++ _42 = copy (_1.0: &mut {async fn body of double()}); ++ _41 = discriminant((*_42)); ++ switchInt(move _41) -> [0: bb42, 1: bb41, 2: bb40, 3: bb36, 4: bb37, 5: bb38, 6: bb39, otherwise: bb13]; } bb1: { - StorageDead(_5); -- goto -> bb24; +- goto -> bb53; + nop; -+ goto -> bb18; ++ goto -> bb33; } bb2: { - StorageDead(_4); - drop(_3) -> [return: bb3, unwind: bb11]; + nop; -+ drop((((*_35) as variant#6).0: SyncInt)) -> [return: bb3, unwind: bb7]; ++ drop((((*_42) as variant#6).1: SyncInt)) -> [return: bb3, unwind: bb7]; } bb3: { - StorageDead(_3); -- goto -> bb30; +- drop(_1) -> [return: bb4, unwind: bb12]; + nop; -+ goto -> bb23; ++ goto -> bb34; } bb4: { -+ _0 = Poll::<()>::Ready(move (((*_35) as variant#5).0: ())); -+ discriminant((*_35)) = 1; ++ _0 = Poll::<()>::Ready(move (((*_42) as variant#6).0: ())); ++ discriminant((*_42)) = 1; return; } @@ -121,7 +136,7 @@ - goto -> bb6; + bb5 (cleanup): { + nop; -+ drop((((*_35) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; ++ drop((((*_42) as variant#6).2: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; } - bb6: { @@ -129,7 +144,7 @@ - goto -> bb7; + bb6 (cleanup): { + nop; -+ drop((((*_35) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; ++ drop((((*_42) as variant#6).1: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; } - bb7: { @@ -142,7 +157,7 @@ - bb8: { - coroutine_drop; + bb8 (cleanup): { -+ goto -> bb36; ++ goto -> bb35; } - bb9 (cleanup): { @@ -164,209 +179,299 @@ - StorageDead(_3); - drop(_1) -> [return: bb12, unwind terminate(cleanup)]; + bb11: { -+ _16 = move _2; -+ goto -> bb25; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb11, unwind: bb10]; } - bb12 (cleanup): { - resume; + bb12: { -+ nop; -+ (((*_35) as variant#4).3: impl std::future::Future) = async_drop_in_place::(copy (_7.0: &mut AsyncInt)) -> [return: bb11, unwind: bb10]; ++ _2 = move _7; ++ StorageDead(_7); ++ goto -> bb11; } bb13: { - StorageDead(_6); - goto -> bb1; -+ _8 = &mut (((*_35) as variant#4).2: AsyncInt); -+ _7 = Pin::<&mut AsyncInt>::new_unchecked(move _8) -> [return: bb12, unwind: bb5]; ++ unreachable; } bb14: { - StorageDead(_6); - goto -> bb5; -+ nop; -+ goto -> bb2; ++ _2 = move _14; ++ StorageDead(_14); ++ goto -> bb19; } - bb15 (cleanup): { +- bb15 (cleanup): { - StorageDead(_6); - goto -> bb9; -+ nop; -+ goto -> bb6; ++ bb15: { ++ StorageLive(_14); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_14); ++ discriminant((*_42)) = 4; ++ return; } bb16: { -- async drop(_5; poll=_6) -> [return: bb13, unwind: bb15, drop: bb14]; -+ _25 = move _2; -+ goto -> bb31; +- assert(const false, "`async fn` resumed after async drop") -> [success: bb16, unwind: bb15]; ++ _16 = discriminant(_15); ++ switchInt(move _16) -> [0: bb9, 1: bb15, otherwise: bb13]; } bb17: { -- StorageLive(_6); -- _6 = async_drop_in_place::(copy (_7.0: &mut AsyncInt)) -> [return: bb16, unwind: bb15]; -+ nop; -+ (((*_35) as variant#6).2: impl std::future::Future) = async_drop_in_place::(copy (_10.0: &mut AsyncInt)) -> [return: bb16, unwind: bb15]; +- _2 = move _7; +- StorageDead(_7); +- goto -> bb16; ++ _15 = as Future>::poll(move _17, move _18) -> [return: bb16, unwind: bb10]; } bb18: { -- _8 = &mut _5; -- _7 = Pin::<&mut AsyncInt>::new_unchecked(move _8) -> [return: bb17, unwind: bb9]; -+ _11 = &mut (((*_35) as variant#6).1: AsyncInt); -+ _10 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb17, unwind: bb6]; +- _2 = move _7; +- StorageDead(_7); +- goto -> bb24; ++ _19 = move _2; ++ _18 = move _19; ++ goto -> bb17; } bb19: { -- StorageDead(_9); -- goto -> bb2; -+ StorageDead(_12); -+ goto -> bb4; +- StorageLive(_7); +- _7 = yield(const ()) -> [resume: bb17, drop: bb18]; ++ _20 = &mut (((*_42) as variant#4).4: impl std::future::Future); ++ _17 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb18, unwind: bb10]; } -- bb20: { -- StorageDead(_9); -- goto -> bb6; -+ bb20 (cleanup): { -+ StorageDead(_12); -+ goto -> bb8; + bb20: { +- unreachable; ++ nop; ++ (((*_42) as variant#4).4: impl std::future::Future) = async_drop_in_place::(copy (_21.0: &mut AsyncInt)) -> [return: bb19, unwind: bb10]; } -- bb21 (cleanup): { -- StorageDead(_9); -- goto -> bb10; -+ bb21: { -+ goto -> bb35; + bb21: { +- _9 = discriminant(_8); +- switchInt(move _9) -> [0: bb14, 1: bb19, otherwise: bb20]; ++ _22 = &mut (((*_42) as variant#4).3: AsyncInt); ++ _21 = Pin::<&mut AsyncInt>::new_unchecked(move _22) -> [return: bb20, unwind: bb5]; } bb22: { -- async drop(_4; poll=_9) -> [return: bb19, unwind: bb21, drop: bb20]; -+ StorageLive(_12); -+ _12 = async_drop_in_place::<{async fn body of double()}>(copy (_13.0: &mut {async fn body of double()})) -> [return: bb21, unwind: bb20]; +- _8 = as Future>::poll(move _10, move _11) -> [return: bb21, unwind: bb15]; ++ nop; ++ goto -> bb2; } - bb23: { -- StorageLive(_9); -- _9 = async_drop_in_place::(copy (_10.0: &mut AsyncInt)) -> [return: bb22, unwind: bb21]; -+ _14 = &mut (*_35); -+ _13 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _14) -> [return: bb22, unwind: bb8]; +- bb23: { +- _12 = move _2; +- _11 = std::future::get_context::<'_, '_>(move _12) -> [return: bb22, unwind: bb15]; ++ bb23 (cleanup): { ++ nop; ++ goto -> bb6; } bb24: { -- _11 = &mut _4; -- _10 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb23, unwind: bb10]; -+ _0 = Poll::<()>::Pending; -+ discriminant((*_35)) = 3; -+ return; +- _13 = &mut _6; +- _10 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb23, unwind: bb15]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb24, unwind: bb23]; } bb25: { -- StorageDead(_12); -- goto -> bb4; -+ StorageLive(_18); -+ _17 = &mut (((*_35) as variant#4).3: impl std::future::Future); -+ _18 = Pin::<&mut impl Future>::new_unchecked(move _17) -> [return: bb28, unwind: bb36]; +- _2 = move _14; +- StorageDead(_14); +- goto -> bb31; ++ _2 = move _24; ++ StorageDead(_24); ++ goto -> bb24; } bb26: { -- StorageDead(_12); -- goto -> bb8; -+ unreachable; +- _2 = move _14; +- StorageDead(_14); +- goto -> bb24; ++ _2 = move _31; ++ StorageDead(_31); ++ goto -> bb31; } -- bb27 (cleanup): { -- StorageDead(_12); -- goto -> bb12; -+ bb27: { -+ StorageDead(_18); -+ _19 = discriminant(_15); -+ switchInt(move _19) -> [0: bb9, 1: bb24, otherwise: bb26]; + bb27: { +- StorageLive(_14); +- _14 = yield(const ()) -> [resume: bb25, drop: bb26]; ++ StorageLive(_31); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_31); ++ discriminant((*_42)) = 6; ++ return; } bb28: { -- async drop(_1; poll=_12) -> [return: bb25, unwind: bb27, drop: bb26]; -+ _15 = as Future>::poll(move _18, move _16) -> [return: bb27, unwind: bb10]; +- _16 = discriminant(_15); +- switchInt(move _16) -> [0: bb13, 1: bb27, otherwise: bb20]; ++ _33 = discriminant(_32); ++ switchInt(move _33) -> [0: bb22, 1: bb27, otherwise: bb13]; } bb29: { -- StorageLive(_12); -- _12 = async_drop_in_place::<{async fn body of double()}>(copy (_13.0: &mut {async fn body of double()})) -> [return: bb28, unwind: bb27]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb29, unwind: bb36]; +- _15 = as Future>::poll(move _17, move _18) -> [return: bb28, unwind: bb15]; ++ _32 = as Future>::poll(move _34, move _35) -> [return: bb28, unwind: bb23]; } bb30: { -- _14 = &mut _1; -- _13 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _14) -> [return: bb29, unwind: bb12]; -+ _0 = Poll::<()>::Pending; -+ discriminant((*_35)) = 5; -+ return; -+ } -+ -+ bb31: { -+ StorageLive(_27); -+ _26 = &mut (((*_35) as variant#6).2: impl std::future::Future); -+ _27 = Pin::<&mut impl Future>::new_unchecked(move _26) -> [return: bb33, unwind: bb36]; -+ } -+ -+ bb32: { -+ StorageDead(_27); -+ _28 = discriminant(_24); -+ switchInt(move _28) -> [0: bb14, 1: bb30, otherwise: bb26]; -+ } -+ -+ bb33: { -+ _24 = as Future>::poll(move _27, move _25) -> [return: bb32, unwind: bb15]; -+ } -+ -+ bb34: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb34, unwind: bb36]; -+ } -+ -+ bb35: { -+ goto -> bb19; -+ } -+ -+ bb36 (cleanup): { -+ discriminant((*_35)) = 2; +- _19 = move _2; +- _18 = std::future::get_context::<'_, '_>(move _19) -> [return: bb29, unwind: bb15]; ++ _36 = move _2; ++ _35 = move _36; ++ goto -> bb29; + } + + bb31: { +- _20 = &mut _6; +- _17 = Pin::<&mut impl Future>::new_unchecked(move _20) -> [return: bb30, unwind: bb15]; ++ _37 = &mut (((*_42) as variant#6).3: impl std::future::Future); ++ _34 = Pin::<&mut impl Future>::new_unchecked(move _37) -> [return: bb30, unwind: bb23]; + } + + bb32: { +- StorageLive(_6); +- _6 = async_drop_in_place::(copy (_21.0: &mut AsyncInt)) -> [return: bb31, unwind: bb15]; ++ nop; ++ (((*_42) as variant#6).3: impl std::future::Future) = async_drop_in_place::(copy (_38.0: &mut AsyncInt)) -> [return: bb31, unwind: bb23]; + } + + bb33: { +- _22 = &mut _5; +- _21 = Pin::<&mut AsyncInt>::new_unchecked(move _22) -> [return: bb32, unwind: bb9]; ++ _39 = &mut (((*_42) as variant#6).2: AsyncInt); ++ _38 = Pin::<&mut AsyncInt>::new_unchecked(move _39) -> [return: bb32, unwind: bb6]; + } + + bb34: { +- StorageDead(_23); +- goto -> bb2; ++ goto -> bb4; + } + +- bb35: { +- StorageDead(_23); +- goto -> bb6; ++ bb35 (cleanup): { ++ discriminant((*_42)) = 2; + resume; -+ } -+ -+ bb37: { -+ _16 = move _2; + } + +- bb36 (cleanup): { +- StorageDead(_23); +- goto -> bb10; ++ bb36: { ++ StorageLive(_7); ++ _7 = move _2; ++ goto -> bb12; + } + + bb37: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb37, unwind: bb36]; ++ StorageLive(_14); ++ _14 = move _2; ++ goto -> bb14; + } + + bb38: { +- _2 = move _24; +- StorageDead(_24); +- goto -> bb37; ++ StorageLive(_24); ++ _24 = move _2; + goto -> bb25; -+ } -+ -+ bb38: { -+ _20 = move _2; -+ goto -> bb29; -+ } -+ -+ bb39: { -+ _25 = move _2; -+ goto -> bb31; -+ } -+ -+ bb40: { -+ _29 = move _2; -+ goto -> bb34; -+ } -+ -+ bb41: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb41, unwind continue]; -+ } -+ -+ bb42: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb42, unwind continue]; -+ } -+ -+ bb43: { + } + + bb39: { +- _2 = move _24; +- StorageDead(_24); +- goto -> bb44; ++ StorageLive(_31); ++ _31 = move _2; ++ goto -> bb26; + } + + bb40: { +- StorageLive(_24); +- _24 = yield(const ()) -> [resume: bb38, drop: bb39]; ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb40, unwind continue]; + } + + bb41: { +- _26 = discriminant(_25); +- switchInt(move _26) -> [0: bb35, 1: bb40, otherwise: bb20]; ++ assert(const false, "`async fn` resumed after completion") -> [success: bb41, unwind continue]; + } + + bb42: { +- _25 = as Future>::poll(move _27, move _28) -> [return: bb41, unwind: bb36]; +- } +- +- bb43: { +- _29 = move _2; +- _28 = std::future::get_context::<'_, '_>(move _29) -> [return: bb42, unwind: bb36]; +- } +- +- bb44: { +- _30 = &mut _23; +- _27 = Pin::<&mut impl Future>::new_unchecked(move _30) -> [return: bb43, unwind: bb36]; +- } +- +- bb45: { +- _2 = move _31; +- StorageDead(_31); +- goto -> bb51; +- } +- +- bb46: { +- _2 = move _31; +- StorageDead(_31); +- goto -> bb44; +- } +- +- bb47: { +- StorageLive(_31); +- _31 = yield(const ()) -> [resume: bb45, drop: bb46]; +- } +- +- bb48: { +- _33 = discriminant(_32); +- switchInt(move _33) -> [0: bb34, 1: bb47, otherwise: bb20]; +- } +- +- bb49: { +- _32 = as Future>::poll(move _34, move _35) -> [return: bb48, unwind: bb36]; +- } +- +- bb50: { +- _36 = move _2; +- _35 = std::future::get_context::<'_, '_>(move _36) -> [return: bb49, unwind: bb36]; +- } +- +- bb51: { +- _37 = &mut _23; +- _34 = Pin::<&mut impl Future>::new_unchecked(move _37) -> [return: bb50, unwind: bb36]; +- } +- +- bb52: { +- StorageLive(_23); +- _23 = async_drop_in_place::(copy (_38.0: &mut AsyncInt)) -> [return: bb51, unwind: bb36]; +- } +- +- bb53: { +- _39 = &mut _4; +- _38 = Pin::<&mut AsyncInt>::new_unchecked(move _39) -> [return: bb52, unwind: bb10]; + nop; -+ (((*_35) as variant#6).0: SyncInt) = SyncInt(const 0_i32); ++ (((*_42) as variant#6).1: SyncInt) = SyncInt(const 0_i32); + nop; -+ (((*_35) as variant#6).1: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_42) as variant#6).2: AsyncInt) = AsyncInt(const 0_i32); + nop; -+ (((*_35) as variant#4).2: AsyncInt) = AsyncInt(const 0_i32); -+ (((*_35) as variant#5).0: ()) = const (); -+ goto -> bb13; ++ (((*_42) as variant#4).3: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_42) as variant#6).0: ()) = const (); ++ goto -> bb21; } } diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir deleted file mode 100644 index 01a90a4a8fa5a..0000000000000 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir +++ /dev/null @@ -1,308 +0,0 @@ -// MIR for `double::{closure#0}` 0 coroutine_async_drop_expand - -fn double::{closure#0}(_1: {async fn body of double()}, _2: &mut Context<'_>) -> () -yields () - { - debug _task_context => _2; - let mut _0: (); - let _3: SyncInt; - let mut _6: impl std::future::Future; - let mut _7: std::pin::Pin<&mut AsyncInt>; - let mut _8: &mut AsyncInt; - let mut _9: impl std::future::Future; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; - let mut _12: impl std::future::Future; - let mut _13: std::pin::Pin<&mut {async fn body of double()}>; - let mut _14: &mut {async fn body of double()}; - let mut _15: std::task::Poll<()>; - let mut _16: &mut std::task::Context<'_>; - let mut _17: &mut impl std::future::Future; - let mut _18: std::pin::Pin<&mut impl std::future::Future>; - let mut _19: isize; - let mut _20: &mut std::task::Context<'_>; - let mut _21: &mut impl std::future::Future; - let mut _22: std::pin::Pin<&mut impl std::future::Future>; - let mut _23: isize; - let mut _24: std::task::Poll<()>; - let mut _25: &mut std::task::Context<'_>; - let mut _26: &mut impl std::future::Future; - let mut _27: std::pin::Pin<&mut impl std::future::Future>; - let mut _28: isize; - let mut _29: &mut std::task::Context<'_>; - let mut _30: &mut impl std::future::Future; - let mut _31: std::pin::Pin<&mut impl std::future::Future>; - let mut _32: isize; - scope 1 { - debug sync_int => _3; - let _4: AsyncInt; - scope 2 { - debug async_int => _4; - let _5: AsyncInt; - scope 3 { - debug async_int_again => _5; - } - } - } - - bb0: { - StorageLive(_3); - _3 = SyncInt(const 0_i32); - StorageLive(_4); - _4 = AsyncInt(const 0_i32); - StorageLive(_5); - _5 = AsyncInt(const 0_i32); - _0 = const (); - goto -> bb18; - } - - bb1: { - StorageDead(_5); - goto -> bb24; - } - - bb2: { - StorageDead(_4); - drop(_3) -> [return: bb3, unwind: bb11]; - } - - bb3: { - StorageDead(_3); - goto -> bb30; - } - - bb4: { - return; - } - - bb5: { - StorageDead(_5); - goto -> bb6; - } - - bb6: { - StorageDead(_4); - goto -> bb7; - } - - bb7: { - StorageDead(_3); - goto -> bb8; - } - - bb8: { - coroutine_drop; - } - - bb9 (cleanup): { - StorageDead(_5); - drop(_4) -> [return: bb10, unwind terminate(cleanup)]; - } - - bb10 (cleanup): { - StorageDead(_4); - drop(_3) -> [return: bb11, unwind terminate(cleanup)]; - } - - bb11 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb12, unwind terminate(cleanup)]; - } - - bb12 (cleanup): { - resume; - } - - bb13: { - StorageDead(_6); - goto -> bb1; - } - - bb14: { - StorageDead(_6); - goto -> bb5; - } - - bb15 (cleanup): { - StorageDead(_6); - goto -> bb9; - } - - bb16: { - _16 = move _2; - goto -> bb32; - } - - bb17: { - StorageLive(_6); - _6 = async_drop_in_place::(copy (_7.0: &mut AsyncInt)) -> [return: bb16, unwind: bb15]; - } - - bb18: { - _8 = &mut _5; - _7 = Pin::<&mut AsyncInt>::new_unchecked(move _8) -> [return: bb17, unwind: bb9]; - } - - bb19: { - StorageDead(_9); - goto -> bb2; - } - - bb20: { - StorageDead(_9); - goto -> bb6; - } - - bb21 (cleanup): { - StorageDead(_9); - goto -> bb10; - } - - bb22: { - _25 = move _2; - goto -> bb43; - } - - bb23: { - StorageLive(_9); - _9 = async_drop_in_place::(copy (_10.0: &mut AsyncInt)) -> [return: bb22, unwind: bb21]; - } - - bb24: { - _11 = &mut _4; - _10 = Pin::<&mut AsyncInt>::new_unchecked(move _11) -> [return: bb23, unwind: bb10]; - } - - bb25: { - StorageDead(_12); - goto -> bb4; - } - - bb26: { - StorageDead(_12); - goto -> bb8; - } - - bb27 (cleanup): { - StorageDead(_12); - goto -> bb12; - } - - bb28: { - drop(_1) -> [return: bb25, unwind: bb27]; - } - - bb29: { - StorageLive(_12); - _12 = async_drop_in_place::<{async fn body of double()}>(copy (_13.0: &mut {async fn body of double()})) -> [return: bb28, unwind: bb27]; - } - - bb30: { - _14 = &mut _1; - _13 = Pin::<&mut {async fn body of double()}>::new_unchecked(move _14) -> [return: bb29, unwind: bb12]; - } - - bb31: { - _16 = yield(const false) -> [resume: bb32, drop: bb37]; - } - - bb32: { - StorageLive(_18); - _17 = &mut _6; - _18 = Pin::<&mut impl Future>::new_unchecked(move _17) -> [return: bb35, unwind continue]; - } - - bb33: { - unreachable; - } - - bb34: { - StorageDead(_18); - _19 = discriminant(_15); - switchInt(move _19) -> [0: bb13, 1: bb31, otherwise: bb33]; - } - - bb35: { - _15 = as Future>::poll(move _18, move _16) -> [return: bb34, unwind: bb15]; - } - - bb36: { - _20 = yield(const false) -> [resume: bb41, drop: bb37]; - } - - bb37: { - StorageLive(_22); - _21 = &mut _6; - _22 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb40, unwind continue]; - } - - bb38: { - unreachable; - } - - bb39: { - StorageDead(_22); - _23 = discriminant(_15); - switchInt(move _23) -> [0: bb14, 1: bb36, otherwise: bb38]; - } - - bb40: { - _15 = as Future>::poll(move _22, move _20) -> [return: bb39, unwind: bb15]; - } - - bb41: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb41, unwind continue]; - } - - bb42: { - _25 = yield(const false) -> [resume: bb43, drop: bb48]; - } - - bb43: { - StorageLive(_27); - _26 = &mut _9; - _27 = Pin::<&mut impl Future>::new_unchecked(move _26) -> [return: bb46, unwind continue]; - } - - bb44: { - unreachable; - } - - bb45: { - StorageDead(_27); - _28 = discriminant(_24); - switchInt(move _28) -> [0: bb19, 1: bb42, otherwise: bb44]; - } - - bb46: { - _24 = as Future>::poll(move _27, move _25) -> [return: bb45, unwind: bb21]; - } - - bb47: { - _29 = yield(const false) -> [resume: bb52, drop: bb48]; - } - - bb48: { - StorageLive(_31); - _30 = &mut _9; - _31 = Pin::<&mut impl Future>::new_unchecked(move _30) -> [return: bb51, unwind continue]; - } - - bb49: { - unreachable; - } - - bb50: { - StorageDead(_31); - _32 = discriminant(_24); - switchInt(move _32) -> [0: bb20, 1: bb47, otherwise: bb49]; - } - - bb51: { - _24 = as Future>::poll(move _31, move _29) -> [return: bb50, unwind: bb21]; - } - - bb52: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb52, unwind continue]; - } -} diff --git a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir index fcdfbad469ce7..acd022800f84c 100644 --- a/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir @@ -5,51 +5,58 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte let mut _0: std::task::Poll<()>; let _3: SyncInt; let mut _6: impl std::future::Future; - let mut _7: std::pin::Pin<&mut AsyncInt>; - let mut _8: &mut AsyncInt; - let mut _9: impl std::future::Future; - let mut _10: std::pin::Pin<&mut AsyncInt>; - let mut _11: &mut AsyncInt; - let mut _12: impl std::future::Future; - let mut _13: std::pin::Pin<&mut {async fn body of double()}>; - let mut _14: &mut {async fn body of double()}; + let mut _7: &mut std::task::Context<'_>; + let mut _8: std::task::Poll<()>; + let mut _9: isize; + let mut _10: std::pin::Pin<&mut impl std::future::Future>; + let mut _11: &mut std::task::Context<'_>; + let mut _12: &mut std::task::Context<'_>; + let mut _13: &mut impl std::future::Future; + let mut _14: &mut std::task::Context<'_>; let mut _15: std::task::Poll<()>; - let mut _16: &mut std::task::Context<'_>; - let mut _17: &mut impl std::future::Future; - let mut _18: std::pin::Pin<&mut impl std::future::Future>; - let mut _19: isize; - let mut _20: &mut std::task::Context<'_>; - let mut _21: &mut impl std::future::Future; - let mut _22: std::pin::Pin<&mut impl std::future::Future>; - let mut _23: isize; - let mut _24: std::task::Poll<()>; - let mut _25: &mut std::task::Context<'_>; - let mut _26: &mut impl std::future::Future; + let mut _16: isize; + let mut _17: std::pin::Pin<&mut impl std::future::Future>; + let mut _18: &mut std::task::Context<'_>; + let mut _19: &mut std::task::Context<'_>; + let mut _20: &mut impl std::future::Future; + let mut _21: std::pin::Pin<&mut AsyncInt>; + let mut _22: &mut AsyncInt; + let mut _23: impl std::future::Future; + let mut _24: &mut std::task::Context<'_>; + let mut _25: std::task::Poll<()>; + let mut _26: isize; let mut _27: std::pin::Pin<&mut impl std::future::Future>; - let mut _28: isize; + let mut _28: &mut std::task::Context<'_>; let mut _29: &mut std::task::Context<'_>; let mut _30: &mut impl std::future::Future; - let mut _31: std::pin::Pin<&mut impl std::future::Future>; - let mut _32: isize; - let mut _33: (); - let mut _34: u32; - let mut _35: &mut {async fn body of double()}; + let mut _31: &mut std::task::Context<'_>; + let mut _32: std::task::Poll<()>; + let mut _33: isize; + let mut _34: std::pin::Pin<&mut impl std::future::Future>; + let mut _35: &mut std::task::Context<'_>; + let mut _36: &mut std::task::Context<'_>; + let mut _37: &mut impl std::future::Future; + let mut _38: std::pin::Pin<&mut AsyncInt>; + let mut _39: &mut AsyncInt; + let mut _40: (); + let mut _41: u32; + let mut _42: &mut {async fn body of double()}; scope 1 { - debug sync_int => (((*_35) as variant#6).0: SyncInt); + debug sync_int => (((*_42) as variant#6).1: SyncInt); let _4: AsyncInt; scope 2 { - debug async_int => (((*_35) as variant#6).1: AsyncInt); + debug async_int => (((*_42) as variant#6).2: AsyncInt); let _5: AsyncInt; scope 3 { - debug async_int_again => (((*_35) as variant#4).2: AsyncInt); + debug async_int_again => (((*_42) as variant#4).3: AsyncInt); } } } bb0: { - _35 = copy (_1.0: &mut {async fn body of double()}); - _34 = discriminant((*_35)); - switchInt(move _34) -> [0: bb23, 2: bb30, 3: bb26, 4: bb27, 5: bb28, 6: bb29, otherwise: bb31]; + _42 = copy (_1.0: &mut {async fn body of double()}); + _41 = discriminant((*_42)); + switchInt(move _41) -> [0: bb29, 2: bb36, 3: bb32, 4: bb33, 5: bb34, 6: bb35, otherwise: bb37]; } bb1: { @@ -74,12 +81,12 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte bb5 (cleanup): { nop; - drop((((*_35) as variant#6).1: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; + drop((((*_42) as variant#6).2: AsyncInt)) -> [return: bb6, unwind terminate(cleanup)]; } bb6 (cleanup): { nop; - drop((((*_35) as variant#6).0: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; + drop((((*_42) as variant#6).1: SyncInt)) -> [return: bb7, unwind terminate(cleanup)]; } bb7 (cleanup): { @@ -88,7 +95,7 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte } bb8 (cleanup): { - goto -> bb25; + goto -> bb31; } bb9: { @@ -102,106 +109,146 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte } bb11: { - nop; - goto -> bb2; + _2 = move _7; + StorageDead(_7); + goto -> bb17; } - bb12 (cleanup): { - nop; - goto -> bb6; + bb12: { + StorageLive(_7); + _0 = Poll::<()>::Pending; + StorageDead(_7); + discriminant((*_42)) = 3; + return; } bb13: { - _0 = Poll::<()>::Pending; - discriminant((*_35)) = 4; - return; + unreachable; } bb14: { - StorageLive(_22); - _21 = &mut (((*_35) as variant#4).3: impl std::future::Future); - _22 = Pin::<&mut impl Future>::new_unchecked(move _21) -> [return: bb17, unwind: bb25]; + _9 = discriminant(_8); + switchInt(move _9) -> [0: bb9, 1: bb12, otherwise: bb13]; } bb15: { - unreachable; + _8 = as Future>::poll(move _10, move _11) -> [return: bb14, unwind: bb10]; } bb16: { - StorageDead(_22); - _23 = discriminant(_15); - switchInt(move _23) -> [0: bb9, 1: bb13, otherwise: bb15]; + _12 = move _2; + _11 = move _12; + goto -> bb15; } bb17: { - _15 = as Future>::poll(move _22, move _20) -> [return: bb16, unwind: bb10]; + _13 = &mut (((*_42) as variant#4).4: impl std::future::Future); + _10 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb16, unwind: bb10]; } bb18: { - _0 = Poll::<()>::Pending; - discriminant((*_35)) = 6; - return; + _2 = move _14; + StorageDead(_14); + goto -> bb17; } bb19: { - StorageLive(_31); - _30 = &mut (((*_35) as variant#6).2: impl std::future::Future); - _31 = Pin::<&mut impl Future>::new_unchecked(move _30) -> [return: bb21, unwind: bb25]; + nop; + goto -> bb2; } - bb20: { - StorageDead(_31); - _32 = discriminant(_24); - switchInt(move _32) -> [0: bb11, 1: bb18, otherwise: bb15]; + bb20 (cleanup): { + nop; + goto -> bb6; } bb21: { - _24 = as Future>::poll(move _31, move _29) -> [return: bb20, unwind: bb12]; + _2 = move _24; + StorageDead(_24); + goto -> bb26; } bb22: { - _0 = Poll::<()>::Ready(const ()); + StorageLive(_24); + _0 = Poll::<()>::Pending; + StorageDead(_24); + discriminant((*_42)) = 5; return; } bb23: { - goto -> bb24; + _26 = discriminant(_25); + switchInt(move _26) -> [0: bb19, 1: bb22, otherwise: bb13]; } bb24: { - goto -> bb22; + _25 = as Future>::poll(move _27, move _28) -> [return: bb23, unwind: bb20]; } - bb25 (cleanup): { - discriminant((*_35)) = 2; - resume; + bb25: { + _29 = move _2; + _28 = move _29; + goto -> bb24; } bb26: { - _16 = move _2; - goto -> bb14; + _30 = &mut (((*_42) as variant#6).3: impl std::future::Future); + _27 = Pin::<&mut impl Future>::new_unchecked(move _30) -> [return: bb25, unwind: bb20]; } bb27: { - _20 = move _2; - goto -> bb14; + _2 = move _31; + StorageDead(_31); + goto -> bb26; } bb28: { - _25 = move _2; - goto -> bb19; + _0 = Poll::<()>::Ready(const ()); + return; } bb29: { - _29 = move _2; - goto -> bb19; + goto -> bb30; } bb30: { - assert(const false, "`async fn` resumed after panicking") -> [success: bb30, unwind continue]; + goto -> bb28; + } + + bb31 (cleanup): { + discriminant((*_42)) = 2; + resume; + } + + bb32: { + StorageLive(_7); + _7 = move _2; + goto -> bb11; + } + + bb33: { + StorageLive(_14); + _14 = move _2; + goto -> bb18; + } + + bb34: { + StorageLive(_24); + _24 = move _2; + goto -> bb21; + } + + bb35: { + StorageLive(_31); + _31 = move _2; + goto -> bb27; + } + + bb36: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb36, unwind continue]; } - bb31: { + bb37: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff index 204ccd0bef58f..dd65409f0db13 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff @@ -19,35 +19,158 @@ let mut _21: &AsyncInt; let _22: &AsyncInt; + let mut _27: impl std::future::Future; -+ let mut _28: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>; -+ let mut _29: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; -+ let mut _30: impl std::future::Future; -+ let mut _31: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>; -+ let mut _32: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; -+ let mut _33: impl std::future::Future; -+ let mut _34: std::pin::Pin<&mut AsyncReference<'_>>; -+ let mut _35: &mut AsyncReference<'_>; -+ let mut _36: impl std::future::Future; -+ let mut _37: std::pin::Pin<&mut AsyncInt>; -+ let mut _38: &mut AsyncInt; -+ let mut _39: impl std::future::Future; -+ let mut _40: std::pin::Pin<&mut AsyncEnum>; -+ let mut _41: &mut AsyncEnum; -+ let mut _42: impl std::future::Future; -+ let mut _43: std::pin::Pin<&mut SyncThenAsync>; -+ let mut _44: &mut SyncThenAsync; -+ let mut _45: impl std::future::Future; -+ let mut _46: std::pin::Pin<&mut AsyncStruct>; -+ let mut _47: &mut AsyncStruct; -+ let mut _48: impl std::future::Future; -+ let mut _49: std::pin::Pin<&mut [AsyncInt; 2]>; -+ let mut _50: &mut [AsyncInt; 2]; -+ let mut _51: impl std::future::Future; -+ let mut _52: std::pin::Pin<&mut AsyncInt>; -+ let mut _53: &mut AsyncInt; -+ let mut _54: impl std::future::Future; -+ let mut _55: std::pin::Pin<&mut {async fn body of elaborate_drops()}>; -+ let mut _56: &mut {async fn body of elaborate_drops()}; ++ let mut _28: std::future::ResumeTy; ++ let mut _29: std::task::Poll<()>; ++ let mut _30: isize; ++ let mut _31: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _32: &mut std::task::Context<'_>; ++ let mut _33: std::future::ResumeTy; ++ let mut _34: &mut impl std::future::Future; ++ let mut _35: std::future::ResumeTy; ++ let mut _36: std::task::Poll<()>; ++ let mut _37: isize; ++ let mut _38: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _39: &mut std::task::Context<'_>; ++ let mut _40: std::future::ResumeTy; ++ let mut _41: &mut impl std::future::Future; ++ let mut _42: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:78:27: 78:35}>; ++ let mut _43: &mut {async closure@$DIR/async_drop.rs:78:27: 78:35}; ++ let mut _44: impl std::future::Future; ++ let mut _45: std::future::ResumeTy; ++ let mut _46: std::task::Poll<()>; ++ let mut _47: isize; ++ let mut _48: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _49: &mut std::task::Context<'_>; ++ let mut _50: std::future::ResumeTy; ++ let mut _51: &mut impl std::future::Future; ++ let mut _52: std::future::ResumeTy; ++ let mut _53: std::task::Poll<()>; ++ let mut _54: isize; ++ let mut _55: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _56: &mut std::task::Context<'_>; ++ let mut _57: std::future::ResumeTy; ++ let mut _58: &mut impl std::future::Future; ++ let mut _59: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:70:25: 70:27}>; ++ let mut _60: &mut {closure@$DIR/async_drop.rs:70:25: 70:27}; ++ let mut _61: impl std::future::Future; ++ let mut _62: std::future::ResumeTy; ++ let mut _63: std::task::Poll<()>; ++ let mut _64: isize; ++ let mut _65: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _66: &mut std::task::Context<'_>; ++ let mut _67: std::future::ResumeTy; ++ let mut _68: &mut impl std::future::Future; ++ let mut _69: std::future::ResumeTy; ++ let mut _70: std::task::Poll<()>; ++ let mut _71: isize; ++ let mut _72: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _73: &mut std::task::Context<'_>; ++ let mut _74: std::future::ResumeTy; ++ let mut _75: &mut impl std::future::Future; ++ let mut _76: std::pin::Pin<&mut AsyncReference<'_>>; ++ let mut _77: &mut AsyncReference<'_>; ++ let mut _78: impl std::future::Future; ++ let mut _79: std::future::ResumeTy; ++ let mut _80: std::task::Poll<()>; ++ let mut _81: isize; ++ let mut _82: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _83: &mut std::task::Context<'_>; ++ let mut _84: std::future::ResumeTy; ++ let mut _85: &mut impl std::future::Future; ++ let mut _86: std::future::ResumeTy; ++ let mut _87: std::task::Poll<()>; ++ let mut _88: isize; ++ let mut _89: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _90: &mut std::task::Context<'_>; ++ let mut _91: std::future::ResumeTy; ++ let mut _92: &mut impl std::future::Future; ++ let mut _93: std::pin::Pin<&mut AsyncInt>; ++ let mut _94: &mut AsyncInt; ++ let mut _95: impl std::future::Future; ++ let mut _96: std::future::ResumeTy; ++ let mut _97: std::task::Poll<()>; ++ let mut _98: isize; ++ let mut _99: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _100: &mut std::task::Context<'_>; ++ let mut _101: std::future::ResumeTy; ++ let mut _102: &mut impl std::future::Future; ++ let mut _103: std::future::ResumeTy; ++ let mut _104: std::task::Poll<()>; ++ let mut _105: isize; ++ let mut _106: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _107: &mut std::task::Context<'_>; ++ let mut _108: std::future::ResumeTy; ++ let mut _109: &mut impl std::future::Future; ++ let mut _110: std::pin::Pin<&mut AsyncEnum>; ++ let mut _111: &mut AsyncEnum; ++ let mut _112: impl std::future::Future; ++ let mut _113: std::future::ResumeTy; ++ let mut _114: std::task::Poll<()>; ++ let mut _115: isize; ++ let mut _116: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _117: &mut std::task::Context<'_>; ++ let mut _118: std::future::ResumeTy; ++ let mut _119: &mut impl std::future::Future; ++ let mut _120: std::future::ResumeTy; ++ let mut _121: std::task::Poll<()>; ++ let mut _122: isize; ++ let mut _123: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _124: &mut std::task::Context<'_>; ++ let mut _125: std::future::ResumeTy; ++ let mut _126: &mut impl std::future::Future; ++ let mut _127: std::pin::Pin<&mut SyncThenAsync>; ++ let mut _128: &mut SyncThenAsync; ++ let mut _129: impl std::future::Future; ++ let mut _130: std::future::ResumeTy; ++ let mut _131: std::task::Poll<()>; ++ let mut _132: isize; ++ let mut _133: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _134: &mut std::task::Context<'_>; ++ let mut _135: std::future::ResumeTy; ++ let mut _136: &mut impl std::future::Future; ++ let mut _137: std::future::ResumeTy; ++ let mut _138: std::task::Poll<()>; ++ let mut _139: isize; ++ let mut _140: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _141: &mut std::task::Context<'_>; ++ let mut _142: std::future::ResumeTy; ++ let mut _143: &mut impl std::future::Future; ++ let mut _144: std::pin::Pin<&mut AsyncStruct>; ++ let mut _145: &mut AsyncStruct; ++ let mut _146: impl std::future::Future; ++ let mut _147: std::future::ResumeTy; ++ let mut _148: std::task::Poll<()>; ++ let mut _149: isize; ++ let mut _150: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _151: &mut std::task::Context<'_>; ++ let mut _152: std::future::ResumeTy; ++ let mut _153: &mut impl std::future::Future; ++ let mut _154: std::future::ResumeTy; ++ let mut _155: std::task::Poll<()>; ++ let mut _156: isize; ++ let mut _157: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _158: &mut std::task::Context<'_>; ++ let mut _159: std::future::ResumeTy; ++ let mut _160: &mut impl std::future::Future; ++ let mut _161: std::pin::Pin<&mut [AsyncInt; 2]>; ++ let mut _162: &mut [AsyncInt; 2]; ++ let mut _163: impl std::future::Future; ++ let mut _164: std::future::ResumeTy; ++ let mut _165: std::task::Poll<()>; ++ let mut _166: isize; ++ let mut _167: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _168: &mut std::task::Context<'_>; ++ let mut _169: std::future::ResumeTy; ++ let mut _170: &mut impl std::future::Future; ++ let mut _171: std::future::ResumeTy; ++ let mut _172: std::task::Poll<()>; ++ let mut _173: isize; ++ let mut _174: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _175: &mut std::task::Context<'_>; ++ let mut _176: std::future::ResumeTy; ++ let mut _177: &mut impl std::future::Future; ++ let mut _178: std::pin::Pin<&mut AsyncInt>; ++ let mut _179: &mut AsyncInt; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -77,13 +200,13 @@ let _23: AsyncInt; scope 10 { debug foo => _23; - let _24: {closure@$DIR/async_drop.rs:72:25: 72:27}; + let _24: {closure@$DIR/async_drop.rs:70:25: 70:27}; scope 11 { debug async_closure => _24; let _25: AsyncInt; scope 12 { debug foo => _25; - let _26: {async closure@$DIR/async_drop.rs:80:27: 80:35}; + let _26: {async closure@$DIR/async_drop.rs:78:27: 78:35}; scope 13 { debug async_coroutine => _26; } @@ -198,14 +321,14 @@ StorageLive(_23); _23 = AsyncInt(const 14_i32); StorageLive(_24); - _24 = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; + _24 = {closure@$DIR/async_drop.rs:70:25: 70:27} { foo: move _23 }; StorageLive(_25); _25 = AsyncInt(const 15_i32); StorageLive(_26); - _26 = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; + _26 = {closure@$DIR/async_drop.rs:78:27: 78:35} { foo: move _25 }; _0 = const (); - drop(_26) -> [return: bb10, unwind: bb44, drop: bb23]; -+ goto -> bb88; ++ goto -> bb103; } bb10: { @@ -217,7 +340,7 @@ bb11: { StorageDead(_25); - drop(_24) -> [return: bb12, unwind: bb46, drop: bb25]; -+ goto -> bb94; ++ goto -> bb123; } bb12: { @@ -229,44 +352,44 @@ bb13: { StorageDead(_23); - drop(_20) -> [return: bb14, unwind: bb48, drop: bb27]; -+ goto -> bb100; ++ goto -> bb143; } bb14: { StorageDead(_20); - drop(_19) -> [return: bb15, unwind: bb49, drop: bb28]; -+ goto -> bb106; ++ goto -> bb163; } bb15: { StorageDead(_19); StorageDead(_17); - drop(_15) -> [return: bb16, unwind: bb54, drop: bb30]; -+ goto -> bb112; ++ goto -> bb183; } bb16: { StorageDead(_15); - drop(_11) -> [return: bb17, unwind: bb58, drop: bb34]; -+ goto -> bb118; ++ goto -> bb203; } bb17: { StorageDead(_11); - drop(_8) -> [return: bb18, unwind: bb61, drop: bb37]; -+ goto -> bb124; ++ goto -> bb223; } bb18: { StorageDead(_8); - drop(_5) -> [return: bb19, unwind: bb64, drop: bb40]; -+ goto -> bb130; ++ goto -> bb243; } bb19: { StorageDead(_5); - drop(_4) -> [return: bb20, unwind: bb65, drop: bb41]; -+ goto -> bb136; ++ goto -> bb263; } bb20: { @@ -277,7 +400,7 @@ bb21: { StorageDead(_3); - drop(_1) -> [return: bb22, drop: bb43, unwind continue]; -+ goto -> bb142; ++ drop(_1) -> [return: bb22, unwind: bb67]; } bb22: { @@ -634,278 +757,901 @@ + } + + bb86: { -+ async drop(_26; poll=_27) -> [return: bb83, unwind: bb85, drop: bb84]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb86, unwind: bb85]; + } + + bb87: { -+ StorageLive(_27); -+ _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(copy (_28.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35})) -> [return: bb86, unwind: bb85]; ++ _2 = move _28; ++ StorageDead(_28); ++ goto -> bb86; + } + + bb88: { -+ _29 = &mut _26; -+ _28 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _29) -> [return: bb87, unwind: bb44]; ++ _2 = move _28; ++ StorageDead(_28); ++ goto -> bb94; + } + + bb89: { -+ StorageDead(_30); -+ goto -> bb12; ++ StorageLive(_28); ++ _28 = yield(const ()) -> [resume: bb87, drop: bb88]; + } + + bb90: { -+ StorageDead(_30); -+ goto -> bb25; ++ unreachable; + } + -+ bb91 (cleanup): { -+ StorageDead(_30); -+ goto -> bb46; ++ bb91: { ++ _30 = discriminant(_29); ++ switchInt(move _30) -> [0: bb84, 1: bb89, otherwise: bb90]; + } + + bb92: { -+ async drop(_24; poll=_30) -> [return: bb89, unwind: bb91, drop: bb90]; ++ _29 = as Future>::poll(move _31, move _32) -> [return: bb91, unwind: bb85]; + } + + bb93: { -+ StorageLive(_30); -+ _30 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(copy (_31.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb92, unwind: bb91]; ++ _33 = move _2; ++ _32 = std::future::get_context::<'_, '_>(move _33) -> [return: bb92, unwind: bb85]; + } + + bb94: { -+ _32 = &mut _24; -+ _31 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb93, unwind: bb46]; ++ _34 = &mut _27; ++ _31 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb93, unwind: bb85]; + } + + bb95: { -+ StorageDead(_33); -+ goto -> bb14; ++ _2 = move _35; ++ StorageDead(_35); ++ goto -> bb101; + } + + bb96: { -+ StorageDead(_33); -+ goto -> bb27; ++ _2 = move _35; ++ StorageDead(_35); ++ goto -> bb94; + } + -+ bb97 (cleanup): { -+ StorageDead(_33); -+ goto -> bb48; ++ bb97: { ++ StorageLive(_35); ++ _35 = yield(const ()) -> [resume: bb95, drop: bb96]; + } + + bb98: { -+ async drop(_20; poll=_33) -> [return: bb95, unwind: bb97, drop: bb96]; ++ _37 = discriminant(_36); ++ switchInt(move _37) -> [0: bb83, 1: bb97, otherwise: bb90]; + } + + bb99: { -+ StorageLive(_33); -+ _33 = async_drop_in_place::>(copy (_34.0: &mut AsyncReference<'_>)) -> [return: bb98, unwind: bb97]; ++ _36 = as Future>::poll(move _38, move _39) -> [return: bb98, unwind: bb85]; + } + + bb100: { -+ _35 = &mut _20; -+ _34 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _35) -> [return: bb99, unwind: bb48]; ++ _40 = move _2; ++ _39 = std::future::get_context::<'_, '_>(move _40) -> [return: bb99, unwind: bb85]; + } + + bb101: { -+ StorageDead(_36); -+ goto -> bb15; ++ _41 = &mut _27; ++ _38 = Pin::<&mut impl Future>::new_unchecked(move _41) -> [return: bb100, unwind: bb85]; + } + + bb102: { -+ StorageDead(_36); -+ goto -> bb28; ++ StorageLive(_27); ++ _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:78:27: 78:35}>(copy (_42.0: &mut {async closure@$DIR/async_drop.rs:78:27: 78:35})) -> [return: bb101, unwind: bb85]; + } + -+ bb103 (cleanup): { -+ StorageDead(_36); -+ goto -> bb49; ++ bb103: { ++ _43 = &mut _26; ++ _42 = Pin::<&mut {async closure@$DIR/async_drop.rs:78:27: 78:35}>::new_unchecked(move _43) -> [return: bb102, unwind: bb44]; + } + + bb104: { -+ async drop(_19; poll=_36) -> [return: bb101, unwind: bb103, drop: bb102]; ++ StorageDead(_44); ++ goto -> bb12; + } + + bb105: { -+ StorageLive(_36); -+ _36 = async_drop_in_place::(copy (_37.0: &mut AsyncInt)) -> [return: bb104, unwind: bb103]; ++ StorageDead(_44); ++ goto -> bb25; + } + -+ bb106: { -+ _38 = &mut _19; -+ _37 = Pin::<&mut AsyncInt>::new_unchecked(move _38) -> [return: bb105, unwind: bb49]; ++ bb106 (cleanup): { ++ StorageDead(_44); ++ goto -> bb46; + } + + bb107: { -+ StorageDead(_39); -+ goto -> bb16; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb107, unwind: bb106]; + } + + bb108: { -+ StorageDead(_39); -+ goto -> bb30; ++ _2 = move _45; ++ StorageDead(_45); ++ goto -> bb107; + } + -+ bb109 (cleanup): { -+ StorageDead(_39); -+ goto -> bb54; ++ bb109: { ++ _2 = move _45; ++ StorageDead(_45); ++ goto -> bb114; + } + + bb110: { -+ async drop(_15; poll=_39) -> [return: bb107, unwind: bb109, drop: bb108]; ++ StorageLive(_45); ++ _45 = yield(const ()) -> [resume: bb108, drop: bb109]; + } + + bb111: { -+ StorageLive(_39); -+ _39 = async_drop_in_place::(copy (_40.0: &mut AsyncEnum)) -> [return: bb110, unwind: bb109]; ++ _47 = discriminant(_46); ++ switchInt(move _47) -> [0: bb105, 1: bb110, otherwise: bb90]; + } + + bb112: { -+ _41 = &mut _15; -+ _40 = Pin::<&mut AsyncEnum>::new_unchecked(move _41) -> [return: bb111, unwind: bb54]; ++ _46 = as Future>::poll(move _48, move _49) -> [return: bb111, unwind: bb106]; + } + + bb113: { -+ StorageDead(_42); -+ goto -> bb17; ++ _50 = move _2; ++ _49 = std::future::get_context::<'_, '_>(move _50) -> [return: bb112, unwind: bb106]; + } + + bb114: { -+ StorageDead(_42); -+ goto -> bb34; ++ _51 = &mut _44; ++ _48 = Pin::<&mut impl Future>::new_unchecked(move _51) -> [return: bb113, unwind: bb106]; + } + -+ bb115 (cleanup): { -+ StorageDead(_42); -+ goto -> bb58; ++ bb115: { ++ _2 = move _52; ++ StorageDead(_52); ++ goto -> bb121; + } + + bb116: { -+ async drop(_11; poll=_42) -> [return: bb113, unwind: bb115, drop: bb114]; ++ _2 = move _52; ++ StorageDead(_52); ++ goto -> bb114; + } + + bb117: { -+ StorageLive(_42); -+ _42 = async_drop_in_place::(copy (_43.0: &mut SyncThenAsync)) -> [return: bb116, unwind: bb115]; ++ StorageLive(_52); ++ _52 = yield(const ()) -> [resume: bb115, drop: bb116]; + } + + bb118: { -+ _44 = &mut _11; -+ _43 = Pin::<&mut SyncThenAsync>::new_unchecked(move _44) -> [return: bb117, unwind: bb58]; ++ _54 = discriminant(_53); ++ switchInt(move _54) -> [0: bb104, 1: bb117, otherwise: bb90]; + } + + bb119: { -+ StorageDead(_45); -+ goto -> bb18; ++ _53 = as Future>::poll(move _55, move _56) -> [return: bb118, unwind: bb106]; + } + + bb120: { -+ StorageDead(_45); -+ goto -> bb37; ++ _57 = move _2; ++ _56 = std::future::get_context::<'_, '_>(move _57) -> [return: bb119, unwind: bb106]; + } + -+ bb121 (cleanup): { -+ StorageDead(_45); -+ goto -> bb61; ++ bb121: { ++ _58 = &mut _44; ++ _55 = Pin::<&mut impl Future>::new_unchecked(move _58) -> [return: bb120, unwind: bb106]; + } + + bb122: { -+ async drop(_8; poll=_45) -> [return: bb119, unwind: bb121, drop: bb120]; ++ StorageLive(_44); ++ _44 = async_drop_in_place::<{closure@$DIR/async_drop.rs:70:25: 70:27}>(copy (_59.0: &mut {closure@$DIR/async_drop.rs:70:25: 70:27})) -> [return: bb121, unwind: bb106]; + } + + bb123: { -+ StorageLive(_45); -+ _45 = async_drop_in_place::(copy (_46.0: &mut AsyncStruct)) -> [return: bb122, unwind: bb121]; ++ _60 = &mut _24; ++ _59 = Pin::<&mut {closure@$DIR/async_drop.rs:70:25: 70:27}>::new_unchecked(move _60) -> [return: bb122, unwind: bb46]; + } + + bb124: { -+ _47 = &mut _8; -+ _46 = Pin::<&mut AsyncStruct>::new_unchecked(move _47) -> [return: bb123, unwind: bb61]; ++ StorageDead(_61); ++ goto -> bb14; + } + + bb125: { -+ StorageDead(_48); -+ goto -> bb19; ++ StorageDead(_61); ++ goto -> bb27; + } + -+ bb126: { -+ StorageDead(_48); -+ goto -> bb40; ++ bb126 (cleanup): { ++ StorageDead(_61); ++ goto -> bb48; + } + -+ bb127 (cleanup): { -+ StorageDead(_48); -+ goto -> bb64; ++ bb127: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb127, unwind: bb126]; + } + + bb128: { -+ async drop(_5; poll=_48) -> [return: bb125, unwind: bb127, drop: bb126]; ++ _2 = move _62; ++ StorageDead(_62); ++ goto -> bb127; + } + + bb129: { -+ StorageLive(_48); -+ _48 = async_drop_in_place::<[AsyncInt; 2]>(copy (_49.0: &mut [AsyncInt; 2])) -> [return: bb128, unwind: bb127]; ++ _2 = move _62; ++ StorageDead(_62); ++ goto -> bb134; + } + + bb130: { -+ _50 = &mut _5; -+ _49 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _50) -> [return: bb129, unwind: bb64]; ++ StorageLive(_62); ++ _62 = yield(const ()) -> [resume: bb128, drop: bb129]; + } + + bb131: { -+ StorageDead(_51); -+ goto -> bb20; ++ _64 = discriminant(_63); ++ switchInt(move _64) -> [0: bb125, 1: bb130, otherwise: bb90]; + } + + bb132: { -+ StorageDead(_51); -+ goto -> bb41; ++ _63 = as Future>::poll(move _65, move _66) -> [return: bb131, unwind: bb126]; + } + -+ bb133 (cleanup): { -+ StorageDead(_51); -+ goto -> bb65; ++ bb133: { ++ _67 = move _2; ++ _66 = std::future::get_context::<'_, '_>(move _67) -> [return: bb132, unwind: bb126]; + } + + bb134: { -+ async drop(_4; poll=_51) -> [return: bb131, unwind: bb133, drop: bb132]; ++ _68 = &mut _61; ++ _65 = Pin::<&mut impl Future>::new_unchecked(move _68) -> [return: bb133, unwind: bb126]; + } + + bb135: { -+ StorageLive(_51); -+ _51 = async_drop_in_place::(copy (_52.0: &mut AsyncInt)) -> [return: bb134, unwind: bb133]; ++ _2 = move _69; ++ StorageDead(_69); ++ goto -> bb141; + } + + bb136: { -+ _53 = &mut _4; -+ _52 = Pin::<&mut AsyncInt>::new_unchecked(move _53) -> [return: bb135, unwind: bb65]; ++ _2 = move _69; ++ StorageDead(_69); ++ goto -> bb134; + } + + bb137: { -+ StorageDead(_54); -+ goto -> bb22; ++ StorageLive(_69); ++ _69 = yield(const ()) -> [resume: bb135, drop: bb136]; + } + + bb138: { -+ StorageDead(_54); -+ goto -> bb43; ++ _71 = discriminant(_70); ++ switchInt(move _71) -> [0: bb124, 1: bb137, otherwise: bb90]; + } + -+ bb139 (cleanup): { -+ StorageDead(_54); -+ goto -> bb67; ++ bb139: { ++ _70 = as Future>::poll(move _72, move _73) -> [return: bb138, unwind: bb126]; + } + + bb140: { -+ async drop(_1; poll=_54) -> [return: bb137, unwind: bb139, drop: bb138]; ++ _74 = move _2; ++ _73 = std::future::get_context::<'_, '_>(move _74) -> [return: bb139, unwind: bb126]; + } + + bb141: { -+ StorageLive(_54); -+ _54 = async_drop_in_place::<{async fn body of elaborate_drops()}>(copy (_55.0: &mut {async fn body of elaborate_drops()})) -> [return: bb140, unwind: bb139]; ++ _75 = &mut _61; ++ _72 = Pin::<&mut impl Future>::new_unchecked(move _75) -> [return: bb140, unwind: bb126]; + } + + bb142: { -+ _56 = &mut _1; -+ _55 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _56) -> [return: bb141, unwind: bb67]; ++ StorageLive(_61); ++ _61 = async_drop_in_place::>(copy (_76.0: &mut AsyncReference<'_>)) -> [return: bb141, unwind: bb126]; ++ } ++ ++ bb143: { ++ _77 = &mut _20; ++ _76 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _77) -> [return: bb142, unwind: bb48]; ++ } ++ ++ bb144: { ++ StorageDead(_78); ++ goto -> bb15; ++ } ++ ++ bb145: { ++ StorageDead(_78); ++ goto -> bb28; ++ } ++ ++ bb146 (cleanup): { ++ StorageDead(_78); ++ goto -> bb49; ++ } ++ ++ bb147: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb147, unwind: bb146]; ++ } ++ ++ bb148: { ++ _2 = move _79; ++ StorageDead(_79); ++ goto -> bb147; ++ } ++ ++ bb149: { ++ _2 = move _79; ++ StorageDead(_79); ++ goto -> bb154; ++ } ++ ++ bb150: { ++ StorageLive(_79); ++ _79 = yield(const ()) -> [resume: bb148, drop: bb149]; ++ } ++ ++ bb151: { ++ _81 = discriminant(_80); ++ switchInt(move _81) -> [0: bb145, 1: bb150, otherwise: bb90]; ++ } ++ ++ bb152: { ++ _80 = as Future>::poll(move _82, move _83) -> [return: bb151, unwind: bb146]; ++ } ++ ++ bb153: { ++ _84 = move _2; ++ _83 = std::future::get_context::<'_, '_>(move _84) -> [return: bb152, unwind: bb146]; ++ } ++ ++ bb154: { ++ _85 = &mut _78; ++ _82 = Pin::<&mut impl Future>::new_unchecked(move _85) -> [return: bb153, unwind: bb146]; ++ } ++ ++ bb155: { ++ _2 = move _86; ++ StorageDead(_86); ++ goto -> bb161; ++ } ++ ++ bb156: { ++ _2 = move _86; ++ StorageDead(_86); ++ goto -> bb154; ++ } ++ ++ bb157: { ++ StorageLive(_86); ++ _86 = yield(const ()) -> [resume: bb155, drop: bb156]; ++ } ++ ++ bb158: { ++ _88 = discriminant(_87); ++ switchInt(move _88) -> [0: bb144, 1: bb157, otherwise: bb90]; ++ } ++ ++ bb159: { ++ _87 = as Future>::poll(move _89, move _90) -> [return: bb158, unwind: bb146]; ++ } ++ ++ bb160: { ++ _91 = move _2; ++ _90 = std::future::get_context::<'_, '_>(move _91) -> [return: bb159, unwind: bb146]; ++ } ++ ++ bb161: { ++ _92 = &mut _78; ++ _89 = Pin::<&mut impl Future>::new_unchecked(move _92) -> [return: bb160, unwind: bb146]; ++ } ++ ++ bb162: { ++ StorageLive(_78); ++ _78 = async_drop_in_place::(copy (_93.0: &mut AsyncInt)) -> [return: bb161, unwind: bb146]; ++ } ++ ++ bb163: { ++ _94 = &mut _19; ++ _93 = Pin::<&mut AsyncInt>::new_unchecked(move _94) -> [return: bb162, unwind: bb49]; ++ } ++ ++ bb164: { ++ StorageDead(_95); ++ goto -> bb16; ++ } ++ ++ bb165: { ++ StorageDead(_95); ++ goto -> bb30; ++ } ++ ++ bb166 (cleanup): { ++ StorageDead(_95); ++ goto -> bb54; ++ } ++ ++ bb167: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb167, unwind: bb166]; ++ } ++ ++ bb168: { ++ _2 = move _96; ++ StorageDead(_96); ++ goto -> bb167; ++ } ++ ++ bb169: { ++ _2 = move _96; ++ StorageDead(_96); ++ goto -> bb174; ++ } ++ ++ bb170: { ++ StorageLive(_96); ++ _96 = yield(const ()) -> [resume: bb168, drop: bb169]; ++ } ++ ++ bb171: { ++ _98 = discriminant(_97); ++ switchInt(move _98) -> [0: bb165, 1: bb170, otherwise: bb90]; ++ } ++ ++ bb172: { ++ _97 = as Future>::poll(move _99, move _100) -> [return: bb171, unwind: bb166]; ++ } ++ ++ bb173: { ++ _101 = move _2; ++ _100 = std::future::get_context::<'_, '_>(move _101) -> [return: bb172, unwind: bb166]; ++ } ++ ++ bb174: { ++ _102 = &mut _95; ++ _99 = Pin::<&mut impl Future>::new_unchecked(move _102) -> [return: bb173, unwind: bb166]; ++ } ++ ++ bb175: { ++ _2 = move _103; ++ StorageDead(_103); ++ goto -> bb181; ++ } ++ ++ bb176: { ++ _2 = move _103; ++ StorageDead(_103); ++ goto -> bb174; ++ } ++ ++ bb177: { ++ StorageLive(_103); ++ _103 = yield(const ()) -> [resume: bb175, drop: bb176]; ++ } ++ ++ bb178: { ++ _105 = discriminant(_104); ++ switchInt(move _105) -> [0: bb164, 1: bb177, otherwise: bb90]; ++ } ++ ++ bb179: { ++ _104 = as Future>::poll(move _106, move _107) -> [return: bb178, unwind: bb166]; ++ } ++ ++ bb180: { ++ _108 = move _2; ++ _107 = std::future::get_context::<'_, '_>(move _108) -> [return: bb179, unwind: bb166]; ++ } ++ ++ bb181: { ++ _109 = &mut _95; ++ _106 = Pin::<&mut impl Future>::new_unchecked(move _109) -> [return: bb180, unwind: bb166]; ++ } ++ ++ bb182: { ++ StorageLive(_95); ++ _95 = async_drop_in_place::(copy (_110.0: &mut AsyncEnum)) -> [return: bb181, unwind: bb166]; ++ } ++ ++ bb183: { ++ _111 = &mut _15; ++ _110 = Pin::<&mut AsyncEnum>::new_unchecked(move _111) -> [return: bb182, unwind: bb54]; ++ } ++ ++ bb184: { ++ StorageDead(_112); ++ goto -> bb17; ++ } ++ ++ bb185: { ++ StorageDead(_112); ++ goto -> bb34; ++ } ++ ++ bb186 (cleanup): { ++ StorageDead(_112); ++ goto -> bb58; ++ } ++ ++ bb187: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb187, unwind: bb186]; ++ } ++ ++ bb188: { ++ _2 = move _113; ++ StorageDead(_113); ++ goto -> bb187; ++ } ++ ++ bb189: { ++ _2 = move _113; ++ StorageDead(_113); ++ goto -> bb194; ++ } ++ ++ bb190: { ++ StorageLive(_113); ++ _113 = yield(const ()) -> [resume: bb188, drop: bb189]; ++ } ++ ++ bb191: { ++ _115 = discriminant(_114); ++ switchInt(move _115) -> [0: bb185, 1: bb190, otherwise: bb90]; ++ } ++ ++ bb192: { ++ _114 = as Future>::poll(move _116, move _117) -> [return: bb191, unwind: bb186]; ++ } ++ ++ bb193: { ++ _118 = move _2; ++ _117 = std::future::get_context::<'_, '_>(move _118) -> [return: bb192, unwind: bb186]; ++ } ++ ++ bb194: { ++ _119 = &mut _112; ++ _116 = Pin::<&mut impl Future>::new_unchecked(move _119) -> [return: bb193, unwind: bb186]; ++ } ++ ++ bb195: { ++ _2 = move _120; ++ StorageDead(_120); ++ goto -> bb201; ++ } ++ ++ bb196: { ++ _2 = move _120; ++ StorageDead(_120); ++ goto -> bb194; ++ } ++ ++ bb197: { ++ StorageLive(_120); ++ _120 = yield(const ()) -> [resume: bb195, drop: bb196]; ++ } ++ ++ bb198: { ++ _122 = discriminant(_121); ++ switchInt(move _122) -> [0: bb184, 1: bb197, otherwise: bb90]; ++ } ++ ++ bb199: { ++ _121 = as Future>::poll(move _123, move _124) -> [return: bb198, unwind: bb186]; ++ } ++ ++ bb200: { ++ _125 = move _2; ++ _124 = std::future::get_context::<'_, '_>(move _125) -> [return: bb199, unwind: bb186]; ++ } ++ ++ bb201: { ++ _126 = &mut _112; ++ _123 = Pin::<&mut impl Future>::new_unchecked(move _126) -> [return: bb200, unwind: bb186]; ++ } ++ ++ bb202: { ++ StorageLive(_112); ++ _112 = async_drop_in_place::(copy (_127.0: &mut SyncThenAsync)) -> [return: bb201, unwind: bb186]; ++ } ++ ++ bb203: { ++ _128 = &mut _11; ++ _127 = Pin::<&mut SyncThenAsync>::new_unchecked(move _128) -> [return: bb202, unwind: bb58]; ++ } ++ ++ bb204: { ++ StorageDead(_129); ++ goto -> bb18; ++ } ++ ++ bb205: { ++ StorageDead(_129); ++ goto -> bb37; ++ } ++ ++ bb206 (cleanup): { ++ StorageDead(_129); ++ goto -> bb61; ++ } ++ ++ bb207: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb207, unwind: bb206]; ++ } ++ ++ bb208: { ++ _2 = move _130; ++ StorageDead(_130); ++ goto -> bb207; ++ } ++ ++ bb209: { ++ _2 = move _130; ++ StorageDead(_130); ++ goto -> bb214; ++ } ++ ++ bb210: { ++ StorageLive(_130); ++ _130 = yield(const ()) -> [resume: bb208, drop: bb209]; ++ } ++ ++ bb211: { ++ _132 = discriminant(_131); ++ switchInt(move _132) -> [0: bb205, 1: bb210, otherwise: bb90]; ++ } ++ ++ bb212: { ++ _131 = as Future>::poll(move _133, move _134) -> [return: bb211, unwind: bb206]; ++ } ++ ++ bb213: { ++ _135 = move _2; ++ _134 = std::future::get_context::<'_, '_>(move _135) -> [return: bb212, unwind: bb206]; ++ } ++ ++ bb214: { ++ _136 = &mut _129; ++ _133 = Pin::<&mut impl Future>::new_unchecked(move _136) -> [return: bb213, unwind: bb206]; ++ } ++ ++ bb215: { ++ _2 = move _137; ++ StorageDead(_137); ++ goto -> bb221; ++ } ++ ++ bb216: { ++ _2 = move _137; ++ StorageDead(_137); ++ goto -> bb214; ++ } ++ ++ bb217: { ++ StorageLive(_137); ++ _137 = yield(const ()) -> [resume: bb215, drop: bb216]; ++ } ++ ++ bb218: { ++ _139 = discriminant(_138); ++ switchInt(move _139) -> [0: bb204, 1: bb217, otherwise: bb90]; ++ } ++ ++ bb219: { ++ _138 = as Future>::poll(move _140, move _141) -> [return: bb218, unwind: bb206]; ++ } ++ ++ bb220: { ++ _142 = move _2; ++ _141 = std::future::get_context::<'_, '_>(move _142) -> [return: bb219, unwind: bb206]; ++ } ++ ++ bb221: { ++ _143 = &mut _129; ++ _140 = Pin::<&mut impl Future>::new_unchecked(move _143) -> [return: bb220, unwind: bb206]; ++ } ++ ++ bb222: { ++ StorageLive(_129); ++ _129 = async_drop_in_place::(copy (_144.0: &mut AsyncStruct)) -> [return: bb221, unwind: bb206]; ++ } ++ ++ bb223: { ++ _145 = &mut _8; ++ _144 = Pin::<&mut AsyncStruct>::new_unchecked(move _145) -> [return: bb222, unwind: bb61]; ++ } ++ ++ bb224: { ++ StorageDead(_146); ++ goto -> bb19; ++ } ++ ++ bb225: { ++ StorageDead(_146); ++ goto -> bb40; ++ } ++ ++ bb226 (cleanup): { ++ StorageDead(_146); ++ goto -> bb64; ++ } ++ ++ bb227: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb227, unwind: bb226]; ++ } ++ ++ bb228: { ++ _2 = move _147; ++ StorageDead(_147); ++ goto -> bb227; ++ } ++ ++ bb229: { ++ _2 = move _147; ++ StorageDead(_147); ++ goto -> bb234; ++ } ++ ++ bb230: { ++ StorageLive(_147); ++ _147 = yield(const ()) -> [resume: bb228, drop: bb229]; ++ } ++ ++ bb231: { ++ _149 = discriminant(_148); ++ switchInt(move _149) -> [0: bb225, 1: bb230, otherwise: bb90]; ++ } ++ ++ bb232: { ++ _148 = as Future>::poll(move _150, move _151) -> [return: bb231, unwind: bb226]; ++ } ++ ++ bb233: { ++ _152 = move _2; ++ _151 = std::future::get_context::<'_, '_>(move _152) -> [return: bb232, unwind: bb226]; ++ } ++ ++ bb234: { ++ _153 = &mut _146; ++ _150 = Pin::<&mut impl Future>::new_unchecked(move _153) -> [return: bb233, unwind: bb226]; ++ } ++ ++ bb235: { ++ _2 = move _154; ++ StorageDead(_154); ++ goto -> bb241; ++ } ++ ++ bb236: { ++ _2 = move _154; ++ StorageDead(_154); ++ goto -> bb234; ++ } ++ ++ bb237: { ++ StorageLive(_154); ++ _154 = yield(const ()) -> [resume: bb235, drop: bb236]; ++ } ++ ++ bb238: { ++ _156 = discriminant(_155); ++ switchInt(move _156) -> [0: bb224, 1: bb237, otherwise: bb90]; ++ } ++ ++ bb239: { ++ _155 = as Future>::poll(move _157, move _158) -> [return: bb238, unwind: bb226]; ++ } ++ ++ bb240: { ++ _159 = move _2; ++ _158 = std::future::get_context::<'_, '_>(move _159) -> [return: bb239, unwind: bb226]; ++ } ++ ++ bb241: { ++ _160 = &mut _146; ++ _157 = Pin::<&mut impl Future>::new_unchecked(move _160) -> [return: bb240, unwind: bb226]; ++ } ++ ++ bb242: { ++ StorageLive(_146); ++ _146 = async_drop_in_place::<[AsyncInt; 2]>(copy (_161.0: &mut [AsyncInt; 2])) -> [return: bb241, unwind: bb226]; ++ } ++ ++ bb243: { ++ _162 = &mut _5; ++ _161 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _162) -> [return: bb242, unwind: bb64]; ++ } ++ ++ bb244: { ++ StorageDead(_163); ++ goto -> bb20; ++ } ++ ++ bb245: { ++ StorageDead(_163); ++ goto -> bb41; ++ } ++ ++ bb246 (cleanup): { ++ StorageDead(_163); ++ goto -> bb65; ++ } ++ ++ bb247: { ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb247, unwind: bb246]; ++ } ++ ++ bb248: { ++ _2 = move _164; ++ StorageDead(_164); ++ goto -> bb247; ++ } ++ ++ bb249: { ++ _2 = move _164; ++ StorageDead(_164); ++ goto -> bb254; ++ } ++ ++ bb250: { ++ StorageLive(_164); ++ _164 = yield(const ()) -> [resume: bb248, drop: bb249]; ++ } ++ ++ bb251: { ++ _166 = discriminant(_165); ++ switchInt(move _166) -> [0: bb245, 1: bb250, otherwise: bb90]; ++ } ++ ++ bb252: { ++ _165 = as Future>::poll(move _167, move _168) -> [return: bb251, unwind: bb246]; ++ } ++ ++ bb253: { ++ _169 = move _2; ++ _168 = std::future::get_context::<'_, '_>(move _169) -> [return: bb252, unwind: bb246]; ++ } ++ ++ bb254: { ++ _170 = &mut _163; ++ _167 = Pin::<&mut impl Future>::new_unchecked(move _170) -> [return: bb253, unwind: bb246]; ++ } ++ ++ bb255: { ++ _2 = move _171; ++ StorageDead(_171); ++ goto -> bb261; ++ } ++ ++ bb256: { ++ _2 = move _171; ++ StorageDead(_171); ++ goto -> bb254; ++ } ++ ++ bb257: { ++ StorageLive(_171); ++ _171 = yield(const ()) -> [resume: bb255, drop: bb256]; ++ } ++ ++ bb258: { ++ _173 = discriminant(_172); ++ switchInt(move _173) -> [0: bb244, 1: bb257, otherwise: bb90]; ++ } ++ ++ bb259: { ++ _172 = as Future>::poll(move _174, move _175) -> [return: bb258, unwind: bb246]; ++ } ++ ++ bb260: { ++ _176 = move _2; ++ _175 = std::future::get_context::<'_, '_>(move _176) -> [return: bb259, unwind: bb246]; ++ } ++ ++ bb261: { ++ _177 = &mut _163; ++ _174 = Pin::<&mut impl Future>::new_unchecked(move _177) -> [return: bb260, unwind: bb246]; ++ } ++ ++ bb262: { ++ StorageLive(_163); ++ _163 = async_drop_in_place::(copy (_178.0: &mut AsyncInt)) -> [return: bb261, unwind: bb246]; ++ } ++ ++ bb263: { ++ _179 = &mut _4; ++ _178 = Pin::<&mut AsyncInt>::new_unchecked(move _179) -> [return: bb262, unwind: bb65]; } } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff index 12fd87a786c29..b0e6100e78fe0 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff @@ -15,8 +15,8 @@ + field _s6: AsyncEnum; + field _s7: AsyncInt; + field _s8: AsyncReference<'_>; -+ field _s9: {closure@$DIR/async_drop.rs:72:25: 72:27}; -+ field _s10: {async closure@$DIR/async_drop.rs:80:27: 80:35}; ++ field _s9: {closure@$DIR/async_drop.rs:70:25: 70:27}; ++ field _s10: {async closure@$DIR/async_drop.rs:78:27: 78:35}; + field _s11: impl Future; + field _s12: impl Future; + field _s13: impl Future; @@ -30,24 +30,24 @@ + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], -+ Suspend0 (3): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11], -+ Suspend1 (4): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11], -+ Suspend2 (5): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s12], -+ Suspend3 (6): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s12], -+ Suspend4 (7): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s13], -+ Suspend5 (8): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s13], -+ Suspend6 (9): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s14], -+ Suspend7 (10): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s14], -+ Suspend8 (11): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s15], -+ Suspend9 (12): [_s1, _s2, _s3, _s4, _s5, _s6, _s15], -+ Suspend10(13): [_s0, _s1, _s2, _s3, _s4, _s5, _s16], -+ Suspend11(14): [_s1, _s2, _s3, _s4, _s5, _s16], -+ Suspend12(15): [_s0, _s1, _s2, _s3, _s4, _s17], -+ Suspend13(16): [_s1, _s2, _s3, _s4, _s17], -+ Suspend14(17): [_s0, _s1, _s2, _s3, _s18], -+ Suspend15(18): [_s1, _s2, _s3, _s18], -+ Suspend16(19): [_s0, _s1, _s2, _s19], -+ Suspend17(20): [_s1, _s2, _s19], ++ Suspend0 (3): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11], ++ Suspend1 (4): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11], ++ Suspend2 (5): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s12], ++ Suspend3 (6): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s12], ++ Suspend4 (7): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s13], ++ Suspend5 (8): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s13], ++ Suspend6 (9): [_s1, _s2, _s3, _s4, _s5, _s6, _s7, _s14], ++ Suspend7 (10): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s14], ++ Suspend8 (11): [_s1, _s2, _s3, _s4, _s5, _s6, _s15], ++ Suspend9 (12): [_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s15], ++ Suspend10(13): [_s1, _s2, _s3, _s4, _s5, _s16], ++ Suspend11(14): [_s0, _s1, _s2, _s3, _s4, _s5, _s16], ++ Suspend12(15): [_s1, _s2, _s3, _s4, _s17], ++ Suspend13(16): [_s0, _s1, _s2, _s3, _s4, _s17], ++ Suspend14(17): [_s1, _s2, _s3, _s18], ++ Suspend15(18): [_s0, _s1, _s2, _s3, _s18], ++ Suspend16(19): [_s1, _s2, _s19], ++ Suspend17(20): [_s0, _s1, _s2, _s19], + } + storage_conflicts = BitMatrix(20x20) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s0, _s4), (_s0, _s5), (_s0, _s6), (_s0, _s7), (_s0, _s8), (_s0, _s9), (_s0, _s10), (_s0, _s11), (_s0, _s12), (_s0, _s13), (_s0, _s14), (_s0, _s15), (_s0, _s16), (_s0, _s17), (_s0, _s18), (_s0, _s19), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s1, _s4), (_s1, _s5), (_s1, _s6), (_s1, _s7), (_s1, _s8), (_s1, _s9), (_s1, _s10), (_s1, _s11), (_s1, _s12), (_s1, _s13), (_s1, _s14), (_s1, _s15), (_s1, _s16), (_s1, _s17), (_s1, _s18), (_s1, _s19), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s2, _s4), (_s2, _s5), (_s2, _s6), (_s2, _s7), (_s2, _s8), (_s2, _s9), (_s2, _s10), (_s2, _s11), (_s2, _s12), (_s2, _s13), (_s2, _s14), (_s2, _s15), (_s2, _s16), (_s2, _s17), (_s2, _s18), (_s2, _s19), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3), (_s3, _s4), (_s3, _s5), (_s3, _s6), (_s3, _s7), (_s3, _s8), (_s3, _s9), (_s3, _s10), (_s3, _s11), (_s3, _s12), (_s3, _s13), (_s3, _s14), (_s3, _s15), (_s3, _s16), (_s3, _s17), (_s3, _s18), (_s4, _s0), (_s4, _s1), (_s4, _s2), (_s4, _s3), (_s4, _s4), (_s4, _s5), (_s4, _s6), (_s4, _s7), (_s4, _s8), (_s4, _s9), (_s4, _s10), (_s4, _s11), (_s4, _s12), (_s4, _s13), (_s4, _s14), (_s4, _s15), (_s4, _s16), (_s4, _s17), (_s5, _s0), (_s5, _s1), (_s5, _s2), (_s5, _s3), (_s5, _s4), (_s5, _s5), (_s5, _s6), (_s5, _s7), (_s5, _s8), (_s5, _s9), (_s5, _s10), (_s5, _s11), (_s5, _s12), (_s5, _s13), (_s5, _s14), (_s5, _s15), (_s5, _s16), (_s6, _s0), (_s6, _s1), (_s6, _s2), (_s6, _s3), (_s6, _s4), (_s6, _s5), (_s6, _s6), (_s6, _s7), (_s6, _s8), (_s6, _s9), (_s6, _s10), (_s6, _s11), (_s6, _s12), (_s6, _s13), (_s6, _s14), (_s6, _s15), (_s7, _s0), (_s7, _s1), (_s7, _s2), (_s7, _s3), (_s7, _s4), (_s7, _s5), (_s7, _s6), (_s7, _s7), (_s7, _s8), (_s7, _s9), (_s7, _s10), (_s7, _s11), (_s7, _s12), (_s7, _s13), (_s7, _s14), (_s8, _s0), (_s8, _s1), (_s8, _s2), (_s8, _s3), (_s8, _s4), (_s8, _s5), (_s8, _s6), (_s8, _s7), (_s8, _s8), (_s8, _s9), (_s8, _s10), (_s8, _s11), (_s8, _s12), (_s8, _s13), (_s9, _s0), (_s9, _s1), (_s9, _s2), (_s9, _s3), (_s9, _s4), (_s9, _s5), (_s9, _s6), (_s9, _s7), (_s9, _s8), (_s9, _s9), (_s9, _s10), (_s9, _s11), (_s9, _s12), (_s10, _s0), (_s10, _s1), (_s10, _s2), (_s10, _s3), (_s10, _s4), (_s10, _s5), (_s10, _s6), (_s10, _s7), (_s10, _s8), (_s10, _s9), (_s10, _s10), (_s10, _s11), (_s11, _s0), (_s11, _s1), (_s11, _s2), (_s11, _s3), (_s11, _s4), (_s11, _s5), (_s11, _s6), (_s11, _s7), (_s11, _s8), (_s11, _s9), (_s11, _s10), (_s11, _s11), (_s12, _s0), (_s12, _s1), (_s12, _s2), (_s12, _s3), (_s12, _s4), (_s12, _s5), (_s12, _s6), (_s12, _s7), (_s12, _s8), (_s12, _s9), (_s12, _s12), (_s13, _s0), (_s13, _s1), (_s13, _s2), (_s13, _s3), (_s13, _s4), (_s13, _s5), (_s13, _s6), (_s13, _s7), (_s13, _s8), (_s13, _s13), (_s14, _s0), (_s14, _s1), (_s14, _s2), (_s14, _s3), (_s14, _s4), (_s14, _s5), (_s14, _s6), (_s14, _s7), (_s14, _s14), (_s15, _s0), (_s15, _s1), (_s15, _s2), (_s15, _s3), (_s15, _s4), (_s15, _s5), (_s15, _s6), (_s15, _s15), (_s16, _s0), (_s16, _s1), (_s16, _s2), (_s16, _s3), (_s16, _s4), (_s16, _s5), (_s16, _s16), (_s17, _s0), (_s17, _s1), (_s17, _s2), (_s17, _s3), (_s17, _s4), (_s17, _s17), (_s18, _s0), (_s18, _s1), (_s18, _s2), (_s18, _s3), (_s18, _s18), (_s19, _s0), (_s19, _s1), (_s19, _s2), (_s19, _s19)} + } @@ -68,147 +68,225 @@ let mut _21: &AsyncInt; let _22: &AsyncInt; let mut _27: impl std::future::Future; - let mut _28: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>; - let mut _29: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35}; - let mut _30: impl std::future::Future; - let mut _31: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>; - let mut _32: &mut {closure@$DIR/async_drop.rs:72:25: 72:27}; - let mut _33: impl std::future::Future; - let mut _34: std::pin::Pin<&mut AsyncReference<'_>>; - let mut _35: &mut AsyncReference<'_>; - let mut _36: impl std::future::Future; - let mut _37: std::pin::Pin<&mut AsyncInt>; - let mut _38: &mut AsyncInt; - let mut _39: impl std::future::Future; - let mut _40: std::pin::Pin<&mut AsyncEnum>; - let mut _41: &mut AsyncEnum; - let mut _42: impl std::future::Future; - let mut _43: std::pin::Pin<&mut SyncThenAsync>; - let mut _44: &mut SyncThenAsync; - let mut _45: impl std::future::Future; - let mut _46: std::pin::Pin<&mut AsyncStruct>; - let mut _47: &mut AsyncStruct; - let mut _48: impl std::future::Future; - let mut _49: std::pin::Pin<&mut [AsyncInt; 2]>; - let mut _50: &mut [AsyncInt; 2]; - let mut _51: impl std::future::Future; - let mut _52: std::pin::Pin<&mut AsyncInt>; - let mut _53: &mut AsyncInt; - let mut _54: impl std::future::Future; - let mut _55: std::pin::Pin<&mut {async fn body of elaborate_drops()}>; - let mut _56: &mut {async fn body of elaborate_drops()}; -+ let mut _57: std::task::Poll<()>; -+ let mut _58: &mut std::task::Context<'_>; -+ let mut _59: &mut impl std::future::Future; -+ let mut _60: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _61: isize; +- let mut _28: std::future::ResumeTy; ++ let mut _28: &mut std::task::Context<'_>; + let mut _29: std::task::Poll<()>; + let mut _30: isize; + let mut _31: std::pin::Pin<&mut impl std::future::Future>; + let mut _32: &mut std::task::Context<'_>; +- let mut _33: std::future::ResumeTy; ++ let mut _33: &mut std::task::Context<'_>; + let mut _34: &mut impl std::future::Future; +- let mut _35: std::future::ResumeTy; ++ let mut _35: &mut std::task::Context<'_>; + let mut _36: std::task::Poll<()>; + let mut _37: isize; + let mut _38: std::pin::Pin<&mut impl std::future::Future>; + let mut _39: &mut std::task::Context<'_>; +- let mut _40: std::future::ResumeTy; ++ let mut _40: &mut std::task::Context<'_>; + let mut _41: &mut impl std::future::Future; + let mut _42: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:78:27: 78:35}>; + let mut _43: &mut {async closure@$DIR/async_drop.rs:78:27: 78:35}; + let mut _44: impl std::future::Future; +- let mut _45: std::future::ResumeTy; ++ let mut _45: &mut std::task::Context<'_>; + let mut _46: std::task::Poll<()>; + let mut _47: isize; + let mut _48: std::pin::Pin<&mut impl std::future::Future>; + let mut _49: &mut std::task::Context<'_>; +- let mut _50: std::future::ResumeTy; ++ let mut _50: &mut std::task::Context<'_>; + let mut _51: &mut impl std::future::Future; +- let mut _52: std::future::ResumeTy; ++ let mut _52: &mut std::task::Context<'_>; + let mut _53: std::task::Poll<()>; + let mut _54: isize; + let mut _55: std::pin::Pin<&mut impl std::future::Future>; + let mut _56: &mut std::task::Context<'_>; +- let mut _57: std::future::ResumeTy; ++ let mut _57: &mut std::task::Context<'_>; + let mut _58: &mut impl std::future::Future; + let mut _59: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:70:25: 70:27}>; + let mut _60: &mut {closure@$DIR/async_drop.rs:70:25: 70:27}; + let mut _61: impl std::future::Future; +- let mut _62: std::future::ResumeTy; + let mut _62: &mut std::task::Context<'_>; -+ let mut _63: &mut impl std::future::Future; -+ let mut _64: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _65: isize; -+ let mut _66: std::task::Poll<()>; + let mut _63: std::task::Poll<()>; + let mut _64: isize; + let mut _65: std::pin::Pin<&mut impl std::future::Future>; + let mut _66: &mut std::task::Context<'_>; +- let mut _67: std::future::ResumeTy; + let mut _67: &mut std::task::Context<'_>; -+ let mut _68: &mut impl std::future::Future; -+ let mut _69: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _70: isize; -+ let mut _71: &mut std::task::Context<'_>; -+ let mut _72: &mut impl std::future::Future; -+ let mut _73: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _74: isize; -+ let mut _75: std::task::Poll<()>; -+ let mut _76: &mut std::task::Context<'_>; -+ let mut _77: &mut impl std::future::Future; -+ let mut _78: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _79: isize; -+ let mut _80: &mut std::task::Context<'_>; -+ let mut _81: &mut impl std::future::Future; -+ let mut _82: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _83: isize; -+ let mut _84: std::task::Poll<()>; -+ let mut _85: &mut std::task::Context<'_>; -+ let mut _86: &mut impl std::future::Future; -+ let mut _87: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _88: isize; -+ let mut _89: &mut std::task::Context<'_>; -+ let mut _90: &mut impl std::future::Future; -+ let mut _91: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _92: isize; -+ let mut _93: std::task::Poll<()>; -+ let mut _94: &mut std::task::Context<'_>; -+ let mut _95: &mut impl std::future::Future; -+ let mut _96: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _97: isize; -+ let mut _98: &mut std::task::Context<'_>; -+ let mut _99: &mut impl std::future::Future; -+ let mut _100: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _101: isize; -+ let mut _102: std::task::Poll<()>; + let mut _68: &mut impl std::future::Future; +- let mut _69: std::future::ResumeTy; ++ let mut _69: &mut std::task::Context<'_>; + let mut _70: std::task::Poll<()>; + let mut _71: isize; + let mut _72: std::pin::Pin<&mut impl std::future::Future>; + let mut _73: &mut std::task::Context<'_>; +- let mut _74: std::future::ResumeTy; ++ let mut _74: &mut std::task::Context<'_>; + let mut _75: &mut impl std::future::Future; + let mut _76: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _77: &mut AsyncReference<'_>; + let mut _78: impl std::future::Future; +- let mut _79: std::future::ResumeTy; ++ let mut _79: &mut std::task::Context<'_>; + let mut _80: std::task::Poll<()>; + let mut _81: isize; + let mut _82: std::pin::Pin<&mut impl std::future::Future>; + let mut _83: &mut std::task::Context<'_>; +- let mut _84: std::future::ResumeTy; ++ let mut _84: &mut std::task::Context<'_>; + let mut _85: &mut impl std::future::Future; +- let mut _86: std::future::ResumeTy; ++ let mut _86: &mut std::task::Context<'_>; + let mut _87: std::task::Poll<()>; + let mut _88: isize; + let mut _89: std::pin::Pin<&mut impl std::future::Future>; + let mut _90: &mut std::task::Context<'_>; +- let mut _91: std::future::ResumeTy; ++ let mut _91: &mut std::task::Context<'_>; + let mut _92: &mut impl std::future::Future; + let mut _93: std::pin::Pin<&mut AsyncInt>; + let mut _94: &mut AsyncInt; + let mut _95: impl std::future::Future; +- let mut _96: std::future::ResumeTy; ++ let mut _96: &mut std::task::Context<'_>; + let mut _97: std::task::Poll<()>; + let mut _98: isize; + let mut _99: std::pin::Pin<&mut impl std::future::Future>; + let mut _100: &mut std::task::Context<'_>; +- let mut _101: std::future::ResumeTy; ++ let mut _101: &mut std::task::Context<'_>; + let mut _102: &mut impl std::future::Future; +- let mut _103: std::future::ResumeTy; + let mut _103: &mut std::task::Context<'_>; -+ let mut _104: &mut impl std::future::Future; -+ let mut _105: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _106: isize; -+ let mut _107: &mut std::task::Context<'_>; -+ let mut _108: &mut impl std::future::Future; -+ let mut _109: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _110: isize; -+ let mut _111: std::task::Poll<()>; -+ let mut _112: &mut std::task::Context<'_>; -+ let mut _113: &mut impl std::future::Future; -+ let mut _114: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _115: isize; -+ let mut _116: &mut std::task::Context<'_>; -+ let mut _117: &mut impl std::future::Future; -+ let mut _118: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _119: isize; -+ let mut _120: std::task::Poll<()>; -+ let mut _121: &mut std::task::Context<'_>; -+ let mut _122: &mut impl std::future::Future; -+ let mut _123: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _124: isize; + let mut _104: std::task::Poll<()>; + let mut _105: isize; + let mut _106: std::pin::Pin<&mut impl std::future::Future>; + let mut _107: &mut std::task::Context<'_>; +- let mut _108: std::future::ResumeTy; ++ let mut _108: &mut std::task::Context<'_>; + let mut _109: &mut impl std::future::Future; + let mut _110: std::pin::Pin<&mut AsyncEnum>; + let mut _111: &mut AsyncEnum; + let mut _112: impl std::future::Future; +- let mut _113: std::future::ResumeTy; ++ let mut _113: &mut std::task::Context<'_>; + let mut _114: std::task::Poll<()>; + let mut _115: isize; + let mut _116: std::pin::Pin<&mut impl std::future::Future>; + let mut _117: &mut std::task::Context<'_>; +- let mut _118: std::future::ResumeTy; ++ let mut _118: &mut std::task::Context<'_>; + let mut _119: &mut impl std::future::Future; +- let mut _120: std::future::ResumeTy; ++ let mut _120: &mut std::task::Context<'_>; + let mut _121: std::task::Poll<()>; + let mut _122: isize; + let mut _123: std::pin::Pin<&mut impl std::future::Future>; + let mut _124: &mut std::task::Context<'_>; +- let mut _125: std::future::ResumeTy; + let mut _125: &mut std::task::Context<'_>; -+ let mut _126: &mut impl std::future::Future; -+ let mut _127: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _128: isize; -+ let mut _129: std::task::Poll<()>; + let mut _126: &mut impl std::future::Future; + let mut _127: std::pin::Pin<&mut SyncThenAsync>; + let mut _128: &mut SyncThenAsync; + let mut _129: impl std::future::Future; +- let mut _130: std::future::ResumeTy; + let mut _130: &mut std::task::Context<'_>; -+ let mut _131: &mut impl std::future::Future; -+ let mut _132: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _133: isize; -+ let mut _134: &mut std::task::Context<'_>; -+ let mut _135: &mut impl std::future::Future; -+ let mut _136: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _137: isize; -+ let mut _138: (); -+ let mut _139: u32; -+ let mut _140: &mut {async fn body of elaborate_drops()}; + let mut _131: std::task::Poll<()>; + let mut _132: isize; + let mut _133: std::pin::Pin<&mut impl std::future::Future>; + let mut _134: &mut std::task::Context<'_>; +- let mut _135: std::future::ResumeTy; ++ let mut _135: &mut std::task::Context<'_>; + let mut _136: &mut impl std::future::Future; +- let mut _137: std::future::ResumeTy; ++ let mut _137: &mut std::task::Context<'_>; + let mut _138: std::task::Poll<()>; + let mut _139: isize; + let mut _140: std::pin::Pin<&mut impl std::future::Future>; + let mut _141: &mut std::task::Context<'_>; +- let mut _142: std::future::ResumeTy; ++ let mut _142: &mut std::task::Context<'_>; + let mut _143: &mut impl std::future::Future; + let mut _144: std::pin::Pin<&mut AsyncStruct>; + let mut _145: &mut AsyncStruct; + let mut _146: impl std::future::Future; +- let mut _147: std::future::ResumeTy; ++ let mut _147: &mut std::task::Context<'_>; + let mut _148: std::task::Poll<()>; + let mut _149: isize; + let mut _150: std::pin::Pin<&mut impl std::future::Future>; + let mut _151: &mut std::task::Context<'_>; +- let mut _152: std::future::ResumeTy; ++ let mut _152: &mut std::task::Context<'_>; + let mut _153: &mut impl std::future::Future; +- let mut _154: std::future::ResumeTy; ++ let mut _154: &mut std::task::Context<'_>; + let mut _155: std::task::Poll<()>; + let mut _156: isize; + let mut _157: std::pin::Pin<&mut impl std::future::Future>; + let mut _158: &mut std::task::Context<'_>; +- let mut _159: std::future::ResumeTy; ++ let mut _159: &mut std::task::Context<'_>; + let mut _160: &mut impl std::future::Future; + let mut _161: std::pin::Pin<&mut [AsyncInt; 2]>; + let mut _162: &mut [AsyncInt; 2]; + let mut _163: impl std::future::Future; +- let mut _164: std::future::ResumeTy; ++ let mut _164: &mut std::task::Context<'_>; + let mut _165: std::task::Poll<()>; + let mut _166: isize; + let mut _167: std::pin::Pin<&mut impl std::future::Future>; + let mut _168: &mut std::task::Context<'_>; +- let mut _169: std::future::ResumeTy; ++ let mut _169: &mut std::task::Context<'_>; + let mut _170: &mut impl std::future::Future; +- let mut _171: std::future::ResumeTy; ++ let mut _171: &mut std::task::Context<'_>; + let mut _172: std::task::Poll<()>; + let mut _173: isize; + let mut _174: std::pin::Pin<&mut impl std::future::Future>; + let mut _175: &mut std::task::Context<'_>; +- let mut _176: std::future::ResumeTy; ++ let mut _176: &mut std::task::Context<'_>; + let mut _177: &mut impl std::future::Future; + let mut _178: std::pin::Pin<&mut AsyncInt>; + let mut _179: &mut AsyncInt; ++ let mut _180: (); ++ let mut _181: u32; ++ let mut _182: &mut {async fn body of elaborate_drops()}; scope 1 { - debug sync_int => _3; -+ debug sync_int => (((*_140) as variant#20).0: SyncInt); ++ debug sync_int => (((*_182) as variant#20).1: SyncInt); + coroutine debug async_int => _s2; let _4: AsyncInt; scope 2 { - debug async_int => _4; -+ debug async_int => (((*_140) as variant#20).1: AsyncInt); ++ debug async_int => (((*_182) as variant#20).2: AsyncInt); + coroutine debug tuple => _s3; let _5: [AsyncInt; 2]; scope 3 { - debug tuple => _5; -+ debug tuple => (((*_140) as variant#18).2: [AsyncInt; 2]); ++ debug tuple => (((*_182) as variant#18).3: [AsyncInt; 2]); + coroutine debug async_struct => _s4; let _8: AsyncStruct; scope 4 { - debug async_struct => _8; -+ debug async_struct => (((*_140) as variant#16).3: AsyncStruct); ++ debug async_struct => (((*_182) as variant#16).4: AsyncStruct); + coroutine debug async_struct_mix => _s5; let _11: SyncThenAsync; scope 5 { - debug async_struct_mix => _11; -+ debug async_struct_mix => (((*_140) as variant#14).4: SyncThenAsync); ++ debug async_struct_mix => (((*_182) as variant#14).5: SyncThenAsync); + coroutine debug async_enum => _s6; let _15: AsyncEnum; scope 6 { - debug async_enum => _15; -+ debug async_enum => (((*_140) as variant#12).5: AsyncEnum); ++ debug async_enum => (((*_182) as variant#12).6: AsyncEnum); let _17: std::mem::ManuallyDrop; scope 7 { debug manually_drop_async_int => _17; @@ -216,28 +294,28 @@ let _19: AsyncInt; scope 8 { - debug foo => _19; -+ debug foo => (((*_140) as variant#10).6: AsyncInt); ++ debug foo => (((*_182) as variant#10).7: AsyncInt); + coroutine debug async_ref => _s8; let _20: AsyncReference<'_>; scope 9 { - debug async_ref => _20; -+ debug async_ref => (((*_140) as variant#8).7: AsyncReference<'_>); ++ debug async_ref => (((*_182) as variant#8).8: AsyncReference<'_>); let _23: AsyncInt; scope 10 { debug foo => _23; + coroutine debug async_closure => _s9; - let _24: {closure@$DIR/async_drop.rs:72:25: 72:27}; + let _24: {closure@$DIR/async_drop.rs:70:25: 70:27}; scope 11 { - debug async_closure => _24; -+ debug async_closure => (((*_140) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); ++ debug async_closure => (((*_182) as variant#6).9: {closure@$DIR/async_drop.rs:70:25: 70:27}); let _25: AsyncInt; scope 12 { debug foo => _25; + coroutine debug async_coroutine => _s10; - let _26: {async closure@$DIR/async_drop.rs:80:27: 80:35}; + let _26: {async closure@$DIR/async_drop.rs:78:27: 78:35}; scope 13 { - debug async_coroutine => _26; -+ debug async_coroutine => (((*_140) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); ++ debug async_coroutine => (((*_182) as variant#4).10: {async closure@$DIR/async_drop.rs:78:27: 78:35}); } } } @@ -264,9 +342,9 @@ - _7 = AsyncInt(const 2_i32); - _5 = [move _6, move _7]; - goto -> bb1; -+ _140 = copy (_1.0: &mut {async fn body of elaborate_drops()}); -+ _139 = discriminant((*_140)); -+ switchInt(move _139) -> [0: bb157, 1: bb156, 2: bb155, 3: bb137, 4: bb138, 5: bb139, 6: bb140, 7: bb141, 8: bb142, 9: bb143, 10: bb144, 11: bb145, 12: bb146, 13: bb147, 14: bb148, 15: bb149, 16: bb150, 17: bb151, 18: bb152, 19: bb153, 20: bb154, otherwise: bb91]; ++ _182 = copy (_1.0: &mut {async fn body of elaborate_drops()}); ++ _181 = discriminant((*_182)); ++ switchInt(move _181) -> [0: bb170, 1: bb169, 2: bb168, 3: bb150, 4: bb151, 5: bb152, 6: bb153, 7: bb154, 8: bb155, 9: bb156, 10: bb157, 11: bb158, 12: bb159, 13: bb160, 14: bb161, 15: bb162, 16: bb163, 17: bb164, 18: bb165, 19: bb166, 20: bb167, otherwise: bb43]; } bb1: { @@ -283,7 +361,7 @@ StorageLive(_10); _10 = AsyncInt(const 4_i32); - _8 = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; -+ (((*_140) as variant#16).3: AsyncStruct) = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; ++ (((*_182) as variant#16).4: AsyncStruct) = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; goto -> bb3; } @@ -303,7 +381,7 @@ StorageLive(_14); _14 = AsyncInt(const 9_i32); - _11 = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; -+ (((*_140) as variant#14).4: SyncThenAsync) = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; ++ (((*_182) as variant#14).5: SyncThenAsync) = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; goto -> bb5; } @@ -324,7 +402,7 @@ StorageLive(_16); _16 = AsyncInt(const 10_i32); - _15 = AsyncEnum::A(move _16); -+ (((*_140) as variant#12).5: AsyncEnum) = AsyncEnum::A(move _16); ++ (((*_182) as variant#12).6: AsyncEnum) = AsyncEnum::A(move _16); goto -> bb8; } @@ -343,33 +421,33 @@ - _19 = AsyncInt(const 12_i32); - StorageLive(_20); + nop; -+ (((*_140) as variant#10).6: AsyncInt) = AsyncInt(const 12_i32); ++ (((*_182) as variant#10).7: AsyncInt) = AsyncInt(const 12_i32); + nop; StorageLive(_21); StorageLive(_22); - _22 = &_19; -+ _22 = &(((*_140) as variant#10).6: AsyncInt); ++ _22 = &(((*_182) as variant#10).7: AsyncInt); _21 = &(*_22); - _20 = AsyncReference::<'_> { foo: move _21 }; -+ (((*_140) as variant#8).7: AsyncReference<'_>) = AsyncReference::<'_> { foo: move _21 }; ++ (((*_182) as variant#8).8: AsyncReference<'_>) = AsyncReference::<'_> { foo: move _21 }; StorageDead(_21); StorageDead(_22); StorageLive(_23); _23 = AsyncInt(const 14_i32); - StorageLive(_24); -- _24 = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; +- _24 = {closure@$DIR/async_drop.rs:70:25: 70:27} { foo: move _23 }; + nop; -+ (((*_140) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}) = {closure@$DIR/async_drop.rs:72:25: 72:27} { foo: move _23 }; ++ (((*_182) as variant#6).9: {closure@$DIR/async_drop.rs:70:25: 70:27}) = {closure@$DIR/async_drop.rs:70:25: 70:27} { foo: move _23 }; StorageLive(_25); _25 = AsyncInt(const 15_i32); - StorageLive(_26); -- _26 = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; +- _26 = {closure@$DIR/async_drop.rs:78:27: 78:35} { foo: move _25 }; - _0 = const (); -- goto -> bb57; +- goto -> bb72; + nop; -+ (((*_140) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}) = {closure@$DIR/async_drop.rs:80:27: 80:35} { foo: move _25 }; -+ (((*_140) as variant#19).0: ()) = const (); -+ goto -> bb43; ++ (((*_182) as variant#4).10: {async closure@$DIR/async_drop.rs:78:27: 78:35}) = {closure@$DIR/async_drop.rs:78:27: 78:35} { foo: move _25 }; ++ (((*_182) as variant#20).0: ()) = const (); ++ goto -> bb51; } bb10: { @@ -380,8 +458,8 @@ bb11: { StorageDead(_25); -- goto -> bb63; -+ goto -> bb48; +- goto -> bb92; ++ goto -> bb63; } bb12: { @@ -392,70 +470,70 @@ bb13: { StorageDead(_23); -- goto -> bb69; -+ goto -> bb53; +- goto -> bb112; ++ goto -> bb75; } bb14: { - StorageDead(_20); -- goto -> bb75; +- goto -> bb132; + nop; -+ goto -> bb58; ++ goto -> bb87; } bb15: { - StorageDead(_19); + nop; StorageDead(_17); -- goto -> bb81; -+ goto -> bb63; +- goto -> bb152; ++ goto -> bb99; } bb16: { - StorageDead(_15); -- goto -> bb87; +- goto -> bb172; + nop; -+ goto -> bb68; ++ goto -> bb111; } bb17: { - StorageDead(_11); -- goto -> bb93; +- goto -> bb192; + nop; -+ goto -> bb73; ++ goto -> bb123; } bb18: { - StorageDead(_8); -- goto -> bb99; +- goto -> bb212; + nop; -+ goto -> bb78; ++ goto -> bb135; } bb19: { - StorageDead(_5); -- goto -> bb105; +- goto -> bb232; + nop; -+ goto -> bb83; ++ goto -> bb147; } bb20: { - StorageDead(_4); - drop(_3) -> [return: bb21, unwind: bb50]; + nop; -+ drop((((*_140) as variant#20).0: SyncInt)) -> [return: bb21, unwind: bb37]; ++ drop((((*_182) as variant#20).1: SyncInt)) -> [return: bb21, unwind: bb37]; } bb21: { - StorageDead(_3); -- goto -> bb111; +- drop(_1) -> [return: bb22, unwind: bb51]; + nop; -+ goto -> bb88; ++ goto -> bb148; } bb22: { -+ _0 = Poll::<()>::Ready(move (((*_140) as variant#19).0: ())); -+ discriminant((*_140)) = 1; ++ _0 = Poll::<()>::Ready(move (((*_182) as variant#20).0: ())); ++ discriminant((*_182)) = 1; return; } @@ -470,7 +548,7 @@ + bb24 (cleanup): { StorageDead(_25); - goto -> bb25; -+ drop((((*_140) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb25, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#6).9: {closure@$DIR/async_drop.rs:70:25: 70:27})) -> [return: bb25, unwind terminate(cleanup)]; } - bb25: { @@ -484,7 +562,7 @@ + bb26 (cleanup): { StorageDead(_23); - goto -> bb27; -+ drop((((*_140) as variant#8).7: AsyncReference<'_>)) -> [return: bb27, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#8).8: AsyncReference<'_>)) -> [return: bb27, unwind terminate(cleanup)]; } - bb27: { @@ -492,7 +570,7 @@ - goto -> bb28; + bb27 (cleanup): { + nop; -+ drop((((*_140) as variant#10).6: AsyncInt)) -> [return: bb28, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#10).7: AsyncInt)) -> [return: bb28, unwind terminate(cleanup)]; } - bb28: { @@ -522,7 +600,7 @@ - goto -> bb32; + bb31 (cleanup): { + StorageDead(_17); -+ drop((((*_140) as variant#12).5: AsyncEnum)) -> [return: bb32, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#12).6: AsyncEnum)) -> [return: bb32, unwind terminate(cleanup)]; } - bb32: { @@ -530,7 +608,7 @@ - goto -> bb33; + bb32 (cleanup): { + nop; -+ drop((((*_140) as variant#14).4: SyncThenAsync)) -> [return: bb33, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#14).5: SyncThenAsync)) -> [return: bb33, unwind terminate(cleanup)]; } - bb33: { @@ -538,7 +616,7 @@ - goto -> bb34; + bb33 (cleanup): { + nop; -+ drop((((*_140) as variant#16).3: AsyncStruct)) -> [return: bb34, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#16).4: AsyncStruct)) -> [return: bb34, unwind terminate(cleanup)]; } - bb34: { @@ -546,21 +624,21 @@ - goto -> bb35; + bb34 (cleanup): { + nop; -+ drop((((*_140) as variant#18).2: [AsyncInt; 2])) -> [return: bb35, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#18).3: [AsyncInt; 2])) -> [return: bb35, unwind terminate(cleanup)]; } - bb35: { - coroutine_drop; + bb35 (cleanup): { + nop; -+ drop((((*_140) as variant#20).1: AsyncInt)) -> [return: bb36, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#20).2: AsyncInt)) -> [return: bb36, unwind terminate(cleanup)]; } bb36 (cleanup): { - StorageDead(_26); - goto -> bb37; + nop; -+ drop((((*_140) as variant#20).0: SyncInt)) -> [return: bb37, unwind terminate(cleanup)]; ++ drop((((*_182) as variant#20).1: SyncInt)) -> [return: bb37, unwind terminate(cleanup)]; } bb37 (cleanup): { @@ -573,7 +651,7 @@ bb38 (cleanup): { - StorageDead(_24); - goto -> bb39; -+ goto -> bb136; ++ goto -> bb149; } - bb39 (cleanup): { @@ -595,772 +673,1331 @@ - StorageDead(_19); - goto -> bb44; + bb41: { -+ _58 = move _2; -+ goto -> bb90; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb41, unwind: bb40]; } - bb42 (cleanup): { - goto -> bb43; + bb42: { -+ nop; -+ (((*_140) as variant#4).10: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(copy (_28.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35})) -> [return: bb41, unwind: bb40]; ++ _2 = move _28; ++ StorageDead(_28); ++ goto -> bb41; } - bb43 (cleanup): { - StorageDead(_18); - goto -> bb44; + bb43: { -+ _29 = &mut (((*_140) as variant#4).9: {async closure@$DIR/async_drop.rs:80:27: 80:35}); -+ _28 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _29) -> [return: bb42, unwind: bb23]; ++ unreachable; } - bb44 (cleanup): { - StorageDead(_17); - drop(_15) -> [return: bb45, unwind terminate(cleanup)]; + bb44: { -+ nop; -+ goto -> bb12; ++ _2 = move _35; ++ StorageDead(_35); ++ goto -> bb49; } - bb45 (cleanup): { +- bb45 (cleanup): { - StorageDead(_15); - drop(_11) -> [return: bb46, unwind terminate(cleanup)]; -+ nop; -+ goto -> bb25; ++ bb45: { ++ StorageLive(_35); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_17); ++ StorageDead(_23); ++ StorageDead(_25); ++ StorageDead(_35); ++ discriminant((*_182)) = 4; ++ return; } - bb46 (cleanup): { - StorageDead(_11); - drop(_8) -> [return: bb47, unwind terminate(cleanup)]; + bb46: { -+ _67 = move _2; -+ goto -> bb96; ++ _37 = discriminant(_36); ++ switchInt(move _37) -> [0: bb39, 1: bb45, otherwise: bb43]; } - bb47 (cleanup): { - StorageDead(_8); - drop(_5) -> [return: bb48, unwind terminate(cleanup)]; + bb47: { -+ nop; -+ (((*_140) as variant#6).9: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(copy (_31.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb46, unwind: bb45]; ++ _36 = as Future>::poll(move _38, move _39) -> [return: bb46, unwind: bb40]; } - bb48 (cleanup): { - StorageDead(_5); - drop(_4) -> [return: bb49, unwind terminate(cleanup)]; + bb48: { -+ _32 = &mut (((*_140) as variant#6).8: {closure@$DIR/async_drop.rs:72:25: 72:27}); -+ _31 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb47, unwind: bb25]; ++ _40 = move _2; ++ _39 = move _40; ++ goto -> bb47; } - bb49 (cleanup): { - StorageDead(_4); - drop(_3) -> [return: bb50, unwind terminate(cleanup)]; + bb49: { -+ nop; -+ goto -> bb14; ++ _41 = &mut (((*_182) as variant#4).11: impl std::future::Future); ++ _38 = Pin::<&mut impl Future>::new_unchecked(move _41) -> [return: bb48, unwind: bb40]; } - bb50 (cleanup): { +- bb50 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb51, unwind terminate(cleanup)]; ++ bb50: { + nop; -+ goto -> bb27; ++ (((*_182) as variant#4).11: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:78:27: 78:35}>(copy (_42.0: &mut {async closure@$DIR/async_drop.rs:78:27: 78:35})) -> [return: bb49, unwind: bb40]; } - bb51 (cleanup): { - resume; + bb51: { -+ _76 = move _2; -+ goto -> bb101; ++ _43 = &mut (((*_182) as variant#4).10: {async closure@$DIR/async_drop.rs:78:27: 78:35}); ++ _42 = Pin::<&mut {async closure@$DIR/async_drop.rs:78:27: 78:35}>::new_unchecked(move _43) -> [return: bb50, unwind: bb23]; } bb52: { - StorageDead(_27); - goto -> bb10; + nop; -+ (((*_140) as variant#8).8: impl std::future::Future) = async_drop_in_place::>(copy (_34.0: &mut AsyncReference<'_>)) -> [return: bb51, unwind: bb50]; ++ goto -> bb12; } - bb53: { +- bb53: { - StorageDead(_27); - goto -> bb23; -+ _35 = &mut (((*_140) as variant#8).7: AsyncReference<'_>); -+ _34 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _35) -> [return: bb52, unwind: bb27]; ++ bb53 (cleanup): { ++ nop; ++ goto -> bb25; } - bb54 (cleanup): { - StorageDead(_27); - goto -> bb36; + bb54: { -+ nop; -+ goto -> bb15; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb54, unwind: bb53]; } -- bb55: { -- async drop(_26; poll=_27) -> [return: bb52, unwind: bb54, drop: bb53]; -+ bb55 (cleanup): { -+ nop; -+ goto -> bb28; + bb55: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb55, unwind: bb54]; ++ _2 = move _45; ++ StorageDead(_45); ++ goto -> bb54; } bb56: { -- StorageLive(_27); -- _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:80:27: 80:35}>(copy (_28.0: &mut {async closure@$DIR/async_drop.rs:80:27: 80:35})) -> [return: bb55, unwind: bb54]; -+ _85 = move _2; -+ goto -> bb106; +- _2 = move _28; +- StorageDead(_28); +- goto -> bb55; ++ _2 = move _52; ++ StorageDead(_52); ++ goto -> bb61; } bb57: { -- _29 = &mut _26; -- _28 = Pin::<&mut {async closure@$DIR/async_drop.rs:80:27: 80:35}>::new_unchecked(move _29) -> [return: bb56, unwind: bb36]; -+ nop; -+ (((*_140) as variant#10).7: impl std::future::Future) = async_drop_in_place::(copy (_37.0: &mut AsyncInt)) -> [return: bb56, unwind: bb55]; +- _2 = move _28; +- StorageDead(_28); +- goto -> bb63; ++ StorageLive(_52); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_17); ++ StorageDead(_23); ++ StorageDead(_52); ++ discriminant((*_182)) = 6; ++ return; } bb58: { -- StorageDead(_30); -- goto -> bb12; -+ _38 = &mut (((*_140) as variant#10).6: AsyncInt); -+ _37 = Pin::<&mut AsyncInt>::new_unchecked(move _38) -> [return: bb57, unwind: bb28]; +- StorageLive(_28); +- _28 = yield(const ()) -> [resume: bb56, drop: bb57]; ++ _54 = discriminant(_53); ++ switchInt(move _54) -> [0: bb52, 1: bb57, otherwise: bb43]; } bb59: { -- StorageDead(_30); -- goto -> bb25; -+ nop; -+ goto -> bb16; +- unreachable; ++ _53 = as Future>::poll(move _55, move _56) -> [return: bb58, unwind: bb53]; } - bb60 (cleanup): { -- StorageDead(_30); -- goto -> bb38; -+ nop; -+ goto -> bb32; + bb60: { +- _30 = discriminant(_29); +- switchInt(move _30) -> [0: bb53, 1: bb58, otherwise: bb59]; ++ _57 = move _2; ++ _56 = move _57; ++ goto -> bb59; } bb61: { -- async drop(_24; poll=_30) -> [return: bb58, unwind: bb60, drop: bb59]; -+ _94 = move _2; -+ goto -> bb111; +- _29 = as Future>::poll(move _31, move _32) -> [return: bb60, unwind: bb54]; ++ _58 = &mut (((*_182) as variant#6).10: impl std::future::Future); ++ _55 = Pin::<&mut impl Future>::new_unchecked(move _58) -> [return: bb60, unwind: bb53]; } bb62: { -- StorageLive(_30); -- _30 = async_drop_in_place::<{closure@$DIR/async_drop.rs:72:25: 72:27}>(copy (_31.0: &mut {closure@$DIR/async_drop.rs:72:25: 72:27})) -> [return: bb61, unwind: bb60]; +- _33 = move _2; +- _32 = std::future::get_context::<'_, '_>(move _33) -> [return: bb61, unwind: bb54]; + nop; -+ (((*_140) as variant#12).6: impl std::future::Future) = async_drop_in_place::(copy (_40.0: &mut AsyncEnum)) -> [return: bb61, unwind: bb60]; ++ (((*_182) as variant#6).10: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:70:25: 70:27}>(copy (_59.0: &mut {closure@$DIR/async_drop.rs:70:25: 70:27})) -> [return: bb61, unwind: bb53]; } bb63: { -- _32 = &mut _24; -- _31 = Pin::<&mut {closure@$DIR/async_drop.rs:72:25: 72:27}>::new_unchecked(move _32) -> [return: bb62, unwind: bb38]; -+ _41 = &mut (((*_140) as variant#12).5: AsyncEnum); -+ _40 = Pin::<&mut AsyncEnum>::new_unchecked(move _41) -> [return: bb62, unwind: bb32]; +- _34 = &mut _27; +- _31 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb62, unwind: bb54]; ++ _60 = &mut (((*_182) as variant#6).9: {closure@$DIR/async_drop.rs:70:25: 70:27}); ++ _59 = Pin::<&mut {closure@$DIR/async_drop.rs:70:25: 70:27}>::new_unchecked(move _60) -> [return: bb62, unwind: bb25]; } bb64: { -- StorageDead(_33); -- goto -> bb14; +- _2 = move _35; +- StorageDead(_35); +- goto -> bb70; + nop; -+ goto -> bb17; ++ goto -> bb14; } - bb65: { -- StorageDead(_33); -- goto -> bb27; +- _2 = move _35; +- StorageDead(_35); +- goto -> bb63; + bb65 (cleanup): { + nop; -+ goto -> bb33; ++ goto -> bb27; } -- bb66 (cleanup): { -- StorageDead(_33); -- goto -> bb40; -+ bb66: { -+ _103 = move _2; -+ goto -> bb116; + bb66: { +- StorageLive(_35); +- _35 = yield(const ()) -> [resume: bb64, drop: bb65]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb66, unwind: bb65]; } bb67: { -- async drop(_20; poll=_33) -> [return: bb64, unwind: bb66, drop: bb65]; -+ nop; -+ (((*_140) as variant#14).5: impl std::future::Future) = async_drop_in_place::(copy (_43.0: &mut SyncThenAsync)) -> [return: bb66, unwind: bb65]; +- _37 = discriminant(_36); +- switchInt(move _37) -> [0: bb52, 1: bb66, otherwise: bb59]; ++ _2 = move _62; ++ StorageDead(_62); ++ goto -> bb66; } bb68: { -- StorageLive(_33); -- _33 = async_drop_in_place::>(copy (_34.0: &mut AsyncReference<'_>)) -> [return: bb67, unwind: bb66]; -+ _44 = &mut (((*_140) as variant#14).4: SyncThenAsync); -+ _43 = Pin::<&mut SyncThenAsync>::new_unchecked(move _44) -> [return: bb67, unwind: bb33]; +- _36 = as Future>::poll(move _38, move _39) -> [return: bb67, unwind: bb54]; ++ _2 = move _69; ++ StorageDead(_69); ++ goto -> bb73; } bb69: { -- _35 = &mut _20; -- _34 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _35) -> [return: bb68, unwind: bb40]; -+ nop; -+ goto -> bb18; +- _40 = move _2; +- _39 = std::future::get_context::<'_, '_>(move _40) -> [return: bb68, unwind: bb54]; ++ StorageLive(_69); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_17); ++ StorageDead(_69); ++ discriminant((*_182)) = 8; ++ return; } -- bb70: { -- StorageDead(_36); -- goto -> bb15; -+ bb70 (cleanup): { -+ nop; -+ goto -> bb34; + bb70: { +- _41 = &mut _27; +- _38 = Pin::<&mut impl Future>::new_unchecked(move _41) -> [return: bb69, unwind: bb54]; ++ _71 = discriminant(_70); ++ switchInt(move _71) -> [0: bb64, 1: bb69, otherwise: bb43]; } bb71: { -- StorageDead(_36); -- goto -> bb28; -+ _112 = move _2; -+ goto -> bb121; +- StorageLive(_27); +- _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:78:27: 78:35}>(copy (_42.0: &mut {async closure@$DIR/async_drop.rs:78:27: 78:35})) -> [return: bb70, unwind: bb54]; ++ _70 = as Future>::poll(move _72, move _73) -> [return: bb70, unwind: bb65]; } -- bb72 (cleanup): { -- StorageDead(_36); -- goto -> bb41; -+ bb72: { -+ nop; -+ (((*_140) as variant#16).4: impl std::future::Future) = async_drop_in_place::(copy (_46.0: &mut AsyncStruct)) -> [return: bb71, unwind: bb70]; + bb72: { +- _43 = &mut _26; +- _42 = Pin::<&mut {async closure@$DIR/async_drop.rs:78:27: 78:35}>::new_unchecked(move _43) -> [return: bb71, unwind: bb36]; ++ _74 = move _2; ++ _73 = move _74; ++ goto -> bb71; } bb73: { -- async drop(_19; poll=_36) -> [return: bb70, unwind: bb72, drop: bb71]; -+ _47 = &mut (((*_140) as variant#16).3: AsyncStruct); -+ _46 = Pin::<&mut AsyncStruct>::new_unchecked(move _47) -> [return: bb72, unwind: bb34]; +- StorageDead(_44); +- goto -> bb12; ++ _75 = &mut (((*_182) as variant#8).9: impl std::future::Future); ++ _72 = Pin::<&mut impl Future>::new_unchecked(move _75) -> [return: bb72, unwind: bb65]; } bb74: { -- StorageLive(_36); -- _36 = async_drop_in_place::(copy (_37.0: &mut AsyncInt)) -> [return: bb73, unwind: bb72]; +- StorageDead(_44); +- goto -> bb25; + nop; -+ goto -> bb19; ++ (((*_182) as variant#8).9: impl std::future::Future) = async_drop_in_place::>(copy (_76.0: &mut AsyncReference<'_>)) -> [return: bb73, unwind: bb65]; } -- bb75: { -- _38 = &mut _19; -- _37 = Pin::<&mut AsyncInt>::new_unchecked(move _38) -> [return: bb74, unwind: bb41]; -+ bb75 (cleanup): { -+ nop; -+ goto -> bb35; +- bb75 (cleanup): { +- StorageDead(_44); +- goto -> bb38; ++ bb75: { ++ _77 = &mut (((*_182) as variant#8).8: AsyncReference<'_>); ++ _76 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _77) -> [return: bb74, unwind: bb27]; } bb76: { -- StorageDead(_39); -- goto -> bb16; -+ _121 = move _2; -+ goto -> bb126; +- assert(const false, "`async fn` resumed after async drop") -> [success: bb76, unwind: bb75]; ++ nop; ++ goto -> bb15; } - bb77: { -- StorageDead(_39); -- goto -> bb29; +- bb77: { +- _2 = move _45; +- StorageDead(_45); +- goto -> bb76; ++ bb77 (cleanup): { + nop; -+ (((*_140) as variant#18).3: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(copy (_49.0: &mut [AsyncInt; 2])) -> [return: bb76, unwind: bb75]; ++ goto -> bb28; } -- bb78 (cleanup): { -- StorageDead(_39); -- goto -> bb45; -+ bb78: { -+ _50 = &mut (((*_140) as variant#18).2: [AsyncInt; 2]); -+ _49 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _50) -> [return: bb77, unwind: bb35]; + bb78: { +- _2 = move _45; +- StorageDead(_45); +- goto -> bb83; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb78, unwind: bb77]; } bb79: { -- async drop(_15; poll=_39) -> [return: bb76, unwind: bb78, drop: bb77]; -+ nop; -+ goto -> bb20; +- StorageLive(_45); +- _45 = yield(const ()) -> [resume: bb77, drop: bb78]; ++ _2 = move _79; ++ StorageDead(_79); ++ goto -> bb78; } -- bb80: { -- StorageLive(_39); -- _39 = async_drop_in_place::(copy (_40.0: &mut AsyncEnum)) -> [return: bb79, unwind: bb78]; -+ bb80 (cleanup): { -+ nop; -+ goto -> bb36; + bb80: { +- _47 = discriminant(_46); +- switchInt(move _47) -> [0: bb74, 1: bb79, otherwise: bb59]; ++ _2 = move _86; ++ StorageDead(_86); ++ goto -> bb85; } bb81: { -- _41 = &mut _15; -- _40 = Pin::<&mut AsyncEnum>::new_unchecked(move _41) -> [return: bb80, unwind: bb45]; -+ _130 = move _2; -+ goto -> bb131; +- _46 = as Future>::poll(move _48, move _49) -> [return: bb80, unwind: bb75]; ++ StorageLive(_86); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_17); ++ StorageDead(_86); ++ discriminant((*_182)) = 10; ++ return; } bb82: { -- StorageDead(_42); -- goto -> bb17; -+ nop; -+ (((*_140) as variant#20).2: impl std::future::Future) = async_drop_in_place::(copy (_52.0: &mut AsyncInt)) -> [return: bb81, unwind: bb80]; +- _50 = move _2; +- _49 = std::future::get_context::<'_, '_>(move _50) -> [return: bb81, unwind: bb75]; ++ _88 = discriminant(_87); ++ switchInt(move _88) -> [0: bb76, 1: bb81, otherwise: bb43]; } bb83: { -- StorageDead(_42); -- goto -> bb30; -+ _53 = &mut (((*_140) as variant#20).1: AsyncInt); -+ _52 = Pin::<&mut AsyncInt>::new_unchecked(move _53) -> [return: bb82, unwind: bb36]; +- _51 = &mut _44; +- _48 = Pin::<&mut impl Future>::new_unchecked(move _51) -> [return: bb82, unwind: bb75]; ++ _87 = as Future>::poll(move _89, move _90) -> [return: bb82, unwind: bb77]; } -- bb84 (cleanup): { -- StorageDead(_42); -- goto -> bb46; -+ bb84: { -+ StorageDead(_54); -+ goto -> bb22; + bb84: { +- _2 = move _52; +- StorageDead(_52); +- goto -> bb90; ++ _91 = move _2; ++ _90 = move _91; ++ goto -> bb83; } -- bb85: { -- async drop(_11; poll=_42) -> [return: bb82, unwind: bb84, drop: bb83]; -+ bb85 (cleanup): { -+ StorageDead(_54); -+ goto -> bb38; + bb85: { +- _2 = move _52; +- StorageDead(_52); +- goto -> bb83; ++ _92 = &mut (((*_182) as variant#10).8: impl std::future::Future); ++ _89 = Pin::<&mut impl Future>::new_unchecked(move _92) -> [return: bb84, unwind: bb77]; } bb86: { -- StorageLive(_42); -- _42 = async_drop_in_place::(copy (_43.0: &mut SyncThenAsync)) -> [return: bb85, unwind: bb84]; -+ goto -> bb135; +- StorageLive(_52); +- _52 = yield(const ()) -> [resume: bb84, drop: bb85]; ++ nop; ++ (((*_182) as variant#10).8: impl std::future::Future) = async_drop_in_place::(copy (_93.0: &mut AsyncInt)) -> [return: bb85, unwind: bb77]; } bb87: { -- _44 = &mut _11; -- _43 = Pin::<&mut SyncThenAsync>::new_unchecked(move _44) -> [return: bb86, unwind: bb46]; -+ StorageLive(_54); -+ _54 = async_drop_in_place::<{async fn body of elaborate_drops()}>(copy (_55.0: &mut {async fn body of elaborate_drops()})) -> [return: bb86, unwind: bb85]; +- _54 = discriminant(_53); +- switchInt(move _54) -> [0: bb73, 1: bb86, otherwise: bb59]; ++ _94 = &mut (((*_182) as variant#10).7: AsyncInt); ++ _93 = Pin::<&mut AsyncInt>::new_unchecked(move _94) -> [return: bb86, unwind: bb28]; } bb88: { -- StorageDead(_45); -- goto -> bb18; -+ _56 = &mut (*_140); -+ _55 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _56) -> [return: bb87, unwind: bb38]; +- _53 = as Future>::poll(move _55, move _56) -> [return: bb87, unwind: bb75]; ++ nop; ++ goto -> bb16; } - bb89: { -- StorageDead(_45); -- goto -> bb31; -+ _0 = Poll::<()>::Pending; -+ StorageDead(_17); -+ StorageDead(_23); -+ StorageDead(_25); -+ discriminant((*_140)) = 3; -+ return; +- bb89: { +- _57 = move _2; +- _56 = std::future::get_context::<'_, '_>(move _57) -> [return: bb88, unwind: bb75]; ++ bb89 (cleanup): { ++ nop; ++ goto -> bb32; } -- bb90 (cleanup): { -- StorageDead(_45); -- goto -> bb47; -+ bb90: { -+ StorageLive(_60); -+ _59 = &mut (((*_140) as variant#4).10: impl std::future::Future); -+ _60 = Pin::<&mut impl Future>::new_unchecked(move _59) -> [return: bb93, unwind: bb136]; + bb90: { +- _58 = &mut _44; +- _55 = Pin::<&mut impl Future>::new_unchecked(move _58) -> [return: bb89, unwind: bb75]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb90, unwind: bb89]; } bb91: { -- async drop(_8; poll=_45) -> [return: bb88, unwind: bb90, drop: bb89]; -+ unreachable; +- StorageLive(_44); +- _44 = async_drop_in_place::<{closure@$DIR/async_drop.rs:70:25: 70:27}>(copy (_59.0: &mut {closure@$DIR/async_drop.rs:70:25: 70:27})) -> [return: bb90, unwind: bb75]; ++ _2 = move _96; ++ StorageDead(_96); ++ goto -> bb90; } bb92: { -- StorageLive(_45); -- _45 = async_drop_in_place::(copy (_46.0: &mut AsyncStruct)) -> [return: bb91, unwind: bb90]; -+ StorageDead(_60); -+ _61 = discriminant(_57); -+ switchInt(move _61) -> [0: bb39, 1: bb89, otherwise: bb91]; +- _60 = &mut _24; +- _59 = Pin::<&mut {closure@$DIR/async_drop.rs:70:25: 70:27}>::new_unchecked(move _60) -> [return: bb91, unwind: bb38]; ++ _2 = move _103; ++ StorageDead(_103); ++ goto -> bb97; } bb93: { -- _47 = &mut _8; -- _46 = Pin::<&mut AsyncStruct>::new_unchecked(move _47) -> [return: bb92, unwind: bb47]; -+ _57 = as Future>::poll(move _60, move _58) -> [return: bb92, unwind: bb40]; +- StorageDead(_61); +- goto -> bb14; ++ StorageLive(_103); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_103); ++ discriminant((*_182)) = 12; ++ return; } bb94: { -- StorageDead(_48); -- goto -> bb19; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb94, unwind: bb136]; +- StorageDead(_61); +- goto -> bb27; ++ _105 = discriminant(_104); ++ switchInt(move _105) -> [0: bb88, 1: bb93, otherwise: bb43]; } - bb95: { -- StorageDead(_48); -- goto -> bb32; -+ _0 = Poll::<()>::Pending; -+ StorageDead(_17); -+ StorageDead(_23); -+ discriminant((*_140)) = 5; -+ return; +- bb95 (cleanup): { +- StorageDead(_61); +- goto -> bb40; ++ bb95: { ++ _104 = as Future>::poll(move _106, move _107) -> [return: bb94, unwind: bb89]; } -- bb96 (cleanup): { -- StorageDead(_48); -- goto -> bb48; -+ bb96: { -+ StorageLive(_69); -+ _68 = &mut (((*_140) as variant#6).9: impl std::future::Future); -+ _69 = Pin::<&mut impl Future>::new_unchecked(move _68) -> [return: bb98, unwind: bb136]; + bb96: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb96, unwind: bb95]; ++ _108 = move _2; ++ _107 = move _108; ++ goto -> bb95; } bb97: { -- async drop(_5; poll=_48) -> [return: bb94, unwind: bb96, drop: bb95]; -+ StorageDead(_69); -+ _70 = discriminant(_66); -+ switchInt(move _70) -> [0: bb44, 1: bb95, otherwise: bb91]; +- _2 = move _62; +- StorageDead(_62); +- goto -> bb96; ++ _109 = &mut (((*_182) as variant#12).7: impl std::future::Future); ++ _106 = Pin::<&mut impl Future>::new_unchecked(move _109) -> [return: bb96, unwind: bb89]; } bb98: { -- StorageLive(_48); -- _48 = async_drop_in_place::<[AsyncInt; 2]>(copy (_49.0: &mut [AsyncInt; 2])) -> [return: bb97, unwind: bb96]; -+ _66 = as Future>::poll(move _69, move _67) -> [return: bb97, unwind: bb45]; +- _2 = move _62; +- StorageDead(_62); +- goto -> bb103; ++ nop; ++ (((*_182) as variant#12).7: impl std::future::Future) = async_drop_in_place::(copy (_110.0: &mut AsyncEnum)) -> [return: bb97, unwind: bb89]; } bb99: { -- _50 = &mut _5; -- _49 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _50) -> [return: bb98, unwind: bb48]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb99, unwind: bb136]; +- StorageLive(_62); +- _62 = yield(const ()) -> [resume: bb97, drop: bb98]; ++ _111 = &mut (((*_182) as variant#12).6: AsyncEnum); ++ _110 = Pin::<&mut AsyncEnum>::new_unchecked(move _111) -> [return: bb98, unwind: bb32]; } bb100: { -- StorageDead(_51); -- goto -> bb20; -+ _0 = Poll::<()>::Pending; -+ StorageDead(_17); -+ discriminant((*_140)) = 7; -+ return; +- _64 = discriminant(_63); +- switchInt(move _64) -> [0: bb94, 1: bb99, otherwise: bb59]; ++ nop; ++ goto -> bb17; } - bb101: { -- StorageDead(_51); -- goto -> bb33; -+ StorageLive(_78); -+ _77 = &mut (((*_140) as variant#8).8: impl std::future::Future); -+ _78 = Pin::<&mut impl Future>::new_unchecked(move _77) -> [return: bb103, unwind: bb136]; +- bb101: { +- _63 = as Future>::poll(move _65, move _66) -> [return: bb100, unwind: bb95]; ++ bb101 (cleanup): { ++ nop; ++ goto -> bb33; } -- bb102 (cleanup): { -- StorageDead(_51); -- goto -> bb49; -+ bb102: { -+ StorageDead(_78); -+ _79 = discriminant(_75); -+ switchInt(move _79) -> [0: bb49, 1: bb100, otherwise: bb91]; + bb102: { +- _67 = move _2; +- _66 = std::future::get_context::<'_, '_>(move _67) -> [return: bb101, unwind: bb95]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb102, unwind: bb101]; } bb103: { -- async drop(_4; poll=_51) -> [return: bb100, unwind: bb102, drop: bb101]; -+ _75 = as Future>::poll(move _78, move _76) -> [return: bb102, unwind: bb50]; +- _68 = &mut _61; +- _65 = Pin::<&mut impl Future>::new_unchecked(move _68) -> [return: bb102, unwind: bb95]; ++ _2 = move _113; ++ StorageDead(_113); ++ goto -> bb102; } bb104: { -- StorageLive(_51); -- _51 = async_drop_in_place::(copy (_52.0: &mut AsyncInt)) -> [return: bb103, unwind: bb102]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb104, unwind: bb136]; +- _2 = move _69; +- StorageDead(_69); +- goto -> bb110; ++ _2 = move _120; ++ StorageDead(_120); ++ goto -> bb109; } bb105: { -- _53 = &mut _4; -- _52 = Pin::<&mut AsyncInt>::new_unchecked(move _53) -> [return: bb104, unwind: bb49]; +- _2 = move _69; +- StorageDead(_69); +- goto -> bb103; ++ StorageLive(_120); + _0 = Poll::<()>::Pending; -+ StorageDead(_17); -+ discriminant((*_140)) = 9; ++ StorageDead(_120); ++ discriminant((*_182)) = 14; + return; } bb106: { -- StorageDead(_54); -- goto -> bb22; -+ StorageLive(_87); -+ _86 = &mut (((*_140) as variant#10).7: impl std::future::Future); -+ _87 = Pin::<&mut impl Future>::new_unchecked(move _86) -> [return: bb108, unwind: bb136]; +- StorageLive(_69); +- _69 = yield(const ()) -> [resume: bb104, drop: bb105]; ++ _122 = discriminant(_121); ++ switchInt(move _122) -> [0: bb100, 1: bb105, otherwise: bb43]; } bb107: { -- StorageDead(_54); -- goto -> bb35; -+ StorageDead(_87); -+ _88 = discriminant(_84); -+ switchInt(move _88) -> [0: bb54, 1: bb105, otherwise: bb91]; +- _71 = discriminant(_70); +- switchInt(move _71) -> [0: bb93, 1: bb106, otherwise: bb59]; ++ _121 = as Future>::poll(move _123, move _124) -> [return: bb106, unwind: bb101]; } -- bb108 (cleanup): { -- StorageDead(_54); -- goto -> bb51; -+ bb108: { -+ _84 = as Future>::poll(move _87, move _85) -> [return: bb107, unwind: bb55]; + bb108: { +- _70 = as Future>::poll(move _72, move _73) -> [return: bb107, unwind: bb95]; ++ _125 = move _2; ++ _124 = move _125; ++ goto -> bb107; } bb109: { -- async drop(_1; poll=_54) -> [return: bb106, unwind: bb108, drop: bb107]; -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb109, unwind: bb136]; +- _74 = move _2; +- _73 = std::future::get_context::<'_, '_>(move _74) -> [return: bb108, unwind: bb95]; ++ _126 = &mut (((*_182) as variant#14).6: impl std::future::Future); ++ _123 = Pin::<&mut impl Future>::new_unchecked(move _126) -> [return: bb108, unwind: bb101]; } bb110: { -- StorageLive(_54); -- _54 = async_drop_in_place::<{async fn body of elaborate_drops()}>(copy (_55.0: &mut {async fn body of elaborate_drops()})) -> [return: bb109, unwind: bb108]; -+ _0 = Poll::<()>::Pending; -+ discriminant((*_140)) = 11; -+ return; +- _75 = &mut _61; +- _72 = Pin::<&mut impl Future>::new_unchecked(move _75) -> [return: bb109, unwind: bb95]; ++ nop; ++ (((*_182) as variant#14).6: impl std::future::Future) = async_drop_in_place::(copy (_127.0: &mut SyncThenAsync)) -> [return: bb109, unwind: bb101]; } bb111: { -- _56 = &mut _1; -- _55 = Pin::<&mut {async fn body of elaborate_drops()}>::new_unchecked(move _56) -> [return: bb110, unwind: bb51]; -+ StorageLive(_96); -+ _95 = &mut (((*_140) as variant#12).6: impl std::future::Future); -+ _96 = Pin::<&mut impl Future>::new_unchecked(move _95) -> [return: bb113, unwind: bb136]; -+ } -+ -+ bb112: { -+ StorageDead(_96); -+ _97 = discriminant(_93); -+ switchInt(move _97) -> [0: bb59, 1: bb110, otherwise: bb91]; -+ } -+ -+ bb113: { -+ _93 = as Future>::poll(move _96, move _94) -> [return: bb112, unwind: bb60]; -+ } -+ -+ bb114: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb114, unwind: bb136]; -+ } -+ +- StorageLive(_61); +- _61 = async_drop_in_place::>(copy (_76.0: &mut AsyncReference<'_>)) -> [return: bb110, unwind: bb95]; ++ _128 = &mut (((*_182) as variant#14).5: SyncThenAsync); ++ _127 = Pin::<&mut SyncThenAsync>::new_unchecked(move _128) -> [return: bb110, unwind: bb33]; + } + + bb112: { +- _77 = &mut _20; +- _76 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _77) -> [return: bb111, unwind: bb40]; ++ nop; ++ goto -> bb18; + } + +- bb113: { +- StorageDead(_78); +- goto -> bb15; ++ bb113 (cleanup): { ++ nop; ++ goto -> bb34; + } + + bb114: { +- StorageDead(_78); +- goto -> bb28; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb114, unwind: bb113]; + } + +- bb115 (cleanup): { +- StorageDead(_78); +- goto -> bb41; + bb115: { ++ _2 = move _130; ++ StorageDead(_130); ++ goto -> bb114; + } + + bb116: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb116, unwind: bb115]; ++ _2 = move _137; ++ StorageDead(_137); ++ goto -> bb121; + } + + bb117: { +- _2 = move _79; +- StorageDead(_79); +- goto -> bb116; ++ StorageLive(_137); + _0 = Poll::<()>::Pending; -+ discriminant((*_140)) = 13; -+ return; -+ } -+ -+ bb116: { -+ StorageLive(_105); -+ _104 = &mut (((*_140) as variant#14).5: impl std::future::Future); -+ _105 = Pin::<&mut impl Future>::new_unchecked(move _104) -> [return: bb118, unwind: bb136]; -+ } -+ -+ bb117: { -+ StorageDead(_105); -+ _106 = discriminant(_102); -+ switchInt(move _106) -> [0: bb64, 1: bb115, otherwise: bb91]; -+ } -+ -+ bb118: { -+ _102 = as Future>::poll(move _105, move _103) -> [return: bb117, unwind: bb65]; -+ } -+ -+ bb119: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb119, unwind: bb136]; -+ } -+ -+ bb120: { -+ _0 = Poll::<()>::Pending; -+ discriminant((*_140)) = 15; ++ StorageDead(_137); ++ discriminant((*_182)) = 16; + return; -+ } -+ -+ bb121: { -+ StorageLive(_114); -+ _113 = &mut (((*_140) as variant#16).4: impl std::future::Future); -+ _114 = Pin::<&mut impl Future>::new_unchecked(move _113) -> [return: bb123, unwind: bb136]; -+ } -+ -+ bb122: { -+ StorageDead(_114); -+ _115 = discriminant(_111); -+ switchInt(move _115) -> [0: bb69, 1: bb120, otherwise: bb91]; -+ } -+ -+ bb123: { -+ _111 = as Future>::poll(move _114, move _112) -> [return: bb122, unwind: bb70]; -+ } -+ -+ bb124: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb124, unwind: bb136]; -+ } -+ -+ bb125: { + } + + bb118: { +- _2 = move _79; +- StorageDead(_79); +- goto -> bb123; ++ _139 = discriminant(_138); ++ switchInt(move _139) -> [0: bb112, 1: bb117, otherwise: bb43]; + } + + bb119: { +- StorageLive(_79); +- _79 = yield(const ()) -> [resume: bb117, drop: bb118]; ++ _138 = as Future>::poll(move _140, move _141) -> [return: bb118, unwind: bb113]; + } + + bb120: { +- _81 = discriminant(_80); +- switchInt(move _81) -> [0: bb114, 1: bb119, otherwise: bb59]; ++ _142 = move _2; ++ _141 = move _142; ++ goto -> bb119; + } + + bb121: { +- _80 = as Future>::poll(move _82, move _83) -> [return: bb120, unwind: bb115]; ++ _143 = &mut (((*_182) as variant#16).5: impl std::future::Future); ++ _140 = Pin::<&mut impl Future>::new_unchecked(move _143) -> [return: bb120, unwind: bb113]; + } + + bb122: { +- _84 = move _2; +- _83 = std::future::get_context::<'_, '_>(move _84) -> [return: bb121, unwind: bb115]; ++ nop; ++ (((*_182) as variant#16).5: impl std::future::Future) = async_drop_in_place::(copy (_144.0: &mut AsyncStruct)) -> [return: bb121, unwind: bb113]; + } + + bb123: { +- _85 = &mut _78; +- _82 = Pin::<&mut impl Future>::new_unchecked(move _85) -> [return: bb122, unwind: bb115]; ++ _145 = &mut (((*_182) as variant#16).4: AsyncStruct); ++ _144 = Pin::<&mut AsyncStruct>::new_unchecked(move _145) -> [return: bb122, unwind: bb34]; + } + + bb124: { +- _2 = move _86; +- StorageDead(_86); +- goto -> bb130; ++ nop; ++ goto -> bb19; + } + +- bb125: { +- _2 = move _86; +- StorageDead(_86); +- goto -> bb123; ++ bb125 (cleanup): { ++ nop; ++ goto -> bb35; + } + + bb126: { +- StorageLive(_86); +- _86 = yield(const ()) -> [resume: bb124, drop: bb125]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb126, unwind: bb125]; + } + + bb127: { +- _88 = discriminant(_87); +- switchInt(move _88) -> [0: bb113, 1: bb126, otherwise: bb59]; ++ _2 = move _147; ++ StorageDead(_147); ++ goto -> bb126; + } + + bb128: { +- _87 = as Future>::poll(move _89, move _90) -> [return: bb127, unwind: bb115]; ++ _2 = move _154; ++ StorageDead(_154); ++ goto -> bb133; + } + + bb129: { +- _91 = move _2; +- _90 = std::future::get_context::<'_, '_>(move _91) -> [return: bb128, unwind: bb115]; ++ StorageLive(_154); + _0 = Poll::<()>::Pending; -+ discriminant((*_140)) = 17; ++ StorageDead(_154); ++ discriminant((*_182)) = 18; + return; -+ } -+ -+ bb126: { -+ StorageLive(_123); -+ _122 = &mut (((*_140) as variant#18).3: impl std::future::Future); -+ _123 = Pin::<&mut impl Future>::new_unchecked(move _122) -> [return: bb128, unwind: bb136]; -+ } -+ -+ bb127: { -+ StorageDead(_123); -+ _124 = discriminant(_120); -+ switchInt(move _124) -> [0: bb74, 1: bb125, otherwise: bb91]; -+ } -+ -+ bb128: { -+ _120 = as Future>::poll(move _123, move _121) -> [return: bb127, unwind: bb75]; -+ } -+ -+ bb129: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb129, unwind: bb136]; -+ } -+ -+ bb130: { + } + + bb130: { +- _92 = &mut _78; +- _89 = Pin::<&mut impl Future>::new_unchecked(move _92) -> [return: bb129, unwind: bb115]; ++ _156 = discriminant(_155); ++ switchInt(move _156) -> [0: bb124, 1: bb129, otherwise: bb43]; + } + + bb131: { +- StorageLive(_78); +- _78 = async_drop_in_place::(copy (_93.0: &mut AsyncInt)) -> [return: bb130, unwind: bb115]; ++ _155 = as Future>::poll(move _157, move _158) -> [return: bb130, unwind: bb125]; + } + + bb132: { +- _94 = &mut _19; +- _93 = Pin::<&mut AsyncInt>::new_unchecked(move _94) -> [return: bb131, unwind: bb41]; ++ _159 = move _2; ++ _158 = move _159; ++ goto -> bb131; + } + + bb133: { +- StorageDead(_95); +- goto -> bb16; ++ _160 = &mut (((*_182) as variant#18).4: impl std::future::Future); ++ _157 = Pin::<&mut impl Future>::new_unchecked(move _160) -> [return: bb132, unwind: bb125]; + } + + bb134: { +- StorageDead(_95); +- goto -> bb29; ++ nop; ++ (((*_182) as variant#18).4: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(copy (_161.0: &mut [AsyncInt; 2])) -> [return: bb133, unwind: bb125]; + } + +- bb135 (cleanup): { +- StorageDead(_95); +- goto -> bb45; ++ bb135: { ++ _162 = &mut (((*_182) as variant#18).3: [AsyncInt; 2]); ++ _161 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _162) -> [return: bb134, unwind: bb35]; + } + + bb136: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb136, unwind: bb135]; ++ nop; ++ goto -> bb20; + } + +- bb137: { +- _2 = move _96; +- StorageDead(_96); +- goto -> bb136; ++ bb137 (cleanup): { ++ nop; ++ goto -> bb36; + } + + bb138: { +- _2 = move _96; +- StorageDead(_96); +- goto -> bb143; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb138, unwind: bb137]; + } + + bb139: { +- StorageLive(_96); +- _96 = yield(const ()) -> [resume: bb137, drop: bb138]; ++ _2 = move _164; ++ StorageDead(_164); ++ goto -> bb138; + } + + bb140: { +- _98 = discriminant(_97); +- switchInt(move _98) -> [0: bb134, 1: bb139, otherwise: bb59]; ++ _2 = move _171; ++ StorageDead(_171); ++ goto -> bb145; + } + + bb141: { +- _97 = as Future>::poll(move _99, move _100) -> [return: bb140, unwind: bb135]; ++ StorageLive(_171); + _0 = Poll::<()>::Pending; -+ discriminant((*_140)) = 19; ++ StorageDead(_171); ++ discriminant((*_182)) = 20; + return; -+ } -+ -+ bb131: { -+ StorageLive(_132); -+ _131 = &mut (((*_140) as variant#20).2: impl std::future::Future); -+ _132 = Pin::<&mut impl Future>::new_unchecked(move _131) -> [return: bb133, unwind: bb136]; -+ } -+ -+ bb132: { -+ StorageDead(_132); -+ _133 = discriminant(_129); -+ switchInt(move _133) -> [0: bb79, 1: bb130, otherwise: bb91]; -+ } -+ -+ bb133: { -+ _129 = as Future>::poll(move _132, move _130) -> [return: bb132, unwind: bb80]; -+ } -+ -+ bb134: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb134, unwind: bb136]; -+ } -+ -+ bb135: { -+ goto -> bb84; -+ } -+ -+ bb136 (cleanup): { -+ discriminant((*_140)) = 2; + } + + bb142: { +- _101 = move _2; +- _100 = std::future::get_context::<'_, '_>(move _101) -> [return: bb141, unwind: bb135]; ++ _173 = discriminant(_172); ++ switchInt(move _173) -> [0: bb136, 1: bb141, otherwise: bb43]; + } + + bb143: { +- _102 = &mut _95; +- _99 = Pin::<&mut impl Future>::new_unchecked(move _102) -> [return: bb142, unwind: bb135]; ++ _172 = as Future>::poll(move _174, move _175) -> [return: bb142, unwind: bb137]; + } + + bb144: { +- _2 = move _103; +- StorageDead(_103); +- goto -> bb150; ++ _176 = move _2; ++ _175 = move _176; ++ goto -> bb143; + } + + bb145: { +- _2 = move _103; +- StorageDead(_103); +- goto -> bb143; ++ _177 = &mut (((*_182) as variant#20).3: impl std::future::Future); ++ _174 = Pin::<&mut impl Future>::new_unchecked(move _177) -> [return: bb144, unwind: bb137]; + } + + bb146: { +- StorageLive(_103); +- _103 = yield(const ()) -> [resume: bb144, drop: bb145]; ++ nop; ++ (((*_182) as variant#20).3: impl std::future::Future) = async_drop_in_place::(copy (_178.0: &mut AsyncInt)) -> [return: bb145, unwind: bb137]; + } + + bb147: { +- _105 = discriminant(_104); +- switchInt(move _105) -> [0: bb133, 1: bb146, otherwise: bb59]; ++ _179 = &mut (((*_182) as variant#20).2: AsyncInt); ++ _178 = Pin::<&mut AsyncInt>::new_unchecked(move _179) -> [return: bb146, unwind: bb36]; + } + + bb148: { +- _104 = as Future>::poll(move _106, move _107) -> [return: bb147, unwind: bb135]; ++ goto -> bb22; + } + +- bb149: { +- _108 = move _2; +- _107 = std::future::get_context::<'_, '_>(move _108) -> [return: bb148, unwind: bb135]; ++ bb149 (cleanup): { ++ discriminant((*_182)) = 2; + resume; -+ } -+ -+ bb137: { + } + + bb150: { +- _109 = &mut _95; +- _106 = Pin::<&mut impl Future>::new_unchecked(move _109) -> [return: bb149, unwind: bb135]; + StorageLive(_17); + StorageLive(_23); + StorageLive(_25); -+ _58 = move _2; -+ goto -> bb90; -+ } -+ -+ bb138: { ++ StorageLive(_28); ++ _28 = move _2; ++ goto -> bb42; + } + + bb151: { +- StorageLive(_95); +- _95 = async_drop_in_place::(copy (_110.0: &mut AsyncEnum)) -> [return: bb150, unwind: bb135]; + StorageLive(_17); + StorageLive(_23); + StorageLive(_25); -+ _62 = move _2; -+ goto -> bb94; -+ } -+ -+ bb139: { ++ StorageLive(_35); ++ _35 = move _2; ++ goto -> bb44; + } + + bb152: { +- _111 = &mut _15; +- _110 = Pin::<&mut AsyncEnum>::new_unchecked(move _111) -> [return: bb151, unwind: bb45]; + StorageLive(_17); + StorageLive(_23); -+ _67 = move _2; -+ goto -> bb96; -+ } -+ -+ bb140: { ++ StorageLive(_45); ++ _45 = move _2; ++ goto -> bb55; + } + + bb153: { +- StorageDead(_112); +- goto -> bb17; + StorageLive(_17); + StorageLive(_23); -+ _71 = move _2; -+ goto -> bb99; -+ } -+ -+ bb141: { ++ StorageLive(_52); ++ _52 = move _2; ++ goto -> bb56; + } + + bb154: { +- StorageDead(_112); +- goto -> bb30; + StorageLive(_17); -+ _76 = move _2; -+ goto -> bb101; -+ } -+ -+ bb142: { ++ StorageLive(_62); ++ _62 = move _2; ++ goto -> bb67; + } + +- bb155 (cleanup): { +- StorageDead(_112); +- goto -> bb46; ++ bb155: { + StorageLive(_17); -+ _80 = move _2; -+ goto -> bb104; -+ } -+ -+ bb143: { ++ StorageLive(_69); ++ _69 = move _2; ++ goto -> bb68; + } + + bb156: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb156, unwind: bb155]; + StorageLive(_17); -+ _85 = move _2; -+ goto -> bb106; -+ } -+ -+ bb144: { ++ StorageLive(_79); ++ _79 = move _2; ++ goto -> bb79; + } + + bb157: { +- _2 = move _113; +- StorageDead(_113); +- goto -> bb156; + StorageLive(_17); -+ _89 = move _2; -+ goto -> bb109; -+ } -+ -+ bb145: { -+ _94 = move _2; -+ goto -> bb111; -+ } -+ -+ bb146: { -+ _98 = move _2; -+ goto -> bb114; -+ } -+ -+ bb147: { ++ StorageLive(_86); ++ _86 = move _2; ++ goto -> bb80; + } + + bb158: { +- _2 = move _113; +- StorageDead(_113); +- goto -> bb163; ++ StorageLive(_96); ++ _96 = move _2; ++ goto -> bb91; + } + + bb159: { +- StorageLive(_113); +- _113 = yield(const ()) -> [resume: bb157, drop: bb158]; ++ StorageLive(_103); + _103 = move _2; -+ goto -> bb116; -+ } -+ -+ bb148: { -+ _107 = move _2; -+ goto -> bb119; -+ } -+ -+ bb149: { -+ _112 = move _2; -+ goto -> bb121; -+ } -+ -+ bb150: { -+ _116 = move _2; -+ goto -> bb124; -+ } -+ -+ bb151: { -+ _121 = move _2; -+ goto -> bb126; -+ } -+ -+ bb152: { -+ _125 = move _2; -+ goto -> bb129; -+ } -+ -+ bb153: { ++ goto -> bb92; + } + + bb160: { +- _115 = discriminant(_114); +- switchInt(move _115) -> [0: bb154, 1: bb159, otherwise: bb59]; ++ StorageLive(_113); ++ _113 = move _2; ++ goto -> bb103; + } + + bb161: { +- _114 = as Future>::poll(move _116, move _117) -> [return: bb160, unwind: bb155]; ++ StorageLive(_120); ++ _120 = move _2; ++ goto -> bb104; + } + + bb162: { +- _118 = move _2; +- _117 = std::future::get_context::<'_, '_>(move _118) -> [return: bb161, unwind: bb155]; ++ StorageLive(_130); + _130 = move _2; -+ goto -> bb131; -+ } -+ -+ bb154: { -+ _134 = move _2; -+ goto -> bb134; -+ } -+ -+ bb155: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb155, unwind continue]; -+ } -+ -+ bb156: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb156, unwind continue]; -+ } -+ -+ bb157: { ++ goto -> bb115; + } + + bb163: { +- _119 = &mut _112; +- _116 = Pin::<&mut impl Future>::new_unchecked(move _119) -> [return: bb162, unwind: bb155]; ++ StorageLive(_137); ++ _137 = move _2; ++ goto -> bb116; + } + + bb164: { +- _2 = move _120; +- StorageDead(_120); +- goto -> bb170; ++ StorageLive(_147); ++ _147 = move _2; ++ goto -> bb127; + } + + bb165: { +- _2 = move _120; +- StorageDead(_120); +- goto -> bb163; ++ StorageLive(_154); ++ _154 = move _2; ++ goto -> bb128; + } + + bb166: { +- StorageLive(_120); +- _120 = yield(const ()) -> [resume: bb164, drop: bb165]; ++ StorageLive(_164); ++ _164 = move _2; ++ goto -> bb139; + } + + bb167: { +- _122 = discriminant(_121); +- switchInt(move _122) -> [0: bb153, 1: bb166, otherwise: bb59]; ++ StorageLive(_171); ++ _171 = move _2; ++ goto -> bb140; + } + + bb168: { +- _121 = as Future>::poll(move _123, move _124) -> [return: bb167, unwind: bb155]; ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb168, unwind continue]; + } + + bb169: { +- _125 = move _2; +- _124 = std::future::get_context::<'_, '_>(move _125) -> [return: bb168, unwind: bb155]; ++ assert(const false, "`async fn` resumed after completion") -> [success: bb169, unwind continue]; + } + + bb170: { +- _126 = &mut _112; +- _123 = Pin::<&mut impl Future>::new_unchecked(move _126) -> [return: bb169, unwind: bb155]; +- } +- +- bb171: { +- StorageLive(_112); +- _112 = async_drop_in_place::(copy (_127.0: &mut SyncThenAsync)) -> [return: bb170, unwind: bb155]; +- } +- +- bb172: { +- _128 = &mut _11; +- _127 = Pin::<&mut SyncThenAsync>::new_unchecked(move _128) -> [return: bb171, unwind: bb46]; +- } +- +- bb173: { +- StorageDead(_129); +- goto -> bb18; +- } +- +- bb174: { +- StorageDead(_129); +- goto -> bb31; +- } +- +- bb175 (cleanup): { +- StorageDead(_129); +- goto -> bb47; +- } +- +- bb176: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb176, unwind: bb175]; +- } +- +- bb177: { +- _2 = move _130; +- StorageDead(_130); +- goto -> bb176; +- } +- +- bb178: { +- _2 = move _130; +- StorageDead(_130); +- goto -> bb183; +- } +- +- bb179: { +- StorageLive(_130); +- _130 = yield(const ()) -> [resume: bb177, drop: bb178]; +- } +- +- bb180: { +- _132 = discriminant(_131); +- switchInt(move _132) -> [0: bb174, 1: bb179, otherwise: bb59]; +- } +- +- bb181: { +- _131 = as Future>::poll(move _133, move _134) -> [return: bb180, unwind: bb175]; +- } +- +- bb182: { +- _135 = move _2; +- _134 = std::future::get_context::<'_, '_>(move _135) -> [return: bb181, unwind: bb175]; +- } +- +- bb183: { +- _136 = &mut _129; +- _133 = Pin::<&mut impl Future>::new_unchecked(move _136) -> [return: bb182, unwind: bb175]; +- } +- +- bb184: { +- _2 = move _137; +- StorageDead(_137); +- goto -> bb190; +- } +- +- bb185: { +- _2 = move _137; +- StorageDead(_137); +- goto -> bb183; +- } +- +- bb186: { +- StorageLive(_137); +- _137 = yield(const ()) -> [resume: bb184, drop: bb185]; +- } +- +- bb187: { +- _139 = discriminant(_138); +- switchInt(move _139) -> [0: bb173, 1: bb186, otherwise: bb59]; +- } +- +- bb188: { +- _138 = as Future>::poll(move _140, move _141) -> [return: bb187, unwind: bb175]; +- } +- +- bb189: { +- _142 = move _2; +- _141 = std::future::get_context::<'_, '_>(move _142) -> [return: bb188, unwind: bb175]; +- } +- +- bb190: { +- _143 = &mut _129; +- _140 = Pin::<&mut impl Future>::new_unchecked(move _143) -> [return: bb189, unwind: bb175]; +- } +- +- bb191: { +- StorageLive(_129); +- _129 = async_drop_in_place::(copy (_144.0: &mut AsyncStruct)) -> [return: bb190, unwind: bb175]; +- } +- +- bb192: { +- _145 = &mut _8; +- _144 = Pin::<&mut AsyncStruct>::new_unchecked(move _145) -> [return: bb191, unwind: bb47]; +- } +- +- bb193: { +- StorageDead(_146); +- goto -> bb19; +- } +- +- bb194: { +- StorageDead(_146); +- goto -> bb32; +- } +- +- bb195 (cleanup): { +- StorageDead(_146); +- goto -> bb48; +- } +- +- bb196: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb196, unwind: bb195]; +- } +- +- bb197: { +- _2 = move _147; +- StorageDead(_147); +- goto -> bb196; +- } +- +- bb198: { +- _2 = move _147; +- StorageDead(_147); +- goto -> bb203; +- } +- +- bb199: { +- StorageLive(_147); +- _147 = yield(const ()) -> [resume: bb197, drop: bb198]; +- } +- +- bb200: { +- _149 = discriminant(_148); +- switchInt(move _149) -> [0: bb194, 1: bb199, otherwise: bb59]; +- } +- +- bb201: { +- _148 = as Future>::poll(move _150, move _151) -> [return: bb200, unwind: bb195]; +- } +- +- bb202: { +- _152 = move _2; +- _151 = std::future::get_context::<'_, '_>(move _152) -> [return: bb201, unwind: bb195]; +- } +- +- bb203: { +- _153 = &mut _146; +- _150 = Pin::<&mut impl Future>::new_unchecked(move _153) -> [return: bb202, unwind: bb195]; +- } +- +- bb204: { +- _2 = move _154; +- StorageDead(_154); +- goto -> bb210; +- } +- +- bb205: { +- _2 = move _154; +- StorageDead(_154); +- goto -> bb203; +- } +- +- bb206: { +- StorageLive(_154); +- _154 = yield(const ()) -> [resume: bb204, drop: bb205]; +- } +- +- bb207: { +- _156 = discriminant(_155); +- switchInt(move _156) -> [0: bb193, 1: bb206, otherwise: bb59]; +- } +- +- bb208: { +- _155 = as Future>::poll(move _157, move _158) -> [return: bb207, unwind: bb195]; +- } +- +- bb209: { +- _159 = move _2; +- _158 = std::future::get_context::<'_, '_>(move _159) -> [return: bb208, unwind: bb195]; +- } +- +- bb210: { +- _160 = &mut _146; +- _157 = Pin::<&mut impl Future>::new_unchecked(move _160) -> [return: bb209, unwind: bb195]; +- } +- +- bb211: { +- StorageLive(_146); +- _146 = async_drop_in_place::<[AsyncInt; 2]>(copy (_161.0: &mut [AsyncInt; 2])) -> [return: bb210, unwind: bb195]; +- } +- +- bb212: { +- _162 = &mut _5; +- _161 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _162) -> [return: bb211, unwind: bb48]; +- } +- +- bb213: { +- StorageDead(_163); +- goto -> bb20; +- } +- +- bb214: { +- StorageDead(_163); +- goto -> bb33; +- } +- +- bb215 (cleanup): { +- StorageDead(_163); +- goto -> bb49; +- } +- +- bb216: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb216, unwind: bb215]; +- } +- +- bb217: { +- _2 = move _164; +- StorageDead(_164); +- goto -> bb216; +- } +- +- bb218: { +- _2 = move _164; +- StorageDead(_164); +- goto -> bb223; +- } +- +- bb219: { +- StorageLive(_164); +- _164 = yield(const ()) -> [resume: bb217, drop: bb218]; +- } +- +- bb220: { +- _166 = discriminant(_165); +- switchInt(move _166) -> [0: bb214, 1: bb219, otherwise: bb59]; +- } +- +- bb221: { +- _165 = as Future>::poll(move _167, move _168) -> [return: bb220, unwind: bb215]; +- } +- +- bb222: { +- _169 = move _2; +- _168 = std::future::get_context::<'_, '_>(move _169) -> [return: bb221, unwind: bb215]; +- } +- +- bb223: { +- _170 = &mut _163; +- _167 = Pin::<&mut impl Future>::new_unchecked(move _170) -> [return: bb222, unwind: bb215]; +- } +- +- bb224: { +- _2 = move _171; +- StorageDead(_171); +- goto -> bb230; +- } +- +- bb225: { +- _2 = move _171; +- StorageDead(_171); +- goto -> bb223; +- } +- +- bb226: { +- StorageLive(_171); +- _171 = yield(const ()) -> [resume: bb224, drop: bb225]; +- } +- +- bb227: { +- _173 = discriminant(_172); +- switchInt(move _173) -> [0: bb213, 1: bb226, otherwise: bb59]; +- } +- +- bb228: { +- _172 = as Future>::poll(move _174, move _175) -> [return: bb227, unwind: bb215]; +- } +- +- bb229: { +- _176 = move _2; +- _175 = std::future::get_context::<'_, '_>(move _176) -> [return: bb228, unwind: bb215]; +- } +- +- bb230: { +- _177 = &mut _163; +- _174 = Pin::<&mut impl Future>::new_unchecked(move _177) -> [return: bb229, unwind: bb215]; +- } +- +- bb231: { +- StorageLive(_163); +- _163 = async_drop_in_place::(copy (_178.0: &mut AsyncInt)) -> [return: bb230, unwind: bb215]; +- } +- +- bb232: { +- _179 = &mut _4; +- _178 = Pin::<&mut AsyncInt>::new_unchecked(move _179) -> [return: bb231, unwind: bb49]; + nop; -+ (((*_140) as variant#20).0: SyncInt) = SyncInt(const 0_i32); ++ (((*_182) as variant#20).1: SyncInt) = SyncInt(const 0_i32); + nop; -+ (((*_140) as variant#20).1: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_182) as variant#20).2: AsyncInt) = AsyncInt(const 0_i32); + nop; + StorageLive(_6); + _6 = AsyncInt(const 1_i32); + StorageLive(_7); + _7 = AsyncInt(const 2_i32); -+ (((*_140) as variant#18).2: [AsyncInt; 2]) = [move _6, move _7]; ++ (((*_182) as variant#18).3: [AsyncInt; 2]) = [move _6, move _7]; + goto -> bb1; } } diff --git a/tests/mir-opt/coroutine/async_drop.rs b/tests/mir-opt/coroutine/async_drop.rs index 1b4a382f960aa..506baac1dabd8 100644 --- a/tests/mir-opt/coroutine/async_drop.rs +++ b/tests/mir-opt/coroutine/async_drop.rs @@ -35,7 +35,6 @@ where } // EMIT_MIR async_drop.simple-{closure#0}.ElaborateDrops.diff -// EMIT_MIR async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir // EMIT_MIR async_drop.simple-{closure#0}.StateTransform.diff // EMIT_MIR async_drop.simple-{closure#0}.coroutine_drop_async.0.mir async fn simple() { @@ -44,7 +43,6 @@ async fn simple() { } // EMIT_MIR async_drop.double-{closure#0}.ElaborateDrops.diff -// EMIT_MIR async_drop.double-{closure#0}.coroutine_async_drop_expand.0.mir // EMIT_MIR async_drop.double-{closure#0}.StateTransform.diff // EMIT_MIR async_drop.double-{closure#0}.coroutine_drop_async.0.mir async fn double() { diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff index 6997c2efaf3a7..0e18ddf5ad2dd 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.ElaborateDrops.diff @@ -8,11 +8,22 @@ let mut _0: (); let _3: SyncInt; + let mut _5: impl std::future::Future; -+ let mut _6: std::pin::Pin<&mut AsyncInt>; -+ let mut _7: &mut AsyncInt; -+ let mut _8: impl std::future::Future; -+ let mut _9: std::pin::Pin<&mut {async fn body of simple()}>; -+ let mut _10: &mut {async fn body of simple()}; ++ let mut _6: std::future::ResumeTy; ++ let mut _7: std::task::Poll<()>; ++ let mut _8: isize; ++ let mut _9: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _10: &mut std::task::Context<'_>; ++ let mut _11: std::future::ResumeTy; ++ let mut _12: &mut impl std::future::Future; ++ let mut _13: std::future::ResumeTy; ++ let mut _14: std::task::Poll<()>; ++ let mut _15: isize; ++ let mut _16: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _17: &mut std::task::Context<'_>; ++ let mut _18: std::future::ResumeTy; ++ let mut _19: &mut impl std::future::Future; ++ let mut _20: std::pin::Pin<&mut AsyncInt>; ++ let mut _21: &mut AsyncInt; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -28,7 +39,7 @@ _4 = AsyncInt(const 0_i32); _0 = const (); - drop(_4) -> [return: bb1, unwind: bb7, drop: bb4]; -+ goto -> bb16; ++ goto -> bb31; } bb1: { @@ -39,7 +50,7 @@ bb2: { StorageDead(_3); - drop(_1) -> [return: bb3, drop: bb6, unwind continue]; -+ goto -> bb22; ++ drop(_1) -> [return: bb3, unwind: bb9]; } bb3: { @@ -98,46 +109,93 @@ + } + + bb14: { -+ async drop(_4; poll=_5) -> [return: bb11, unwind: bb13, drop: bb12]; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb14, unwind: bb13]; + } + + bb15: { -+ StorageLive(_5); -+ _5 = async_drop_in_place::(copy (_6.0: &mut AsyncInt)) -> [return: bb14, unwind: bb13]; ++ _2 = move _6; ++ StorageDead(_6); ++ goto -> bb14; + } + + bb16: { -+ _7 = &mut _4; -+ _6 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb15, unwind: bb7]; ++ _2 = move _6; ++ StorageDead(_6); ++ goto -> bb22; + } + + bb17: { -+ StorageDead(_8); -+ goto -> bb3; ++ StorageLive(_6); ++ _6 = yield(const ()) -> [resume: bb15, drop: bb16]; + } + + bb18: { -+ StorageDead(_8); -+ goto -> bb6; ++ unreachable; + } + -+ bb19 (cleanup): { -+ StorageDead(_8); -+ goto -> bb9; ++ bb19: { ++ _8 = discriminant(_7); ++ switchInt(move _8) -> [0: bb12, 1: bb17, otherwise: bb18]; + } + + bb20: { -+ async drop(_1; poll=_8) -> [return: bb17, unwind: bb19, drop: bb18]; ++ _7 = as Future>::poll(move _9, move _10) -> [return: bb19, unwind: bb13]; + } + + bb21: { -+ StorageLive(_8); -+ _8 = async_drop_in_place::<{async fn body of simple()}>(copy (_9.0: &mut {async fn body of simple()})) -> [return: bb20, unwind: bb19]; ++ _11 = move _2; ++ _10 = std::future::get_context::<'_, '_>(move _11) -> [return: bb20, unwind: bb13]; + } + + bb22: { -+ _10 = &mut _1; -+ _9 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb21, unwind: bb9]; ++ _12 = &mut _5; ++ _9 = Pin::<&mut impl Future>::new_unchecked(move _12) -> [return: bb21, unwind: bb13]; ++ } ++ ++ bb23: { ++ _2 = move _13; ++ StorageDead(_13); ++ goto -> bb29; ++ } ++ ++ bb24: { ++ _2 = move _13; ++ StorageDead(_13); ++ goto -> bb22; ++ } ++ ++ bb25: { ++ StorageLive(_13); ++ _13 = yield(const ()) -> [resume: bb23, drop: bb24]; ++ } ++ ++ bb26: { ++ _15 = discriminant(_14); ++ switchInt(move _15) -> [0: bb11, 1: bb25, otherwise: bb18]; ++ } ++ ++ bb27: { ++ _14 = as Future>::poll(move _16, move _17) -> [return: bb26, unwind: bb13]; ++ } ++ ++ bb28: { ++ _18 = move _2; ++ _17 = std::future::get_context::<'_, '_>(move _18) -> [return: bb27, unwind: bb13]; ++ } ++ ++ bb29: { ++ _19 = &mut _5; ++ _16 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb28, unwind: bb13]; ++ } ++ ++ bb30: { ++ StorageLive(_5); ++ _5 = async_drop_in_place::(copy (_20.0: &mut AsyncInt)) -> [return: bb29, unwind: bb13]; ++ } ++ ++ bb31: { ++ _21 = &mut _4; ++ _20 = Pin::<&mut AsyncInt>::new_unchecked(move _21) -> [return: bb30, unwind: bb7]; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff index 640bb46dd6fcd..0f2b3ab13ec58 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.StateTransform.diff @@ -14,8 +14,8 @@ + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], -+ Suspend0 (3): [_s0, _s1, _s2, _s3], -+ Suspend1 (4): [_s1, _s2, _s3], ++ Suspend0 (3): [_s1, _s2, _s3], ++ Suspend1 (4): [_s0, _s1, _s2, _s3], + } + storage_conflicts = BitMatrix(4x4) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3)} + } @@ -25,31 +25,37 @@ + let mut _0: std::task::Poll<()>; let _3: SyncInt; let mut _5: impl std::future::Future; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; - let mut _9: std::pin::Pin<&mut {async fn body of simple()}>; - let mut _10: &mut {async fn body of simple()}; -+ let mut _11: std::task::Poll<()>; -+ let mut _12: &mut std::task::Context<'_>; -+ let mut _13: &mut impl std::future::Future; -+ let mut _14: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _15: isize; -+ let mut _16: &mut std::task::Context<'_>; -+ let mut _17: &mut impl std::future::Future; -+ let mut _18: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _19: isize; -+ let mut _20: (); -+ let mut _21: u32; -+ let mut _22: &mut {async fn body of simple()}; +- let mut _6: std::future::ResumeTy; ++ let mut _6: &mut std::task::Context<'_>; + let mut _7: std::task::Poll<()>; + let mut _8: isize; + let mut _9: std::pin::Pin<&mut impl std::future::Future>; + let mut _10: &mut std::task::Context<'_>; +- let mut _11: std::future::ResumeTy; ++ let mut _11: &mut std::task::Context<'_>; + let mut _12: &mut impl std::future::Future; +- let mut _13: std::future::ResumeTy; ++ let mut _13: &mut std::task::Context<'_>; + let mut _14: std::task::Poll<()>; + let mut _15: isize; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: &mut std::task::Context<'_>; +- let mut _18: std::future::ResumeTy; ++ let mut _18: &mut std::task::Context<'_>; + let mut _19: &mut impl std::future::Future; + let mut _20: std::pin::Pin<&mut AsyncInt>; + let mut _21: &mut AsyncInt; ++ let mut _22: (); ++ let mut _23: u32; ++ let mut _24: &mut {async fn body of simple()}; scope 1 { - debug sync_int => _3; -+ debug sync_int => (((*_22) as variant#4).0: SyncInt); ++ debug sync_int => (((*_24) as variant#4).1: SyncInt); + coroutine debug async_int => _s2; let _4: AsyncInt; scope 2 { - debug async_int => _4; -+ debug async_int => (((*_22) as variant#4).1: AsyncInt); ++ debug async_int => (((*_24) as variant#4).2: AsyncInt); } } @@ -59,29 +65,29 @@ - StorageLive(_4); - _4 = AsyncInt(const 0_i32); - _0 = const (); -- goto -> bb15; -+ _22 = copy (_1.0: &mut {async fn body of simple()}); -+ _21 = discriminant((*_22)); -+ switchInt(move _21) -> [0: bb29, 1: bb28, 2: bb27, 3: bb25, 4: bb26, otherwise: bb19]; +- goto -> bb30; ++ _24 = copy (_1.0: &mut {async fn body of simple()}); ++ _23 = discriminant((*_24)); ++ switchInt(move _23) -> [0: bb26, 1: bb25, 2: bb24, 3: bb22, 4: bb23, otherwise: bb11]; } bb1: { - StorageDead(_4); - drop(_3) -> [return: bb2, unwind: bb8]; + nop; -+ drop((((*_22) as variant#4).0: SyncInt)) -> [return: bb2, unwind: bb5]; ++ drop((((*_24) as variant#4).1: SyncInt)) -> [return: bb2, unwind: bb5]; } bb2: { - StorageDead(_3); -- goto -> bb21; +- drop(_1) -> [return: bb3, unwind: bb9]; + nop; -+ goto -> bb16; ++ goto -> bb20; } bb3: { -+ _0 = Poll::<()>::Ready(move (((*_22) as variant#3).0: ())); -+ discriminant((*_22)) = 1; ++ _0 = Poll::<()>::Ready(move (((*_24) as variant#4).0: ())); ++ discriminant((*_24)) = 1; return; } @@ -90,7 +96,7 @@ - goto -> bb5; + bb4 (cleanup): { + nop; -+ drop((((*_22) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; ++ drop((((*_24) as variant#4).1: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; } - bb5: { @@ -103,7 +109,7 @@ - bb6: { - coroutine_drop; + bb6 (cleanup): { -+ goto -> bb24; ++ goto -> bb21; } - bb7 (cleanup): { @@ -124,133 +130,155 @@ - bb9 (cleanup): { - resume; + bb9: { -+ _12 = move _2; -+ goto -> bb18; ++ assert(const false, "`async fn` resumed after async drop") -> [success: bb9, unwind: bb8]; } bb10: { - StorageDead(_5); - goto -> bb1; -+ nop; -+ (((*_22) as variant#4).2: impl std::future::Future) = async_drop_in_place::(copy (_6.0: &mut AsyncInt)) -> [return: bb9, unwind: bb8]; ++ _2 = move _6; ++ StorageDead(_6); ++ goto -> bb9; } bb11: { - StorageDead(_5); - goto -> bb4; -+ _7 = &mut (((*_22) as variant#4).1: AsyncInt); -+ _6 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb10, unwind: bb4]; ++ unreachable; } - bb12 (cleanup): { - StorageDead(_5); - goto -> bb7; + bb12: { -+ StorageDead(_8); -+ goto -> bb3; ++ _2 = move _13; ++ StorageDead(_13); ++ goto -> bb17; } -- bb13: { -- async drop(_4; poll=_5) -> [return: bb10, unwind: bb12, drop: bb11]; -+ bb13 (cleanup): { -+ StorageDead(_8); -+ goto -> bb6; + bb13: { +- assert(const false, "`async fn` resumed after async drop") -> [success: bb13, unwind: bb12]; ++ StorageLive(_13); ++ _0 = Poll::<()>::Pending; ++ StorageDead(_13); ++ discriminant((*_24)) = 4; ++ return; } bb14: { -- StorageLive(_5); -- _5 = async_drop_in_place::(copy (_6.0: &mut AsyncInt)) -> [return: bb13, unwind: bb12]; -+ goto -> bb23; +- _2 = move _6; +- StorageDead(_6); +- goto -> bb13; ++ _15 = discriminant(_14); ++ switchInt(move _15) -> [0: bb7, 1: bb13, otherwise: bb11]; } bb15: { -- _7 = &mut _4; -- _6 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb14, unwind: bb7]; -+ StorageLive(_8); -+ _8 = async_drop_in_place::<{async fn body of simple()}>(copy (_9.0: &mut {async fn body of simple()})) -> [return: bb14, unwind: bb13]; +- _2 = move _6; +- StorageDead(_6); +- goto -> bb21; ++ _14 = as Future>::poll(move _16, move _17) -> [return: bb14, unwind: bb8]; } bb16: { -- StorageDead(_8); -- goto -> bb3; -+ _10 = &mut (*_22); -+ _9 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb15, unwind: bb6]; +- StorageLive(_6); +- _6 = yield(const ()) -> [resume: bb14, drop: bb15]; ++ _18 = move _2; ++ _17 = move _18; ++ goto -> bb15; } bb17: { -- StorageDead(_8); -- goto -> bb6; -+ _0 = Poll::<()>::Pending; -+ discriminant((*_22)) = 3; -+ return; +- unreachable; ++ _19 = &mut (((*_24) as variant#4).3: impl std::future::Future); ++ _16 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb16, unwind: bb8]; } -- bb18 (cleanup): { -- StorageDead(_8); -- goto -> bb9; -+ bb18: { -+ StorageLive(_14); -+ _13 = &mut (((*_22) as variant#4).2: impl std::future::Future); -+ _14 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb21, unwind: bb24]; + bb18: { +- _8 = discriminant(_7); +- switchInt(move _8) -> [0: bb11, 1: bb16, otherwise: bb17]; ++ nop; ++ (((*_24) as variant#4).3: impl std::future::Future) = async_drop_in_place::(copy (_20.0: &mut AsyncInt)) -> [return: bb17, unwind: bb8]; } bb19: { -- async drop(_1; poll=_8) -> [return: bb16, unwind: bb18, drop: bb17]; -+ unreachable; +- _7 = as Future>::poll(move _9, move _10) -> [return: bb18, unwind: bb12]; ++ _21 = &mut (((*_24) as variant#4).2: AsyncInt); ++ _20 = Pin::<&mut AsyncInt>::new_unchecked(move _21) -> [return: bb18, unwind: bb4]; } bb20: { -- StorageLive(_8); -- _8 = async_drop_in_place::<{async fn body of simple()}>(copy (_9.0: &mut {async fn body of simple()})) -> [return: bb19, unwind: bb18]; -+ StorageDead(_14); -+ _15 = discriminant(_11); -+ switchInt(move _15) -> [0: bb7, 1: bb17, otherwise: bb19]; +- _11 = move _2; +- _10 = std::future::get_context::<'_, '_>(move _11) -> [return: bb19, unwind: bb12]; ++ goto -> bb3; } - bb21: { -- _10 = &mut _1; -- _9 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb20, unwind: bb9]; -+ _11 = as Future>::poll(move _14, move _12) -> [return: bb20, unwind: bb8]; -+ } -+ -+ bb22: { -+ assert(const false, "`async fn` resumed after async drop") -> [success: bb22, unwind: bb24]; -+ } -+ -+ bb23: { -+ goto -> bb12; -+ } -+ -+ bb24 (cleanup): { -+ discriminant((*_22)) = 2; +- bb21: { +- _12 = &mut _5; +- _9 = Pin::<&mut impl Future>::new_unchecked(move _12) -> [return: bb20, unwind: bb12]; ++ bb21 (cleanup): { ++ discriminant((*_24)) = 2; + resume; -+ } -+ -+ bb25: { -+ _12 = move _2; -+ goto -> bb18; -+ } -+ -+ bb26: { -+ _16 = move _2; -+ goto -> bb22; -+ } -+ -+ bb27: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb27, unwind continue]; -+ } -+ -+ bb28: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind continue]; -+ } -+ -+ bb29: { + } + + bb22: { +- _2 = move _13; +- StorageDead(_13); +- goto -> bb28; ++ StorageLive(_6); ++ _6 = move _2; ++ goto -> bb10; + } + + bb23: { +- _2 = move _13; +- StorageDead(_13); +- goto -> bb21; ++ StorageLive(_13); ++ _13 = move _2; ++ goto -> bb12; + } + + bb24: { +- StorageLive(_13); +- _13 = yield(const ()) -> [resume: bb22, drop: bb23]; ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb24, unwind continue]; + } + + bb25: { +- _15 = discriminant(_14); +- switchInt(move _15) -> [0: bb10, 1: bb24, otherwise: bb17]; ++ assert(const false, "`async fn` resumed after completion") -> [success: bb25, unwind continue]; + } + + bb26: { +- _14 = as Future>::poll(move _16, move _17) -> [return: bb25, unwind: bb12]; +- } +- +- bb27: { +- _18 = move _2; +- _17 = std::future::get_context::<'_, '_>(move _18) -> [return: bb26, unwind: bb12]; +- } +- +- bb28: { +- _19 = &mut _5; +- _16 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb27, unwind: bb12]; +- } +- +- bb29: { +- StorageLive(_5); +- _5 = async_drop_in_place::(copy (_20.0: &mut AsyncInt)) -> [return: bb28, unwind: bb12]; +- } +- +- bb30: { +- _21 = &mut _4; +- _20 = Pin::<&mut AsyncInt>::new_unchecked(move _21) -> [return: bb29, unwind: bb7]; + nop; -+ (((*_22) as variant#4).0: SyncInt) = SyncInt(const 0_i32); ++ (((*_24) as variant#4).1: SyncInt) = SyncInt(const 0_i32); + nop; -+ (((*_22) as variant#4).1: AsyncInt) = AsyncInt(const 0_i32); -+ (((*_22) as variant#3).0: ()) = const (); -+ goto -> bb11; ++ (((*_24) as variant#4).2: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_24) as variant#4).0: ()) = const (); ++ goto -> bb19; } } diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir deleted file mode 100644 index ae58869409262..0000000000000 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_async_drop_expand.0.mir +++ /dev/null @@ -1,193 +0,0 @@ -// MIR for `simple::{closure#0}` 0 coroutine_async_drop_expand - -fn simple::{closure#0}(_1: {async fn body of simple()}, _2: &mut Context<'_>) -> () -yields () - { - debug _task_context => _2; - let mut _0: (); - let _3: SyncInt; - let mut _5: impl std::future::Future; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; - let mut _9: std::pin::Pin<&mut {async fn body of simple()}>; - let mut _10: &mut {async fn body of simple()}; - let mut _11: std::task::Poll<()>; - let mut _12: &mut std::task::Context<'_>; - let mut _13: &mut impl std::future::Future; - let mut _14: std::pin::Pin<&mut impl std::future::Future>; - let mut _15: isize; - let mut _16: &mut std::task::Context<'_>; - let mut _17: &mut impl std::future::Future; - let mut _18: std::pin::Pin<&mut impl std::future::Future>; - let mut _19: isize; - scope 1 { - debug sync_int => _3; - let _4: AsyncInt; - scope 2 { - debug async_int => _4; - } - } - - bb0: { - StorageLive(_3); - _3 = SyncInt(const 0_i32); - StorageLive(_4); - _4 = AsyncInt(const 0_i32); - _0 = const (); - goto -> bb15; - } - - bb1: { - StorageDead(_4); - drop(_3) -> [return: bb2, unwind: bb8]; - } - - bb2: { - StorageDead(_3); - goto -> bb21; - } - - bb3: { - return; - } - - bb4: { - StorageDead(_4); - goto -> bb5; - } - - bb5: { - StorageDead(_3); - goto -> bb6; - } - - bb6: { - coroutine_drop; - } - - bb7 (cleanup): { - StorageDead(_4); - drop(_3) -> [return: bb8, unwind terminate(cleanup)]; - } - - bb8 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb9, unwind terminate(cleanup)]; - } - - bb9 (cleanup): { - resume; - } - - bb10: { - StorageDead(_5); - goto -> bb1; - } - - bb11: { - StorageDead(_5); - goto -> bb4; - } - - bb12 (cleanup): { - StorageDead(_5); - goto -> bb7; - } - - bb13: { - _12 = move _2; - goto -> bb23; - } - - bb14: { - StorageLive(_5); - _5 = async_drop_in_place::(copy (_6.0: &mut AsyncInt)) -> [return: bb13, unwind: bb12]; - } - - bb15: { - _7 = &mut _4; - _6 = Pin::<&mut AsyncInt>::new_unchecked(move _7) -> [return: bb14, unwind: bb7]; - } - - bb16: { - StorageDead(_8); - goto -> bb3; - } - - bb17: { - StorageDead(_8); - goto -> bb6; - } - - bb18 (cleanup): { - StorageDead(_8); - goto -> bb9; - } - - bb19: { - drop(_1) -> [return: bb16, unwind: bb18]; - } - - bb20: { - StorageLive(_8); - _8 = async_drop_in_place::<{async fn body of simple()}>(copy (_9.0: &mut {async fn body of simple()})) -> [return: bb19, unwind: bb18]; - } - - bb21: { - _10 = &mut _1; - _9 = Pin::<&mut {async fn body of simple()}>::new_unchecked(move _10) -> [return: bb20, unwind: bb9]; - } - - bb22: { - _12 = yield(const false) -> [resume: bb23, drop: bb28]; - } - - bb23: { - StorageLive(_14); - _13 = &mut _5; - _14 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb26, unwind continue]; - } - - bb24: { - unreachable; - } - - bb25: { - StorageDead(_14); - _15 = discriminant(_11); - switchInt(move _15) -> [0: bb10, 1: bb22, otherwise: bb24]; - } - - bb26: { - _11 = as Future>::poll(move _14, move _12) -> [return: bb25, unwind: bb12]; - } - - bb27: { - _16 = yield(const false) -> [resume: bb32, drop: bb28]; - } - - bb28: { - StorageLive(_18); - _17 = &mut _5; - _18 = Pin::<&mut impl Future>::new_unchecked(move _17) -> [return: bb31, unwind continue]; - } - - bb29: { - unreachable; - } - - bb30: { - StorageDead(_18); - _19 = discriminant(_11); - switchInt(move _19) -> [0: bb11, 1: bb27, otherwise: bb29]; - } - - bb31: { - _11 = as Future>::poll(move _18, move _16) -> [return: bb30, unwind: bb12]; - } - - bb32: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb32, unwind continue]; - } -} diff --git a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir index f67922017a1d6..bc3def602a09e 100644 --- a/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir @@ -5,35 +5,37 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte let mut _0: std::task::Poll<()>; let _3: SyncInt; let mut _5: impl std::future::Future; - let mut _6: std::pin::Pin<&mut AsyncInt>; - let mut _7: &mut AsyncInt; - let mut _8: impl std::future::Future; - let mut _9: std::pin::Pin<&mut {async fn body of simple()}>; - let mut _10: &mut {async fn body of simple()}; - let mut _11: std::task::Poll<()>; - let mut _12: &mut std::task::Context<'_>; - let mut _13: &mut impl std::future::Future; - let mut _14: std::pin::Pin<&mut impl std::future::Future>; + let mut _6: &mut std::task::Context<'_>; + let mut _7: std::task::Poll<()>; + let mut _8: isize; + let mut _9: std::pin::Pin<&mut impl std::future::Future>; + let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut std::task::Context<'_>; + let mut _12: &mut impl std::future::Future; + let mut _13: &mut std::task::Context<'_>; + let mut _14: std::task::Poll<()>; let mut _15: isize; - let mut _16: &mut std::task::Context<'_>; - let mut _17: &mut impl std::future::Future; - let mut _18: std::pin::Pin<&mut impl std::future::Future>; - let mut _19: isize; - let mut _20: (); - let mut _21: u32; - let mut _22: &mut {async fn body of simple()}; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut std::task::Context<'_>; + let mut _19: &mut impl std::future::Future; + let mut _20: std::pin::Pin<&mut AsyncInt>; + let mut _21: &mut AsyncInt; + let mut _22: (); + let mut _23: u32; + let mut _24: &mut {async fn body of simple()}; scope 1 { - debug sync_int => (((*_22) as variant#4).0: SyncInt); + debug sync_int => (((*_24) as variant#4).1: SyncInt); let _4: AsyncInt; scope 2 { - debug async_int => (((*_22) as variant#4).1: AsyncInt); + debug async_int => (((*_24) as variant#4).2: AsyncInt); } } bb0: { - _22 = copy (_1.0: &mut {async fn body of simple()}); - _21 = discriminant((*_22)); - switchInt(move _21) -> [0: bb15, 2: bb20, 3: bb18, 4: bb19, otherwise: bb21]; + _24 = copy (_1.0: &mut {async fn body of simple()}); + _23 = discriminant((*_24)); + switchInt(move _23) -> [0: bb18, 2: bb23, 3: bb21, 4: bb22, otherwise: bb24]; } bb1: { @@ -53,7 +55,7 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte bb4 (cleanup): { nop; - drop((((*_22) as variant#4).0: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; + drop((((*_24) as variant#4).1: SyncInt)) -> [return: bb5, unwind terminate(cleanup)]; } bb5 (cleanup): { @@ -62,7 +64,7 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte } bb6 (cleanup): { - goto -> bb17; + goto -> bb20; } bb7: { @@ -76,15 +78,17 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte } bb9: { - _0 = Poll::<()>::Pending; - discriminant((*_22)) = 4; - return; + _2 = move _6; + StorageDead(_6); + goto -> bb15; } bb10: { - StorageLive(_18); - _17 = &mut (((*_22) as variant#4).2: impl std::future::Future); - _18 = Pin::<&mut impl Future>::new_unchecked(move _17) -> [return: bb13, unwind: bb17]; + StorageLive(_6); + _0 = Poll::<()>::Pending; + StorageDead(_6); + discriminant((*_24)) = 3; + return; } bb11: { @@ -92,48 +96,66 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte } bb12: { - StorageDead(_18); - _19 = discriminant(_11); - switchInt(move _19) -> [0: bb7, 1: bb9, otherwise: bb11]; + _8 = discriminant(_7); + switchInt(move _8) -> [0: bb7, 1: bb10, otherwise: bb11]; } bb13: { - _11 = as Future>::poll(move _18, move _16) -> [return: bb12, unwind: bb8]; + _7 = as Future>::poll(move _9, move _10) -> [return: bb12, unwind: bb8]; } bb14: { - _0 = Poll::<()>::Ready(const ()); - return; + _11 = move _2; + _10 = move _11; + goto -> bb13; } bb15: { - goto -> bb16; + _12 = &mut (((*_24) as variant#4).3: impl std::future::Future); + _9 = Pin::<&mut impl Future>::new_unchecked(move _12) -> [return: bb14, unwind: bb8]; } bb16: { - goto -> bb14; + _2 = move _13; + StorageDead(_13); + goto -> bb15; } - bb17 (cleanup): { - discriminant((*_22)) = 2; - resume; + bb17: { + _0 = Poll::<()>::Ready(const ()); + return; } bb18: { - _12 = move _2; - goto -> bb10; + goto -> bb19; } bb19: { - _16 = move _2; - goto -> bb10; + goto -> bb17; } - bb20: { - assert(const false, "`async fn` resumed after panicking") -> [success: bb20, unwind continue]; + bb20 (cleanup): { + discriminant((*_24)) = 2; + resume; } bb21: { + StorageLive(_6); + _6 = move _2; + goto -> bb9; + } + + bb22: { + StorageLive(_13); + _13 = move _2; + goto -> bb16; + } + + bb23: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb23, unwind continue]; + } + + bb24: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir index 6e14fc04ec4ad..1790b350c7b49 100644 --- a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir +++ b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir @@ -2,32 +2,37 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { debug _task_context => _2; - debug x => ((*_18).0: T); + debug x => ((*_23).0: T); let mut _0: std::task::Poll<()>; let _3: T; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut T>; - let mut _6: &mut T; - let mut _7: std::task::Poll<()>; - let mut _8: &mut std::task::Context<'_>; - let mut _9: &mut impl std::future::Future; - let mut _10: std::pin::Pin<&mut impl std::future::Future>; - let mut _11: isize; + let mut _5: &mut std::task::Context<'_>; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; + let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; let mut _12: &mut std::task::Context<'_>; - let mut _13: &mut impl std::future::Future; - let mut _14: std::pin::Pin<&mut impl std::future::Future>; - let mut _15: isize; - let mut _16: (); - let mut _17: u32; - let mut _18: &mut {async fn body of a()}; + let mut _13: std::task::Poll<()>; + let mut _14: isize; + let mut _15: std::pin::Pin<&mut impl std::future::Future>; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut impl std::future::Future; + let mut _19: std::pin::Pin<&mut T>; + let mut _20: &mut T; + let mut _21: (); + let mut _22: u32; + let mut _23: &mut {async fn body of a()}; scope 1 { - debug x => (((*_18) as variant#4).0: T); + debug x => (((*_23) as variant#4).1: T); } bb0: { - _18 = copy (_1.0: &mut {async fn body of a()}); - _17 = discriminant((*_18)); - switchInt(move _17) -> [0: bb10, 3: bb13, 4: bb14, otherwise: bb15]; + _23 = copy (_1.0: &mut {async fn body of a()}); + _22 = discriminant((*_23)); + switchInt(move _22) -> [0: bb13, 3: bb16, 4: bb17, otherwise: bb18]; } bb1: { @@ -46,15 +51,17 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb4: { - _0 = Poll::<()>::Pending; - discriminant((*_18)) = 4; - return; + _2 = move _5; + StorageDead(_5); + goto -> bb10; } bb5: { - StorageLive(_14); - _13 = &mut (((*_18) as variant#4).1: impl std::future::Future); - _14 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb8, unwind unreachable]; + StorageLive(_5); + _0 = Poll::<()>::Pending; + StorageDead(_5); + discriminant((*_23)) = 3; + return; } bb6: { @@ -62,43 +69,61 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb7: { - StorageDead(_14); - _15 = discriminant(_7); - switchInt(move _15) -> [0: bb3, 1: bb4, otherwise: bb6]; + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb3, 1: bb5, otherwise: bb6]; } bb8: { - _7 = as Future>::poll(move _14, move _12) -> [return: bb7, unwind unreachable]; + _6 = as Future>::poll(move _8, move _9) -> [return: bb7, unwind unreachable]; } bb9: { - _0 = Poll::<()>::Ready(const ()); - return; + _10 = move _2; + _9 = move _10; + goto -> bb8; } bb10: { - goto -> bb12; + _11 = &mut (((*_23) as variant#4).2: impl std::future::Future); + _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb9, unwind unreachable]; } bb11: { - goto -> bb9; + _2 = move _12; + StorageDead(_12); + goto -> bb10; } bb12: { - drop(((*_18).0: T)) -> [return: bb11, unwind unreachable]; + _0 = Poll::<()>::Ready(const ()); + return; } bb13: { - _8 = move _2; - goto -> bb5; + goto -> bb15; } bb14: { - _12 = move _2; - goto -> bb5; + goto -> bb12; } bb15: { + drop(((*_23).0: T)) -> [return: bb14, unwind unreachable]; + } + + bb16: { + StorageLive(_5); + _5 = move _2; + goto -> bb4; + } + + bb17: { + StorageLive(_12); + _12 = move _2; + goto -> bb11; + } + + bb18: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir index b39a3dba1fcd0..83bfc3992b93b 100644 --- a/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir +++ b/tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir @@ -2,32 +2,37 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { debug _task_context => _2; - debug x => ((*_18).0: T); + debug x => ((*_23).0: T); let mut _0: std::task::Poll<()>; let _3: T; let mut _4: impl std::future::Future; - let mut _5: std::pin::Pin<&mut T>; - let mut _6: &mut T; - let mut _7: std::task::Poll<()>; - let mut _8: &mut std::task::Context<'_>; - let mut _9: &mut impl std::future::Future; - let mut _10: std::pin::Pin<&mut impl std::future::Future>; - let mut _11: isize; + let mut _5: &mut std::task::Context<'_>; + let mut _6: std::task::Poll<()>; + let mut _7: isize; + let mut _8: std::pin::Pin<&mut impl std::future::Future>; + let mut _9: &mut std::task::Context<'_>; + let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; let mut _12: &mut std::task::Context<'_>; - let mut _13: &mut impl std::future::Future; - let mut _14: std::pin::Pin<&mut impl std::future::Future>; - let mut _15: isize; - let mut _16: (); - let mut _17: u32; - let mut _18: &mut {async fn body of a()}; + let mut _13: std::task::Poll<()>; + let mut _14: isize; + let mut _15: std::pin::Pin<&mut impl std::future::Future>; + let mut _16: &mut std::task::Context<'_>; + let mut _17: &mut std::task::Context<'_>; + let mut _18: &mut impl std::future::Future; + let mut _19: std::pin::Pin<&mut T>; + let mut _20: &mut T; + let mut _21: (); + let mut _22: u32; + let mut _23: &mut {async fn body of a()}; scope 1 { - debug x => (((*_18) as variant#4).0: T); + debug x => (((*_23) as variant#4).1: T); } bb0: { - _18 = copy (_1.0: &mut {async fn body of a()}); - _17 = discriminant((*_18)); - switchInt(move _17) -> [0: bb14, 2: bb20, 3: bb18, 4: bb19, otherwise: bb21]; + _23 = copy (_1.0: &mut {async fn body of a()}); + _22 = discriminant((*_23)); + switchInt(move _22) -> [0: bb17, 2: bb23, 3: bb21, 4: bb22, otherwise: bb24]; } bb1: { @@ -42,11 +47,11 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) bb3 (cleanup): { nop; - goto -> bb7; + goto -> bb15; } bb4 (cleanup): { - goto -> bb17; + goto -> bb20; } bb5: { @@ -59,73 +64,93 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) goto -> bb3; } - bb7 (cleanup): { - goto -> bb4; + bb7: { + _2 = move _5; + StorageDead(_5); + goto -> bb13; } bb8: { + StorageLive(_5); _0 = Poll::<()>::Pending; - discriminant((*_18)) = 4; + StorageDead(_5); + discriminant((*_23)) = 3; return; } bb9: { - StorageLive(_14); - _13 = &mut (((*_18) as variant#4).1: impl std::future::Future); - _14 = Pin::<&mut impl Future>::new_unchecked(move _13) -> [return: bb12, unwind: bb17]; + unreachable; } bb10: { - unreachable; + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb5, 1: bb8, otherwise: bb9]; } bb11: { - StorageDead(_14); - _15 = discriminant(_7); - switchInt(move _15) -> [0: bb5, 1: bb8, otherwise: bb10]; + _6 = as Future>::poll(move _8, move _9) -> [return: bb10, unwind: bb6]; } bb12: { - _7 = as Future>::poll(move _14, move _12) -> [return: bb11, unwind: bb6]; + _10 = move _2; + _9 = move _10; + goto -> bb11; } bb13: { - _0 = Poll::<()>::Ready(const ()); - return; + _11 = &mut (((*_23) as variant#4).2: impl std::future::Future); + _8 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb12, unwind: bb6]; } bb14: { - goto -> bb16; + _2 = move _12; + StorageDead(_12); + goto -> bb13; } - bb15: { - goto -> bb13; + bb15 (cleanup): { + goto -> bb4; } bb16: { - drop(((*_18).0: T)) -> [return: bb15, unwind: bb4]; + _0 = Poll::<()>::Ready(const ()); + return; } - bb17 (cleanup): { - discriminant((*_18)) = 2; - resume; + bb17: { + goto -> bb19; } bb18: { - _8 = move _2; - goto -> bb9; + goto -> bb16; } bb19: { - _12 = move _2; - goto -> bb9; + drop(((*_23).0: T)) -> [return: bb18, unwind: bb4]; } - bb20: { - assert(const false, "`async fn` resumed after panicking") -> [success: bb20, unwind continue]; + bb20 (cleanup): { + discriminant((*_23)) = 2; + resume; } bb21: { + StorageLive(_5); + _5 = move _2; + goto -> bb7; + } + + bb22: { + StorageLive(_12); + _12 = move _2; + goto -> bb14; + } + + bb23: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb23, unwind continue]; + } + + bb24: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir b/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir index ecb77a4ab3a70..3d1ee14cc0740 100644 --- a/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir +++ b/tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir @@ -14,17 +14,38 @@ yields () let mut _10: *mut Foo; let mut _11: bool; let mut _12: impl std::future::Future; - let mut _13: std::pin::Pin<&mut Foo>; - let mut _14: &mut Foo; - let mut _15: *mut Foo; - let mut _16: bool; - let mut _17: impl std::future::Future; - let mut _18: std::pin::Pin<&mut Foo>; - let mut _19: &mut Foo; + let mut _13: std::future::ResumeTy; + let mut _14: std::task::Poll<()>; + let mut _15: isize; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: &mut std::task::Context<'_>; + let mut _18: std::future::ResumeTy; + let mut _19: &mut impl std::future::Future; + let mut _20: std::pin::Pin<&mut Foo>; + let mut _21: &mut Foo; + let mut _22: *mut Foo; + let mut _23: bool; + let mut _24: impl std::future::Future; + let mut _25: std::future::ResumeTy; + let mut _26: std::task::Poll<()>; + let mut _27: isize; + let mut _28: std::pin::Pin<&mut impl std::future::Future>; + let mut _29: &mut std::task::Context<'_>; + let mut _30: std::future::ResumeTy; + let mut _31: &mut impl std::future::Future; + let mut _32: std::future::ResumeTy; + let mut _33: std::task::Poll<()>; + let mut _34: isize; + let mut _35: std::pin::Pin<&mut impl std::future::Future>; + let mut _36: &mut std::task::Context<'_>; + let mut _37: std::future::ResumeTy; + let mut _38: &mut impl std::future::Future; + let mut _39: std::pin::Pin<&mut Foo>; + let mut _40: &mut Foo; bb0: { _3 = move (_1.0: &mut [Foo; 1]); - goto -> bb22; + goto -> bb44; } bb1: { @@ -49,7 +70,7 @@ yields () bb5: { _10 = &raw mut (*_5)[_7]; _7 = Add(move _7, const 1_usize); - goto -> bb11; + goto -> bb19; } bb6: { @@ -68,72 +89,184 @@ yields () } bb9: { - async drop((*_10); poll=_12) -> [return: bb7, unwind: bb8]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb9, unwind: bb8]; } bb10: { - StorageLive(_12); - _12 = async_drop_in_place::(copy (_13.0: &mut Foo)) -> [return: bb9, unwind: bb8]; + _2 = move _13; + StorageDead(_13); + goto -> bb9; } bb11: { - _14 = &mut (*_10); - _13 = Pin::<&mut Foo>::new_unchecked(move _14) -> [return: bb10, unwind: bb4]; + _2 = move _13; + StorageDead(_13); + goto -> bb17; } bb12: { - _15 = &raw mut (*_5)[_7]; - _7 = Add(move _7, const 1_usize); - goto -> bb19; + StorageLive(_13); + _13 = yield(const ()) -> [resume: bb10, drop: bb11]; } bb13: { - _16 = Eq(copy _7, copy _6); - switchInt(move _16) -> [0: bb12, otherwise: bb1]; + unreachable; } bb14: { - StorageDead(_17); - goto -> bb13; + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb7, 1: bb12, otherwise: bb13]; } bb15: { - StorageDead(_17); - goto -> bb6; + _14 = as Future>::poll(move _16, move _17) -> [return: bb14, unwind: bb8]; } - bb16 (cleanup): { - StorageDead(_17); - goto -> bb4; + bb16: { + _18 = move _2; + _17 = std::future::get_context::<'_, '_>(move _18) -> [return: bb15, unwind: bb8]; } bb17: { - async drop((*_15); poll=_17) -> [return: bb14, unwind: bb16, drop: bb15]; + _19 = &mut _12; + _16 = Pin::<&mut impl Future>::new_unchecked(move _19) -> [return: bb16, unwind: bb8]; } bb18: { - StorageLive(_17); - _17 = async_drop_in_place::(copy (_18.0: &mut Foo)) -> [return: bb17, unwind: bb16]; + StorageLive(_12); + _12 = async_drop_in_place::(copy (_20.0: &mut Foo)) -> [return: bb17, unwind: bb8]; } bb19: { - _19 = &mut (*_15); - _18 = Pin::<&mut Foo>::new_unchecked(move _19) -> [return: bb18, unwind: bb4]; + _21 = &mut (*_10); + _20 = Pin::<&mut Foo>::new_unchecked(move _21) -> [return: bb18, unwind: bb4]; } bb20: { - _6 = PtrMetadata(copy _5); - _7 = const 0_usize; - goto -> bb13; + _22 = &raw mut (*_5)[_7]; + _7 = Add(move _7, const 1_usize); + goto -> bb41; } bb21: { - goto -> bb20; + _23 = Eq(copy _7, copy _6); + switchInt(move _23) -> [0: bb20, otherwise: bb1]; } bb22: { + StorageDead(_24); + goto -> bb21; + } + + bb23: { + StorageDead(_24); + goto -> bb6; + } + + bb24 (cleanup): { + StorageDead(_24); + goto -> bb4; + } + + bb25: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb25, unwind: bb24]; + } + + bb26: { + _2 = move _25; + StorageDead(_25); + goto -> bb25; + } + + bb27: { + _2 = move _25; + StorageDead(_25); + goto -> bb32; + } + + bb28: { + StorageLive(_25); + _25 = yield(const ()) -> [resume: bb26, drop: bb27]; + } + + bb29: { + _27 = discriminant(_26); + switchInt(move _27) -> [0: bb23, 1: bb28, otherwise: bb13]; + } + + bb30: { + _26 = as Future>::poll(move _28, move _29) -> [return: bb29, unwind: bb24]; + } + + bb31: { + _30 = move _2; + _29 = std::future::get_context::<'_, '_>(move _30) -> [return: bb30, unwind: bb24]; + } + + bb32: { + _31 = &mut _24; + _28 = Pin::<&mut impl Future>::new_unchecked(move _31) -> [return: bb31, unwind: bb24]; + } + + bb33: { + _2 = move _32; + StorageDead(_32); + goto -> bb39; + } + + bb34: { + _2 = move _32; + StorageDead(_32); + goto -> bb32; + } + + bb35: { + StorageLive(_32); + _32 = yield(const ()) -> [resume: bb33, drop: bb34]; + } + + bb36: { + _34 = discriminant(_33); + switchInt(move _34) -> [0: bb22, 1: bb35, otherwise: bb13]; + } + + bb37: { + _33 = as Future>::poll(move _35, move _36) -> [return: bb36, unwind: bb24]; + } + + bb38: { + _37 = move _2; + _36 = std::future::get_context::<'_, '_>(move _37) -> [return: bb37, unwind: bb24]; + } + + bb39: { + _38 = &mut _24; + _35 = Pin::<&mut impl Future>::new_unchecked(move _38) -> [return: bb38, unwind: bb24]; + } + + bb40: { + StorageLive(_24); + _24 = async_drop_in_place::(copy (_39.0: &mut Foo)) -> [return: bb39, unwind: bb24]; + } + + bb41: { + _40 = &mut (*_22); + _39 = Pin::<&mut Foo>::new_unchecked(move _40) -> [return: bb40, unwind: bb4]; + } + + bb42: { + _6 = PtrMetadata(copy _5); + _7 = const 0_usize; + goto -> bb21; + } + + bb43: { + goto -> bb42; + } + + bb44: { _4 = &raw mut (*_3); _5 = move _4 as *mut [Foo] (PointerCoercion(Unsize, Implicit)); - goto -> bb21; + goto -> bb43; } } From a27155e69172af4cddde6b5c5c6cc9d627d6fcc3 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 18:41:05 +0000 Subject: [PATCH 11/12] Remove async_fut. This is now unused. --- compiler/rustc_borrowck/src/lib.rs | 9 +-------- .../src/polonius/legacy/loan_invalidations.rs | 9 +-------- compiler/rustc_codegen_cranelift/src/base.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/block.rs | 4 ++-- .../rustc_const_eval/src/interpret/step.rs | 4 ++-- compiler/rustc_middle/src/mir/pretty.rs | 5 +---- compiler/rustc_middle/src/mir/syntax.rs | 2 -- compiler/rustc_middle/src/mir/terminator.rs | 2 +- compiler/rustc_middle/src/mir/visit.rs | 8 -------- .../src/builder/custom/parse/instruction.rs | 1 - .../src/builder/expr/as_rvalue.rs | 1 - compiler/rustc_mir_build/src/builder/scope.rs | 4 ---- .../src/impls/initialized.rs | 10 ++-------- .../src/add_moves_for_packed_drops.rs | 5 +---- .../rustc_mir_transform/src/coroutine/drop.rs | 4 +--- .../rustc_mir_transform/src/elaborate_drop.rs | 4 ---- .../src/elaborate_drops.rs | 3 +-- compiler/rustc_mir_transform/src/inline.rs | 10 ++-------- .../src/lint_tail_expr_drop_order.rs | 1 - compiler/rustc_mir_transform/src/shim.rs | 3 --- .../src/shim/async_destructor_ctor.rs | 1 - .../src/unstable/convert/stable/mir.rs | 19 +++++++------------ 22 files changed, 24 insertions(+), 89 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index e80969cd0cbb2..ae2f6225c8880 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -881,14 +881,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, TerminatorKind::SwitchInt { discr, targets: _ } => { self.consume_operand(loc, (discr, span), state); } - TerminatorKind::Drop { - place, - target: _, - unwind: _, - replace, - drop: _, - async_fut: _, - } => { + TerminatorKind::Drop { place, target: _, unwind: _, replace, drop: _ } => { debug!( "visit_terminator_drop \ loc: {:?} term: {:?} place: {:?} span: {:?}", diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 5a33b2d5bbe5b..9edf7103f3990 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -97,14 +97,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> { TerminatorKind::SwitchInt { discr, targets: _ } => { self.consume_operand(location, discr); } - TerminatorKind::Drop { - place: drop_place, - target: _, - unwind: _, - replace, - drop: _, - async_fut: _, - } => { + TerminatorKind::Drop { place: drop_place, target: _, unwind: _, replace, drop: _ } => { let write_kind = if *replace { WriteKind::Replace } else { WriteKind::StorageDeadOrDrop }; self.access_place( diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 1d90c8e0dadcf..2edbdb560f52b 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -582,9 +582,9 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { | TerminatorKind::CoroutineDrop => { bug!("shouldn't exist at codegen {:?}", bb_data.terminator()); } - TerminatorKind::Drop { place, target, unwind, replace: _, drop, async_fut } => { + TerminatorKind::Drop { place, target, unwind, replace: _, drop } => { assert!( - async_fut.is_none() && drop.is_none(), + drop.is_none(), "Async Drop must be expanded or reset to sync before codegen" ); let drop_place = codegen_place(fx, *place); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index b6b95c5f12aae..0b75339789da2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1585,9 +1585,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { MergingSucc::False } - mir::TerminatorKind::Drop { place, target, unwind, replace: _, drop, async_fut } => { + mir::TerminatorKind::Drop { place, target, unwind, replace: _, drop } => { assert!( - async_fut.is_none() && drop.is_none(), + drop.is_none(), "Async Drop must be expanded or reset to sync before codegen" ); self.codegen_drop_terminator( diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 0718638c1d219..b1e3fd735399d 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -596,9 +596,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - Drop { place, target, unwind, replace: _, drop, async_fut } => { + Drop { place, target, unwind, replace: _, drop } => { assert!( - async_fut.is_none() && drop.is_none(), + drop.is_none(), "Async Drop must be expanded or reset to sync in runtime MIR" ); let place = self.eval_place(place)?; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 7bae4768bf46a..f93c4b0d24f80 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -991,10 +991,7 @@ impl<'tcx> TerminatorKind<'tcx> { } Yield { value, resume_arg, .. } => write!(fmt, "{resume_arg:?} = yield({value:?})"), Unreachable => write!(fmt, "unreachable"), - Drop { place, async_fut: None, .. } => write!(fmt, "drop({place:?})"), - Drop { place, async_fut: Some(async_fut), .. } => { - write!(fmt, "async drop({place:?}; poll={async_fut:?})") - } + Drop { place, .. } => write!(fmt, "drop({place:?})"), Call { func, args, destination, .. } => { write!(fmt, "{destination:?} = ")?; write!(fmt, "{func:?}(")?; diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 1f5a8f1c2cdc6..91ff3f52390e1 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -778,8 +778,6 @@ pub enum TerminatorKind<'tcx> { replace: bool, /// Cleanup to be done if the coroutine is dropped at this suspend point (for async drop). drop: Option, - /// Prepared async future local (for async drop) - async_fut: Option, }, /// Roughly speaking, evaluates the `func` operand and the arguments, and starts execution of diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 503fd8a3d6b60..741ba8ad53f8a 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -743,7 +743,7 @@ impl<'tcx> TerminatorKind<'tcx> { // FIXME: Maybe we need also TerminatorEdges::Trio for async drop // (target + unwind + dropline) Assert { target, unwind, expected: _, msg: _, cond: _ } - | Drop { target, unwind, place: _, replace: _, drop: _, async_fut: _ } + | Drop { target, unwind, place: _, replace: _, drop: _ } | FalseUnwind { real_target: target, unwind } => match unwind { UnwindAction::Cleanup(unwind) => TerminatorEdges::Double(target, unwind), UnwindAction::Continue | UnwindAction::Terminate(_) | UnwindAction::Unreachable => { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index e6e911dece742..fbe22ecc06e47 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -555,20 +555,12 @@ macro_rules! make_mir_visitor { unwind: _, replace: _, drop: _, - async_fut, } => { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Drop), location ); - if let Some(async_fut) = async_fut { - self.visit_local( - $(&$mutability)? *async_fut, - PlaceContext::MutatingUse(MutatingUseContext::Borrow), - location - ); - } } TerminatorKind::Call { diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index 5d9a2382ba419..84203c5caefea 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -63,7 +63,6 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { unwind: self.parse_unwind_action(args[2])?, replace: false, drop: None, - async_fut: None, }) }, @call(mir_call, args) => { diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index ce443d66dc619..dd36411658305 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -642,7 +642,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unwind: UnwindAction::Continue, replace: false, drop: None, - async_fut: None, }, ); this.diverge_from(block); diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 3343bec30caf5..3f80d7872a407 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -427,7 +427,6 @@ impl DropTree { place: drop_node.data.local.into(), replace: false, drop: None, - async_fut: None, }; cfg.terminate(block, drop_node.data.source_info, terminator); } @@ -1170,7 +1169,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unwind: UnwindAction::Continue, replace: false, drop: None, - async_fut: None, }, ); block = next; @@ -1745,7 +1743,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unwind: UnwindAction::Cleanup(assign_unwind), replace: true, drop: None, - async_fut: None, }, ); self.diverge_from(block); @@ -1916,7 +1913,6 @@ where unwind: UnwindAction::Continue, replace: false, drop: None, - async_fut: None, }, ); block = next; diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index e045b0e950779..b4cbe7d1da14c 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -412,14 +412,8 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { // the result of `is_unwind_dead`. let mut edges = terminator.edges(); if self.skip_unreachable_unwind - && let mir::TerminatorKind::Drop { - target, - unwind, - place, - replace: _, - drop: _, - async_fut: _, - } = terminator.kind + && let mir::TerminatorKind::Drop { target, unwind, place, replace: _, drop: _ } = + terminator.kind && matches!(unwind, mir::UnwindAction::Cleanup(_)) && self.is_unwind_dead(place, state) { diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index 46d5773102583..f47751ea83223 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -83,9 +83,7 @@ fn add_move_for_packed_drop<'tcx>( is_cleanup: bool, ) { debug!("add_move_for_packed_drop({:?} @ {:?})", terminator, loc); - let TerminatorKind::Drop { ref place, target, unwind, replace, drop, async_fut } = - terminator.kind - else { + let TerminatorKind::Drop { ref place, target, unwind, replace, drop } = terminator.kind else { unreachable!(); }; @@ -109,7 +107,6 @@ fn add_move_for_packed_drop<'tcx>( unwind, replace, drop, - async_fut, }, ); } diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 5a22d139a34a0..71da5f50a1274 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -87,7 +87,7 @@ pub(super) fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body let (target, unwind, source_info, dropline) = match block_data.terminator() { Terminator { source_info, - kind: TerminatorKind::Drop { place, target, unwind, replace: _, drop, async_fut: _ }, + kind: TerminatorKind::Drop { place, target, unwind, replace: _, drop }, } => { if let Some(local) = place.as_local() && local == SELF_ARG @@ -146,7 +146,6 @@ pub(super) fn insert_clean_drop<'tcx>( unwind: UnwindAction::Continue, replace: false, drop: dropline, - async_fut: None, }; // Create a block to destroy an unresumed coroutines. This can only destroy upvars. @@ -349,7 +348,6 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( unwind: UnwindAction::Continue, replace: false, drop: None, - async_fut: None, }; body.basic_blocks_mut()[call_bb].terminator = Some(Terminator { source_info, kind }); diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 89e15049ed9db..f9ba86c06c5e1 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -662,7 +662,6 @@ where unwind: self.unwind.into_action(), replace: false, drop: None, - async_fut: None, }, ); } @@ -1329,7 +1328,6 @@ where unwind: unwind.into_action(), replace: false, drop: None, - async_fut: None, }, ); } @@ -1565,7 +1563,6 @@ where unwind: self.unwind.into_action(), replace: false, drop: self.dropline, - async_fut: None, }, ); self.elaborate_drop(blk); @@ -1585,7 +1582,6 @@ where unwind: unwind.into_action(), replace: false, drop: None, - async_fut: None, }, ) } diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 11fd15190e7c8..01235b1824218 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -332,8 +332,7 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { // This function should mirror what `collect_drop_flags` does. for (bb, data) in self.body.basic_blocks.iter_enumerated() { let terminator = data.terminator(); - let TerminatorKind::Drop { place, target, unwind, replace, drop, async_fut: _ } = - terminator.kind + let TerminatorKind::Drop { place, target, unwind, replace, drop } = terminator.kind else { continue; }; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 434f96996eeaf..f234166be24a6 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -413,14 +413,8 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> { let term = blk.terminator(); let caller_attrs = tcx.codegen_fn_attrs(self.caller_def_id()); - if let TerminatorKind::Drop { - ref place, - target, - unwind, - replace: _, - drop: _, - async_fut: _, - } = term.kind + if let TerminatorKind::Drop { ref place, target, unwind, replace: _, drop: _ } = + term.kind { work_list.push(target); diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index c354279b8ed32..0bc5704a8625d 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -137,7 +137,6 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> { unwind: _, replace: _, drop: _, - async_fut: _, } = &terminator.kind && place_has_common_prefix(dropped_place, self.place) { diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 8efe536497ef5..c5ef70558c88c 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -689,7 +689,6 @@ impl<'tcx> CloneShimBuilder<'tcx> { unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup), replace: false, drop: None, - async_fut: None, }, /* is_cleanup */ true, ); @@ -956,7 +955,6 @@ fn build_call_shim<'tcx>( unwind: UnwindAction::Continue, replace: false, drop: None, - async_fut: None, }, false, ); @@ -975,7 +973,6 @@ fn build_call_shim<'tcx>( unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup), replace: false, drop: None, - async_fut: None, }, /* is_cleanup */ true, ); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 02f748c21e083..e9c317ecdec21 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -96,7 +96,6 @@ pub(super) fn build_async_drop_shim<'tcx>( unwind: UnwindAction::Continue, replace: false, drop: None, - async_fut: None, } } else { TerminatorKind::Goto { target: return_block } diff --git a/compiler/rustc_public/src/unstable/convert/stable/mir.rs b/compiler/rustc_public/src/unstable/convert/stable/mir.rs index 7e76d5a91ac66..d126304af8cde 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/mir.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/mir.rs @@ -726,18 +726,13 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort, mir::TerminatorKind::Return => TerminatorKind::Return, mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable, - mir::TerminatorKind::Drop { - place, - target, - unwind, - replace: _, - drop: _, - async_fut: _, - } => TerminatorKind::Drop { - place: place.stable(tables, cx), - target: target.as_usize(), - unwind: unwind.stable(tables, cx), - }, + mir::TerminatorKind::Drop { place, target, unwind, replace: _, drop: _ } => { + TerminatorKind::Drop { + place: place.stable(tables, cx), + target: target.as_usize(), + unwind: unwind.stable(tables, cx), + } + } mir::TerminatorKind::Call { func, args, From d0e0ceabcfca2f044c8ddcb1f56afb48505aa7f5 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 31 May 2026 16:02:07 +0000 Subject: [PATCH 12/12] Move outdated comment. --- compiler/rustc_mir_transform/src/coroutine.rs | 4 ---- compiler/rustc_mir_transform/src/coroutine/drop.rs | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 356e7a2d43f27..9047055bc2570 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1600,10 +1600,6 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { body.coroutine.as_mut().unwrap().resume_ty = None; body.coroutine.as_mut().unwrap().coroutine_layout = Some(layout); - // FIXME: Drops, produced by insert_clean_drop + elaborate_coroutine_drops, - // are currently sync only. To allow async for them, we need to move those calls - // before expand_async_drops, and fix the related problems. - // // Insert `drop(coroutine_struct)` which is used to drop upvars for coroutines in // the unresumed state. // This is expanded to a drop ladder in `elaborate_coroutine_drops`. diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 71da5f50a1274..dc58bc14d0c9b 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -80,6 +80,9 @@ pub(super) fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body patch: MirPatch::new(body), tcx, typing_env, + // FIXME(async_drop): Drops, produced by insert_clean_drop + elaborate_coroutine_drops, are + // currently sync only. To allow async for them, flip this flag and fix the related + // problems. produce_async_drops: false, };