From a057dd1c865e32c1df817628d428f985ef197d42 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 14:29:19 +0000 Subject: [PATCH 01/16] Make a dedicated coroutine mir-opt test directory. --- tests/mir-opt/building/async_await.rs | 18 --- ...await.a-{closure#0}.coroutine_resume.0.mir | 2 +- ...await.b-{closure#0}.coroutine_resume.0.mir | 134 +++++++++++++++--- tests/mir-opt/coroutine/async_await.rs | 29 ++++ ...oo-{closure#0}-{closure#0}.built.after.mir | 0 ...-{closure#0}-{synthetic#0}.built.after.mir | 0 .../async_closure_fake_read_for_by_move.rs | 0 ...0}-{closure#0}-{closure#0}.built.after.mir | 0 ...-{closure#0}-{synthetic#0}.built.after.mir | 0 ...closure#0}.coroutine_closure_by_move.0.mir | 0 ...0}-{closure#1}-{closure#0}.built.after.mir | 0 ...-{closure#1}-{synthetic#0}.built.after.mir | 0 ...closure#1}.coroutine_closure_by_move.0.mir | 0 ...{closure#1}.coroutine_closure_by_ref.0.mir | 0 .../{ => coroutine}/async_closure_shims.rs | 0 ...#0}.coroutine_drop_async.0.panic-abort.mir | 0 ...0}.coroutine_drop_async.0.panic-unwind.mir | 0 .../{ => coroutine}/async_drop_live_dead.rs | 0 ...losure#0}.[Foo;1].MentionedItems.after.mir | 0 .../{ => coroutine}/async_drop_mir_pin.rs | 0 ....main-{closure#0}.StateTransform.after.mir | 119 +++++++++++++--- ....main-{closure#1}.StateTransform.after.mir | 119 +++++++++++++--- .../{building => coroutine}/coroutine.rs | 3 +- ...losure#0}.coroutine_drop.0.panic-abort.mir | 0 ...osure#0}.coroutine_drop.0.panic-unwind.mir | 0 .../{ => coroutine}/coroutine_drop_cleanup.rs | 0 ...e#0}.StateTransform.before.panic-abort.mir | 0 ...#0}.StateTransform.before.panic-unwind.mir | 0 .../coroutine_storage_dead_unwind.rs | 0 ...ny.main-{closure#0}.coroutine_resume.0.mir | 0 .../mir-opt/{ => coroutine}/coroutine_tiny.rs | 0 .../{ => inline}/inline_coroutine_body.rs | 0 ...y.run2-{closure#0}.Inline.panic-abort.diff | 0 ....run2-{closure#0}.Inline.panic-unwind.diff | 0 34 files changed, 347 insertions(+), 77 deletions(-) delete mode 100644 tests/mir-opt/building/async_await.rs rename tests/mir-opt/{building => coroutine}/async_await.a-{closure#0}.coroutine_resume.0.mir (96%) rename tests/mir-opt/{building => coroutine}/async_await.b-{closure#0}.coroutine_resume.0.mir (75%) create mode 100644 tests/mir-opt/coroutine/async_await.rs rename tests/mir-opt/{ => coroutine}/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_fake_read_for_by_move.rs (100%) rename tests/mir-opt/{ => coroutine}/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir (100%) rename tests/mir-opt/{ => coroutine}/async_closure_shims.rs (100%) rename tests/mir-opt/{ => coroutine}/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir (100%) rename tests/mir-opt/{ => coroutine}/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir (100%) rename tests/mir-opt/{ => coroutine}/async_drop_live_dead.rs (100%) rename tests/mir-opt/{ => coroutine}/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir (100%) rename tests/mir-opt/{ => coroutine}/async_drop_mir_pin.rs (100%) rename tests/mir-opt/{building => coroutine}/coroutine.main-{closure#0}.StateTransform.after.mir (64%) rename tests/mir-opt/{building => coroutine}/coroutine.main-{closure#1}.StateTransform.after.mir (64%) rename tests/mir-opt/{building => coroutine}/coroutine.rs (93%) rename tests/mir-opt/{ => coroutine}/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir (100%) rename tests/mir-opt/{ => coroutine}/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir (100%) rename tests/mir-opt/{ => coroutine}/coroutine_drop_cleanup.rs (100%) rename tests/mir-opt/{ => coroutine}/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir (100%) rename tests/mir-opt/{ => coroutine}/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir (100%) rename tests/mir-opt/{ => coroutine}/coroutine_storage_dead_unwind.rs (100%) rename tests/mir-opt/{ => coroutine}/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir (100%) rename tests/mir-opt/{ => coroutine}/coroutine_tiny.rs (100%) rename tests/mir-opt/{ => inline}/inline_coroutine_body.rs (100%) rename tests/mir-opt/{ => inline}/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff (100%) rename tests/mir-opt/{ => inline}/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff (100%) diff --git a/tests/mir-opt/building/async_await.rs b/tests/mir-opt/building/async_await.rs deleted file mode 100644 index e84f8a6c561bc..0000000000000 --- a/tests/mir-opt/building/async_await.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ skip-filecheck -// This test makes sure that the coroutine MIR pass eliminates all calls to -// `get_context`, and that the MIR argument type for an async fn and all locals -// related to `yield` are `&mut Context`, and its return type is `Poll`. - -//@ edition:2018 -//@ compile-flags: -Zmir-opt-level=0 -C panic=abort - -#![crate_type = "lib"] - -// EMIT_MIR async_await.a-{closure#0}.coroutine_resume.0.mir -async fn a() {} - -// EMIT_MIR async_await.b-{closure#0}.coroutine_resume.0.mir -pub async fn b() { - a().await; - a().await -} diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir similarity index 96% rename from tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir rename to tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir index 6cad5b105d3e3..f59cdb5c27bc0 100644 --- a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir @@ -38,7 +38,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> } bb4: { - assert(const false, "`async fn` resumed after completion") -> [success: bb4, unwind unreachable]; + assert(const false, "`async fn` resumed after completion") -> [success: bb4, unwind continue]; } bb5: { diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir similarity index 75% rename from tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir rename to tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir index 96ee37185db16..0c130634aeac4 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -13,7 +13,7 @@ ], ), source_info: SourceInfo { - span: $DIR/async_await.rs:16:5: 16:14 (#9), + span: $DIR/async_await.rs:27:5: 27:14 (#9), scope: scope[0], }, ignore_for_traits: false, @@ -30,7 +30,7 @@ ], ), source_info: SourceInfo { - span: $DIR/async_await.rs:17:5: 17:14 (#11), + span: $DIR/async_await.rs:28:5: 28:14 (#11), scope: scope[0], }, ignore_for_traits: false, @@ -105,18 +105,18 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb0: { _39 = copy (_1.0: &mut {async fn body of b()}); _38 = discriminant((*_39)); - switchInt(move _38) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8]; + switchInt(move _38) -> [0: bb1, 1: bb47, 2: bb46, 3: bb44, 4: bb45, otherwise: bb8]; } bb1: { StorageLive(_3); StorageLive(_4); StorageLive(_5); - _5 = a() -> [return: bb2, unwind unreachable]; + _5 = a() -> [return: bb2, unwind: bb38]; } bb2: { - _4 = <{async fn body of a()} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable]; + _4 = <{async fn body of a()} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind: bb37]; } bb3: { @@ -135,7 +135,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageLive(_12); _12 = &mut (((*_39) as variant#3).0: {async fn body of a()}); _11 = &mut (*_12); - _10 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable]; + _10 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _11) -> [return: bb5, unwind: bb34]; } bb5: { @@ -151,7 +151,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb6: { _13 = &mut (*_14); StorageDead(_15); - _9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable]; + _9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb7, unwind: bb33]; } bb7: { @@ -193,7 +193,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageDead(_12); StorageDead(_9); StorageDead(_8); - drop((((*_39) as variant#3).0: {async fn body of a()})) -> [return: bb12, unwind unreachable]; + drop((((*_39) as variant#3).0: {async fn body of a()})) -> [return: bb12, unwind: bb36]; } bb11: { @@ -214,11 +214,11 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageDead(_3); StorageLive(_21); StorageLive(_22); - _22 = a() -> [return: bb14, unwind unreachable]; + _22 = a() -> [return: bb14, unwind: bb31]; } bb14: { - _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; + _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind: bb30]; } bb15: { @@ -237,7 +237,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageLive(_28); _28 = &mut (((*_39) as variant#4).0: {async fn body of a()}); _27 = &mut (*_28); - _26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable]; + _26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb17, unwind: bb27]; } bb17: { @@ -253,7 +253,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb18: { _29 = &mut (*_30); StorageDead(_31); - _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; + _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb19, unwind: bb26]; } bb19: { @@ -290,7 +290,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageDead(_28); StorageDead(_25); StorageDead(_24); - drop((((*_39) as variant#4).0: {async fn body of a()})) -> [return: bb23, unwind unreachable]; + drop((((*_39) as variant#4).0: {async fn body of a()})) -> [return: bb23, unwind: bb29]; } bb22: { @@ -308,7 +308,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb24: { StorageDead(_21); - goto -> bb26; + goto -> bb42; } bb25: { @@ -317,11 +317,103 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> return; } - bb26: { + bb26 (cleanup): { + StorageDead(_29); + StorageDead(_26); + StorageDead(_30); + goto -> bb28; + } + + bb27 (cleanup): { + StorageDead(_27); + StorageDead(_26); + goto -> bb28; + } + + bb28 (cleanup): { + StorageDead(_28); + StorageDead(_25); + StorageDead(_24); + drop((((*_39) as variant#4).0: {async fn body of a()})) -> [return: bb29, unwind terminate(cleanup)]; + } + + bb29 (cleanup): { + nop; + goto -> bb32; + } + + bb30 (cleanup): { + goto -> bb31; + } + + bb31 (cleanup): { + StorageDead(_22); + goto -> bb32; + } + + bb32 (cleanup): { + StorageDead(_21); + goto -> bb40; + } + + bb33 (cleanup): { + StorageDead(_13); + StorageDead(_10); + StorageDead(_14); + goto -> bb35; + } + + bb34 (cleanup): { + StorageDead(_11); + StorageDead(_10); + goto -> bb35; + } + + bb35 (cleanup): { + StorageDead(_12); + StorageDead(_9); + StorageDead(_8); + drop((((*_39) as variant#3).0: {async fn body of a()})) -> [return: bb36, unwind terminate(cleanup)]; + } + + bb36 (cleanup): { + nop; + goto -> bb39; + } + + bb37 (cleanup): { + goto -> bb38; + } + + bb38 (cleanup): { + StorageDead(_5); + goto -> bb39; + } + + bb39 (cleanup): { + StorageDead(_4); + StorageDead(_3); + goto -> bb40; + } + + bb40 (cleanup): { + goto -> bb41; + } + + bb41 (cleanup): { + goto -> bb43; + } + + bb42: { goto -> bb25; } - bb27: { + bb43 (cleanup): { + discriminant((*_39)) = 2; + resume; + } + + bb44: { StorageLive(_3); StorageLive(_4); StorageLive(_19); @@ -330,7 +422,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> goto -> bb11; } - bb28: { + bb45: { StorageLive(_21); StorageLive(_35); StorageLive(_36); @@ -338,7 +430,11 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> goto -> bb22; } - bb29: { - assert(const false, "`async fn` resumed after completion") -> [success: bb29, unwind unreachable]; + bb46: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb46, unwind continue]; + } + + bb47: { + assert(const false, "`async fn` resumed after completion") -> [success: bb47, unwind continue]; } } diff --git a/tests/mir-opt/coroutine/async_await.rs b/tests/mir-opt/coroutine/async_await.rs new file mode 100644 index 0000000000000..8334baa594720 --- /dev/null +++ b/tests/mir-opt/coroutine/async_await.rs @@ -0,0 +1,29 @@ +// This test makes sure that the coroutine MIR pass eliminates all calls to +// `get_context`, and that the MIR argument type for an async fn and all locals +// related to `yield` are `&mut Context`, and its return type is `Poll`. + +//@ edition:2018 +//@ compile-flags: -Zmir-opt-level=0 +//@ needs-unwind + +#![crate_type = "lib"] + +// EMIT_MIR async_await.a-{closure#0}.coroutine_resume.0.mir +async fn a() { + // CHECK-LABEL: fn a::{closure#0}( + // CHECK-SAME: _1: Pin<&mut {async fn body of a()}> + // CHECK-SAME: _2: &mut Context<'_> + // CHECK-SAME: -> Poll<()> + // CHECK-NOT: get_context +} + +// EMIT_MIR async_await.b-{closure#0}.coroutine_resume.0.mir +pub async fn b() { + // CHECK-LABEL: fn b::{closure#0}( + // CHECK-SAME: _1: Pin<&mut {async fn body of b()}> + // CHECK-SAME: _2: &mut Context<'_> + // CHECK-SAME: -> Poll<()> + // CHECK-NOT: get_context + a().await; + a().await +} diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/coroutine/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir similarity index 100% rename from tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir rename to tests/mir-opt/coroutine/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/coroutine/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir similarity index 100% rename from tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir rename to tests/mir-opt/coroutine/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.rs b/tests/mir-opt/coroutine/async_closure_fake_read_for_by_move.rs similarity index 100% rename from tests/mir-opt/async_closure_fake_read_for_by_move.rs rename to tests/mir-opt/coroutine/async_closure_fake_read_for_by_move.rs diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir similarity index 100% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir rename to tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir similarity index 100% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir rename to tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir b/tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir similarity index 100% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir rename to tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir b/tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir similarity index 100% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir rename to tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir b/tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir similarity index 100% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir rename to tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir b/tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir similarity index 100% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir rename to tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir b/tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir similarity index 100% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir rename to tests/mir-opt/coroutine/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/coroutine/async_closure_shims.rs similarity index 100% rename from tests/mir-opt/async_closure_shims.rs rename to tests/mir-opt/coroutine/async_closure_shims.rs diff --git a/tests/mir-opt/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 similarity index 100% rename from tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir rename to tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir diff --git a/tests/mir-opt/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 similarity index 100% rename from tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir rename to tests/mir-opt/coroutine/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir diff --git a/tests/mir-opt/async_drop_live_dead.rs b/tests/mir-opt/coroutine/async_drop_live_dead.rs similarity index 100% rename from tests/mir-opt/async_drop_live_dead.rs rename to tests/mir-opt/coroutine/async_drop_live_dead.rs diff --git a/tests/mir-opt/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 similarity index 100% rename from tests/mir-opt/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir rename to tests/mir-opt/coroutine/async_drop_mir_pin.core.future-async_drop-async_drop_in_place-{closure#0}.[Foo;1].MentionedItems.after.mir diff --git a/tests/mir-opt/async_drop_mir_pin.rs b/tests/mir-opt/coroutine/async_drop_mir_pin.rs similarity index 100% rename from tests/mir-opt/async_drop_mir_pin.rs rename to tests/mir-opt/coroutine/async_drop_mir_pin.rs diff --git a/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir similarity index 64% rename from tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir rename to tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir index b61215dc28cb4..7adceef744a2a 100644 --- a/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir +++ b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir @@ -4,7 +4,7 @@ _s0: CoroutineSavedTy { ty: std::string::String, source_info: SourceInfo { - span: $DIR/coroutine.rs:18:6: 18:9 (#0), + span: $DIR/coroutine.rs:19:6: 19:9 (#0), scope: scope[0], }, ignore_for_traits: false, @@ -22,7 +22,7 @@ }, } */ -fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { +fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { debug arg => (((*_18) as variant#4).0: std::string::String); let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; let _3: std::string::String; @@ -40,12 +40,12 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 let _15: &std::panic::Location<'_>; let mut _16: (); let mut _17: u32; - let mut _18: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + let mut _18: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}; bb0: { - _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}); _17 = discriminant((*_18)); - switchInt(move _17) -> [0: bb1, 1: bb19, 3: bb17, 4: bb18, otherwise: bb20]; + switchInt(move _17) -> [0: bb1, 1: bb35, 2: bb34, 3: bb32, 4: bb33, otherwise: bb36]; } bb1: { @@ -55,13 +55,13 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 StorageLive(_5); StorageLive(_6); _6 = &(((*_18) as variant#4).0: std::string::String); - _5 = ::clone(move _6) -> [return: bb2, unwind unreachable]; + _5 = ::clone(move _6) -> [return: bb2, unwind: bb23]; } bb2: { StorageDead(_6); StorageLive(_7); - _7 = Location::<'_>::caller() -> [return: bb3, unwind unreachable]; + _7 = Location::<'_>::caller() -> [return: bb3, unwind: bb22]; } bb3: { @@ -85,7 +85,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 bb6: { StorageDead(_4); - drop(_3) -> [return: bb7, unwind unreachable]; + drop(_3) -> [return: bb7, unwind: bb26]; } bb7: { @@ -99,14 +99,14 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 StorageLive(_12); StorageLive(_13); _13 = &(((*_18) as variant#4).0: std::string::String); - _12 = ::clone(move _13) -> [return: bb8, unwind unreachable]; + _12 = ::clone(move _13) -> [return: bb8, unwind: bb20]; } bb8: { StorageDead(_13); StorageLive(_14); StorageLive(_15); - _15 = Location::<'_>::caller() -> [return: bb9, unwind unreachable]; + _15 = Location::<'_>::caller() -> [return: bb9, unwind: bb16]; } bb9: { @@ -134,7 +134,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 bb12: { StorageDead(_9); - drop(_8) -> [return: bb13, unwind unreachable]; + drop(_8) -> [return: bb13, unwind: bb19]; } bb13: { @@ -142,11 +142,11 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 StorageDead(_11); StorageDead(_8); _16 = const (); - drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable]; + drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb14, unwind: bb28]; } bb14: { - goto -> bb16; + goto -> bb30; } bb15: { @@ -155,18 +155,95 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 return; } - bb16: { + bb16 (cleanup): { + StorageDead(_14); + drop(_12) -> [return: bb17, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { + StorageDead(_12); + StorageDead(_10); + goto -> bb18; + } + + bb18 (cleanup): { + StorageDead(_9); + goto -> bb19; + } + + bb19 (cleanup): { + StorageDead(_15); + goto -> bb21; + } + + bb20 (cleanup): { + StorageDead(_13); + StorageDead(_12); + StorageDead(_10); + StorageDead(_9); + goto -> bb21; + } + + bb21 (cleanup): { + StorageDead(_11); + StorageDead(_8); + goto -> bb27; + } + + bb22 (cleanup): { + StorageDead(_7); + drop(_5) -> [return: bb24, unwind terminate(cleanup)]; + } + + bb23 (cleanup): { + StorageDead(_6); + goto -> bb24; + } + + bb24 (cleanup): { + StorageDead(_5); + goto -> bb25; + } + + bb25 (cleanup): { + StorageDead(_4); + goto -> bb26; + } + + bb26 (cleanup): { + StorageDead(_3); + goto -> bb27; + } + + bb27 (cleanup): { + drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb28, unwind terminate(cleanup)]; + } + + bb28 (cleanup): { + goto -> bb29; + } + + bb29 (cleanup): { + goto -> bb31; + } + + bb30: { goto -> bb15; } - bb17: { + bb31 (cleanup): { + discriminant((*_18)) = 2; + resume; + } + + bb32: { StorageLive(_3); StorageLive(_4); _3 = move _2; goto -> bb5; } - bb18: { + bb33: { StorageLive(_8); StorageLive(_9); StorageLive(_11); @@ -175,11 +252,15 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 goto -> bb11; } - bb19: { - assert(const false, "coroutine resumed after completion") -> [success: bb19, unwind unreachable]; + bb34: { + assert(const false, "coroutine resumed after panicking") -> [success: bb34, unwind continue]; + } + + bb35: { + assert(const false, "coroutine resumed after completion") -> [success: bb35, unwind continue]; } - bb20: { + bb36: { unreachable; } } diff --git a/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir similarity index 64% rename from tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir rename to tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir index aac028a9e6c0e..b4fcd2051303e 100644 --- a/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir +++ b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir @@ -4,7 +4,7 @@ _s0: CoroutineSavedTy { ty: std::string::String, source_info: SourceInfo { - span: $DIR/coroutine.rs:25:6: 25:9 (#0), + span: $DIR/coroutine.rs:26:6: 26:9 (#0), scope: scope[0], }, ignore_for_traits: false, @@ -22,7 +22,7 @@ }, } */ -fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { +fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { debug arg => (((*_18) as variant#4).0: std::string::String); let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; let _3: std::string::String; @@ -40,12 +40,12 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 let _15: &std::panic::Location<'_>; let mut _16: (); let mut _17: u32; - let mut _18: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + let mut _18: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}; bb0: { - _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}); _17 = discriminant((*_18)); - switchInt(move _17) -> [0: bb1, 1: bb19, 3: bb17, 4: bb18, otherwise: bb20]; + switchInt(move _17) -> [0: bb1, 1: bb35, 2: bb34, 3: bb32, 4: bb33, otherwise: bb36]; } bb1: { @@ -55,13 +55,13 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 StorageLive(_5); StorageLive(_6); _6 = &(((*_18) as variant#4).0: std::string::String); - _5 = ::clone(move _6) -> [return: bb2, unwind unreachable]; + _5 = ::clone(move _6) -> [return: bb2, unwind: bb23]; } bb2: { StorageDead(_6); StorageLive(_7); - _7 = Location::<'_>::caller() -> [return: bb3, unwind unreachable]; + _7 = Location::<'_>::caller() -> [return: bb3, unwind: bb22]; } bb3: { @@ -85,7 +85,7 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 bb6: { StorageDead(_4); - drop(_3) -> [return: bb7, unwind unreachable]; + drop(_3) -> [return: bb7, unwind: bb26]; } bb7: { @@ -99,14 +99,14 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 StorageLive(_12); StorageLive(_13); _13 = &(((*_18) as variant#4).0: std::string::String); - _12 = ::clone(move _13) -> [return: bb8, unwind unreachable]; + _12 = ::clone(move _13) -> [return: bb8, unwind: bb20]; } bb8: { StorageDead(_13); StorageLive(_14); StorageLive(_15); - _15 = Location::<'_>::caller() -> [return: bb9, unwind unreachable]; + _15 = Location::<'_>::caller() -> [return: bb9, unwind: bb16]; } bb9: { @@ -134,7 +134,7 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 bb12: { StorageDead(_9); - drop(_8) -> [return: bb13, unwind unreachable]; + drop(_8) -> [return: bb13, unwind: bb19]; } bb13: { @@ -142,11 +142,11 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 StorageDead(_11); StorageDead(_8); _16 = const (); - drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable]; + drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb14, unwind: bb28]; } bb14: { - goto -> bb16; + goto -> bb30; } bb15: { @@ -155,18 +155,95 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 return; } - bb16: { + bb16 (cleanup): { + StorageDead(_14); + drop(_12) -> [return: bb17, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { + StorageDead(_12); + StorageDead(_10); + goto -> bb18; + } + + bb18 (cleanup): { + StorageDead(_9); + goto -> bb19; + } + + bb19 (cleanup): { + StorageDead(_15); + goto -> bb21; + } + + bb20 (cleanup): { + StorageDead(_13); + StorageDead(_12); + StorageDead(_10); + StorageDead(_9); + goto -> bb21; + } + + bb21 (cleanup): { + StorageDead(_11); + StorageDead(_8); + goto -> bb27; + } + + bb22 (cleanup): { + StorageDead(_7); + drop(_5) -> [return: bb24, unwind terminate(cleanup)]; + } + + bb23 (cleanup): { + StorageDead(_6); + goto -> bb24; + } + + bb24 (cleanup): { + StorageDead(_5); + goto -> bb25; + } + + bb25 (cleanup): { + StorageDead(_4); + goto -> bb26; + } + + bb26 (cleanup): { + StorageDead(_3); + goto -> bb27; + } + + bb27 (cleanup): { + drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb28, unwind terminate(cleanup)]; + } + + bb28 (cleanup): { + goto -> bb29; + } + + bb29 (cleanup): { + goto -> bb31; + } + + bb30: { goto -> bb15; } - bb17: { + bb31 (cleanup): { + discriminant((*_18)) = 2; + resume; + } + + bb32: { StorageLive(_3); StorageLive(_4); _3 = move _2; goto -> bb5; } - bb18: { + bb33: { StorageLive(_8); StorageLive(_9); StorageLive(_11); @@ -175,11 +252,15 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 goto -> bb11; } - bb19: { - assert(const false, "coroutine resumed after completion") -> [success: bb19, unwind unreachable]; + bb34: { + assert(const false, "coroutine resumed after panicking") -> [success: bb34, unwind continue]; + } + + bb35: { + assert(const false, "coroutine resumed after completion") -> [success: bb35, unwind continue]; } - bb20: { + bb36: { unreachable; } } diff --git a/tests/mir-opt/building/coroutine.rs b/tests/mir-opt/coroutine/coroutine.rs similarity index 93% rename from tests/mir-opt/building/coroutine.rs rename to tests/mir-opt/coroutine/coroutine.rs index 77388c8786aaa..41fdbee119e14 100644 --- a/tests/mir-opt/building/coroutine.rs +++ b/tests/mir-opt/coroutine/coroutine.rs @@ -1,6 +1,7 @@ //@ skip-filecheck //@ edition:2024 -//@ compile-flags: -Zmir-opt-level=0 -C panic=abort +//@ compile-flags: -Zmir-opt-level=0 +//@ needs-unwind #![feature(stmt_expr_attributes)] #![feature(closure_track_caller)] diff --git a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir b/tests/mir-opt/coroutine/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir similarity index 100% rename from tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir rename to tests/mir-opt/coroutine/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir diff --git a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir b/tests/mir-opt/coroutine/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir similarity index 100% rename from tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir rename to tests/mir-opt/coroutine/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir diff --git a/tests/mir-opt/coroutine_drop_cleanup.rs b/tests/mir-opt/coroutine/coroutine_drop_cleanup.rs similarity index 100% rename from tests/mir-opt/coroutine_drop_cleanup.rs rename to tests/mir-opt/coroutine/coroutine_drop_cleanup.rs diff --git a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir similarity index 100% rename from tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir rename to tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir diff --git a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir similarity index 100% rename from tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir rename to tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir diff --git a/tests/mir-opt/coroutine_storage_dead_unwind.rs b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.rs similarity index 100% rename from tests/mir-opt/coroutine_storage_dead_unwind.rs rename to tests/mir-opt/coroutine/coroutine_storage_dead_unwind.rs diff --git a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir similarity index 100% rename from tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir rename to tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir diff --git a/tests/mir-opt/coroutine_tiny.rs b/tests/mir-opt/coroutine/coroutine_tiny.rs similarity index 100% rename from tests/mir-opt/coroutine_tiny.rs rename to tests/mir-opt/coroutine/coroutine_tiny.rs diff --git a/tests/mir-opt/inline_coroutine_body.rs b/tests/mir-opt/inline/inline_coroutine_body.rs similarity index 100% rename from tests/mir-opt/inline_coroutine_body.rs rename to tests/mir-opt/inline/inline_coroutine_body.rs diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff similarity index 100% rename from tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff rename to tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff rename to tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff From 23eb80986f6c974432032d5b42b26679dd03ee2f Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Thu, 14 May 2026 12:48:24 +0000 Subject: [PATCH 02/16] Change how coroutine layout is dumped in MIR. --- compiler/rustc_middle/src/mir/pretty.rs | 77 ++++++++++++++++++- ...await.a-{closure#0}.coroutine_resume.0.mir | 17 ++-- ...await.b-{closure#0}.coroutine_resume.0.mir | 63 ++++----------- ....main-{closure#0}.StateTransform.after.mir | 34 +++----- ....main-{closure#1}.StateTransform.after.mir | 34 +++----- ...ny.main-{closure#0}.coroutine_resume.0.mir | 32 +++----- 6 files changed, 131 insertions(+), 126 deletions(-) diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 60c829311c4b1..1f8efa72ea867 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -15,6 +15,7 @@ use crate::mir::interpret::{ }; use crate::mir::visit::Visitor; use crate::mir::*; +use crate::ty::CoroutineArgsExt; const INDENT: &str = " "; /// Alignment for lining up comments following MIR statements @@ -185,9 +186,6 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { Some(promoted) => write!(w, "::{promoted:?}`")?, } writeln!(w, " {} {}", self.disambiguator, self.pass_name)?; - if let Some(ref layout) = body.coroutine_layout_raw() { - writeln!(w, "/* coroutine_layout = {layout:#?} */")?; - } writeln!(w)?; (self.writer.extra_data)(PassWhere::BeforeCFG, w)?; write_user_type_annotations(self.tcx(), body, w)?; @@ -429,6 +427,31 @@ fn write_scope_tree( } } + // Coroutine debuginfo. + if let Some(layout) = body.coroutine_layout_raw() { + for (field, name) in layout.field_names.iter_enumerated() { + if let Some(name) = name + && let source_info = layout.field_tys[field].source_info + && source_info.scope == parent + { + let indented_debug_info = + format!("{0:1$}coroutine debug {2} => {3:?};", INDENT, indent, name, field); + + if options.include_extra_comments { + writeln!( + w, + "{0:1$} // in {2}", + indented_debug_info, + ALIGN, + comment(tcx, source_info), + )?; + } else { + writeln!(w, "{indented_debug_info}")?; + } + } + } + } + // Local variable types. for (local, local_decl) in body.local_decls.iter_enumerated() { if (1..body.arg_count + 1).contains(&local.index()) { @@ -530,6 +553,50 @@ impl Debug for VarDebugInfo<'_> { } } +fn write_coroutine_layout<'tcx>( + tcx: TyCtxt<'tcx>, + layout: &CoroutineLayout<'_>, + w: &mut dyn io::Write, + options: PrettyPrintMirOptions, +) -> io::Result<()> { + let CoroutineLayout { + field_tys, + field_names: _, // Dumped in scope tree with debug info. + variant_fields, + variant_source_info, + storage_conflicts, + } = layout; + + writeln!(w, "{INDENT}coroutine layout {{")?; + + for (field, CoroutineSavedTy { ty, source_info, ignore_for_traits }) in + field_tys.iter_enumerated() + { + let ignore_for_traits = if *ignore_for_traits { " (ignored for traits)" } else { "" }; + let indented_body = format!("{INDENT}{INDENT}field {field:?}: {ty}{ignore_for_traits};",); + if options.include_extra_comments { + writeln!(w, "{0:ALIGN$} // in {1}", indented_body, comment(tcx, *source_info))?; + } else { + writeln!(w, "{}", indented_body)?; + } + } + + writeln!(w, "{INDENT}{INDENT}variant_fields = {{")?; + for (variant, fields) in variant_fields.iter_enumerated() { + let variant_name = ty::CoroutineArgs::variant_name(variant); + let header = format!("{INDENT}{INDENT}{INDENT}{variant_name:9}({variant:?}): {fields:?},"); + if options.include_extra_comments { + let source_info = variant_source_info[variant]; + writeln!(w, "{0:ALIGN$} // in {1}", header, comment(tcx, source_info))?; + } else { + writeln!(w, "{}", header)?; + } + } + writeln!(w, "{INDENT}{INDENT}}}")?; + writeln!(w, "{INDENT}{INDENT}storage_conflicts = {storage_conflicts:?}")?; + writeln!(w, "{INDENT}}}") +} + /// Write out a human-readable textual representation of the MIR's `fn` type and the types of its /// local variables (both user-defined bindings and compiler temporaries). fn write_mir_intro<'tcx>( @@ -541,6 +608,10 @@ fn write_mir_intro<'tcx>( write_mir_sig(tcx, body, w)?; writeln!(w, "{{")?; + if let Some(ref layout) = body.coroutine_layout_raw() { + write_coroutine_layout(tcx, layout, w, options)?; + } + // construct a scope tree and write it out let mut scope_tree: FxHashMap> = Default::default(); for (index, scope_data) in body.source_scopes.iter_enumerated() { diff --git a/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir index f59cdb5c27bc0..539316c9725e4 100644 --- a/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir @@ -1,15 +1,14 @@ // MIR for `a::{closure#0}` 0 coroutine_resume -/* coroutine_layout = CoroutineLayout { - field_tys: {}, - variant_fields: { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - }, - storage_conflicts: BitMatrix(0x0) {}, -} */ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { + coroutine layout { + variant_fields = { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + } + storage_conflicts = BitMatrix(0x0) {} + } debug _task_context => _2; let mut _0: std::task::Poll<()>; let mut _3: (); diff --git a/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir index 0c130634aeac4..22e4a8cee6494 100644 --- a/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -1,56 +1,21 @@ // MIR for `b::{closure#0}` 0 coroutine_resume -/* coroutine_layout = CoroutineLayout { - field_tys: { - _s0: CoroutineSavedTy { - ty: Coroutine( - DefId(0:5 ~ async_await[ccf8]::a::{closure#0}), - [ - (), - std::future::ResumeTy, - (), - (), - (), - ], - ), - source_info: SourceInfo { - span: $DIR/async_await.rs:27:5: 27:14 (#9), - scope: scope[0], - }, - ignore_for_traits: false, - }, - _s1: CoroutineSavedTy { - ty: Coroutine( - DefId(0:5 ~ async_await[ccf8]::a::{closure#0}), - [ - (), - std::future::ResumeTy, - (), - (), - (), - ], - ), - source_info: SourceInfo { - span: $DIR/async_await.rs:28:5: 28:14 (#11), - scope: scope[0], - }, - ignore_for_traits: false, - }, - }, - variant_fields: { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - Suspend0 (3): [_s0], - Suspend1 (4): [_s1], - }, - storage_conflicts: BitMatrix(2x2) { - (_s0, _s0), - (_s1, _s1), - }, -} */ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> { + coroutine layout { + field _s0: {async fn body of a()}; + field _s1: {async fn body of a()}; + variant_fields = { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_s0], + Suspend1 (4): [_s1], + } + storage_conflicts = BitMatrix(2x2) {(_s0, _s0), (_s1, _s1)} + } debug _task_context => _2; + coroutine debug __awaitee => _s0; + coroutine debug __awaitee => _s1; let mut _0: std::task::Poll<()>; let _3: (); let mut _4: {async fn body of a()}; diff --git a/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir index 7adceef744a2a..60e52d51829fc 100644 --- a/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir +++ b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir @@ -1,29 +1,19 @@ // MIR for `main::{closure#0}` after StateTransform -/* coroutine_layout = CoroutineLayout { - field_tys: { - _s0: CoroutineSavedTy { - ty: std::string::String, - source_info: SourceInfo { - span: $DIR/coroutine.rs:19:6: 19:9 (#0), - scope: scope[0], - }, - ignore_for_traits: false, - }, - }, - variant_fields: { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - Suspend0 (3): [_s0], - Suspend1 (4): [_s0], - }, - storage_conflicts: BitMatrix(1x1) { - (_s0, _s0), - }, -} */ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { + coroutine layout { + field _s0: String; + variant_fields = { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_s0], + Suspend1 (4): [_s0], + } + storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} + } debug arg => (((*_18) as variant#4).0: std::string::String); + coroutine debug arg => _s0; let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; let _3: std::string::String; let mut _4: (&str, std::string::String, &std::panic::Location<'_>); diff --git a/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir index b4fcd2051303e..1abfe986f6867 100644 --- a/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir +++ b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir @@ -1,29 +1,19 @@ // MIR for `main::{closure#1}` after StateTransform -/* coroutine_layout = CoroutineLayout { - field_tys: { - _s0: CoroutineSavedTy { - ty: std::string::String, - source_info: SourceInfo { - span: $DIR/coroutine.rs:26:6: 26:9 (#0), - scope: scope[0], - }, - ignore_for_traits: false, - }, - }, - variant_fields: { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - Suspend0 (3): [_s0], - Suspend1 (4): [_s0], - }, - storage_conflicts: BitMatrix(1x1) { - (_s0, _s0), - }, -} */ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { + coroutine layout { + field _s0: String; + variant_fields = { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_s0], + Suspend1 (4): [_s0], + } + storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} + } debug arg => (((*_18) as variant#4).0: std::string::String); + coroutine debug arg => _s0; let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; let _3: std::string::String; let mut _4: (&str, std::string::String, &std::panic::Location<'_>); diff --git a/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir index 222c7144ef07d..e5667215d54fd 100644 --- a/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir @@ -1,28 +1,18 @@ // MIR for `main::{closure#0}` 0 coroutine_resume -/* coroutine_layout = CoroutineLayout { - field_tys: { - _s0: CoroutineSavedTy { - ty: HasDrop, - source_info: SourceInfo { - span: $DIR/coroutine_tiny.rs:22:13: 22:15 (#0), - scope: scope[0], - }, - ignore_for_traits: false, - }, - }, - variant_fields: { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - Suspend0 (3): [_s0], - }, - storage_conflicts: BitMatrix(1x1) { - (_s0, _s0), - }, -} */ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}>, _2: u8) -> CoroutineState<(), ()> { + coroutine layout { + field _s0: HasDrop; + variant_fields = { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_s0], + } + storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} + } debug _x => _2; + coroutine debug _d => _s0; let mut _0: std::ops::CoroutineState<(), ()>; let _3: HasDrop; let mut _4: !; From 144f43ec37ac06320221ed9c93fced6f8eab29f0 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 17 May 2026 15:20:10 +0000 Subject: [PATCH 03/16] Simplify can_unwind. --- compiler/rustc_mir_transform/src/coroutine.rs | 34 +------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 4ae6e9a8885d1..b18c7db387401 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1173,40 +1173,8 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { } // Unwinds can only start at certain terminators. - for block in body.basic_blocks.iter() { - match block.terminator().kind { - // These never unwind. - TerminatorKind::Goto { .. } - | TerminatorKind::SwitchInt { .. } - | TerminatorKind::UnwindTerminate(_) - | TerminatorKind::Return - | TerminatorKind::Unreachable - | TerminatorKind::CoroutineDrop - | TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } => {} - - // Resume will *continue* unwinding, but if there's no other unwinding terminator it - // will never be reached. - TerminatorKind::UnwindResume => {} - - TerminatorKind::Yield { .. } => { - unreachable!("`can_unwind` called before coroutine transform") - } - - // These may unwind. - TerminatorKind::Drop { .. } - | TerminatorKind::Call { .. } - | TerminatorKind::InlineAsm { .. } - | TerminatorKind::Assert { .. } => return true, - - TerminatorKind::TailCall { .. } => { - unreachable!("tail calls can't be present in generators") - } - } - } - + body.basic_blocks.iter().any(|block| block.terminator().unwind().is_some()) // If we didn't find an unwinding terminator, the function cannot unwind. - false } // Poison the coroutine when it unwinds From 757cfe587eed1a99402b8643007f4674374f924c Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 17 May 2026 15:43:18 +0000 Subject: [PATCH 04/16] Put entry block at the end instead of shifting everything. --- compiler/rustc_mir_transform/src/coroutine.rs | 39 +- ...nc_await.a-{closure#0}.StateTransform.diff | 56 ++ ...await.a-{closure#0}.coroutine_resume.0.mir | 46 -- ...nc_await.b-{closure#0}.StateTransform.diff | 543 ++++++++++++++++++ ...await.b-{closure#0}.coroutine_resume.0.mir | 405 ------------- tests/mir-opt/coroutine/async_await.rs | 4 +- ....main-{closure#0}.StateTransform.after.mir | 264 --------- ...utine.main-{closure#0}.StateTransform.diff | 353 ++++++++++++ ....main-{closure#1}.StateTransform.after.mir | 264 --------- ...utine.main-{closure#1}.StateTransform.diff | 353 ++++++++++++ tests/mir-opt/coroutine/coroutine.rs | 4 +- ...e#0}.StateTransform.before.panic-abort.mir | 83 --- ...#0}.StateTransform.before.panic-unwind.mir | 118 ---- ...closure#0}.StateTransform.panic-abort.diff | 141 +++++ ...losure#0}.StateTransform.panic-unwind.diff | 201 +++++++ .../coroutine_storage_dead_unwind.rs | 2 +- ..._tiny.main-{closure#0}.StateTransform.diff | 98 ++++ ...ny.main-{closure#0}.coroutine_resume.0.mir | 79 --- tests/mir-opt/coroutine/coroutine_tiny.rs | 6 +- ...y.run2-{closure#0}.Inline.panic-abort.diff | 158 ++--- ....run2-{closure#0}.Inline.panic-unwind.diff | 168 +++--- tests/ui/force-inlining/deny-async.stderr | 16 +- .../async-closure.stdout | 28 +- 23 files changed, 1964 insertions(+), 1465 deletions(-) create mode 100644 tests/mir-opt/coroutine/async_await.a-{closure#0}.StateTransform.diff delete mode 100644 tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir create mode 100644 tests/mir-opt/coroutine/async_await.b-{closure#0}.StateTransform.diff delete mode 100644 tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir delete mode 100644 tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir create mode 100644 tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.diff delete mode 100644 tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir create mode 100644 tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.diff delete mode 100644 tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir delete mode 100644 tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir create mode 100644 tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.panic-abort.diff create mode 100644 tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.panic-unwind.diff create mode 100644 tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.StateTransform.diff delete mode 100644 tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index b18c7db387401..a00fad4bd599a 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1077,7 +1077,7 @@ fn compute_layout<'tcx>( /// Replaces the entry point of `body` with a block that switches on the coroutine discriminant and /// dispatches to blocks according to `cases`. /// -/// After this function, the former entry point of the function will be bb1. +/// After this function, the former entry point of the function will be the last block. fn insert_switch<'tcx>( body: &mut Body<'tcx>, cases: Vec<(usize, BasicBlock)>, @@ -1085,23 +1085,34 @@ fn insert_switch<'tcx>( default_block: BasicBlock, ) { let (assign, discr) = transform.get_discr(body); - let switch_targets = - SwitchTargets::new(cases.iter().map(|(i, bb)| ((*i) as u128, *bb)), default_block); - let switch = TerminatorKind::SwitchInt { discr: Operand::Move(discr), targets: switch_targets }; - let source_info = SourceInfo::outermost(body.span); - body.basic_blocks_mut().raw.insert( - 0, - BasicBlockData::new_stmts( - vec![assign], - Some(Terminator { source_info, kind: switch }), - false, - ), + // MIR validation ensures that no block targets `ENTRY_BLOCK`. + #[cfg(debug_assertions)] + for bb in body.basic_blocks.iter() { + for target in bb.terminator().successors() { + assert_ne!(target, START_BLOCK); + } + } + + // Add the switch as entry block, and put the former entry block at the end. + let former_entry = std::mem::replace( + &mut body.basic_blocks_mut()[START_BLOCK], + BasicBlockData::new_stmts(vec![assign], None, false), ); + let former_entry = body.basic_blocks_mut().push(former_entry); - for b in body.basic_blocks_mut().iter_mut() { - b.terminator_mut().successors_mut(|target| *target += 1); + // We may point to `START_BLOCK` in our `cases`, replace it with `former_entry`. + let mut switch_targets = + SwitchTargets::new(cases.iter().map(|(i, bb)| ((*i) as u128, *bb)), default_block); + for bb in switch_targets.all_targets_mut() { + if *bb == START_BLOCK { + *bb = former_entry; + } } + + let switch = TerminatorKind::SwitchInt { discr: Operand::Move(discr), targets: switch_targets }; + body.basic_blocks_mut()[START_BLOCK].terminator = + Some(Terminator { source_info: SourceInfo::outermost(body.span), kind: switch }); } fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock { diff --git a/tests/mir-opt/coroutine/async_await.a-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_await.a-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..dddd66e73fd51 --- /dev/null +++ b/tests/mir-opt/coroutine/async_await.a-{closure#0}.StateTransform.diff @@ -0,0 +1,56 @@ +- // MIR for `a::{closure#0}` before StateTransform ++ // MIR for `a::{closure#0}` after StateTransform + +- fn a::{closure#0}(_1: {async fn body of a()}, _2: std::future::ResumeTy) -> () +- yields () +- { ++ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ } ++ storage_conflicts = BitMatrix(0x0) {} ++ } + debug _task_context => _2; +- let mut _0: (); ++ let mut _0: std::task::Poll<()>; ++ let mut _3: (); ++ let mut _4: u32; ++ let mut _5: &mut {async fn body of a()}; + + bb0: { +- _0 = const (); +- drop(_1) -> [return: bb1, unwind: bb2]; ++ _5 = copy (_1.0: &mut {async fn body of a()}); ++ _4 = discriminant((*_5)); ++ switchInt(move _4) -> [0: bb5, 1: bb3, otherwise: bb4]; + } + + bb1: { ++ _0 = Poll::<()>::Ready(move _3); ++ discriminant((*_5)) = 1; + return; + } + +- bb2 (cleanup): { +- resume; ++ bb2: { ++ goto -> bb1; ++ } ++ ++ bb3: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb3, unwind continue]; ++ } ++ ++ bb4: { ++ unreachable; ++ } ++ ++ bb5: { ++ _3 = const (); ++ goto -> bb2; + } + } + diff --git a/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir deleted file mode 100644 index 539316c9725e4..0000000000000 --- a/tests/mir-opt/coroutine/async_await.a-{closure#0}.coroutine_resume.0.mir +++ /dev/null @@ -1,46 +0,0 @@ -// MIR for `a::{closure#0}` 0 coroutine_resume - -fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { - coroutine layout { - variant_fields = { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - } - storage_conflicts = BitMatrix(0x0) {} - } - debug _task_context => _2; - let mut _0: std::task::Poll<()>; - let mut _3: (); - let mut _4: u32; - let mut _5: &mut {async fn body of a()}; - - bb0: { - _5 = copy (_1.0: &mut {async fn body of a()}); - _4 = discriminant((*_5)); - switchInt(move _4) -> [0: bb1, 1: bb4, otherwise: bb5]; - } - - bb1: { - _3 = const (); - goto -> bb3; - } - - bb2: { - _0 = Poll::<()>::Ready(move _3); - discriminant((*_5)) = 1; - return; - } - - bb3: { - goto -> bb2; - } - - bb4: { - assert(const false, "`async fn` resumed after completion") -> [success: bb4, unwind continue]; - } - - bb5: { - unreachable; - } -} diff --git a/tests/mir-opt/coroutine/async_await.b-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_await.b-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..fdbc67d51bd34 --- /dev/null +++ b/tests/mir-opt/coroutine/async_await.b-{closure#0}.StateTransform.diff @@ -0,0 +1,543 @@ +- // MIR for `b::{closure#0}` before StateTransform ++ // MIR for `b::{closure#0}` after StateTransform + +- fn b::{closure#0}(_1: {async fn body of b()}, _2: std::future::ResumeTy) -> () +- yields () +- { ++ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> { ++ coroutine layout { ++ field _s0: {async fn body of a()}; ++ field _s1: {async fn body of a()}; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0], ++ Suspend1 (4): [_s1], ++ } ++ storage_conflicts = BitMatrix(2x2) {(_s0, _s0), (_s1, _s1)} ++ } + debug _task_context => _2; +- let mut _0: (); ++ coroutine debug __awaitee => _s0; ++ coroutine debug __awaitee => _s1; ++ let mut _0: std::task::Poll<()>; + let _3: (); + let mut _4: {async fn body of a()}; + let mut _5: {async fn body of a()}; + let mut _6: {async fn body of a()}; + let mut _7: (); + let _8: (); + let mut _9: std::task::Poll<()>; + let mut _10: std::pin::Pin<&mut {async fn body of a()}>; + let mut _11: &mut {async fn body of a()}; + let mut _12: &mut {async fn body of a()}; + let mut _13: &mut std::task::Context<'_>; + let mut _14: &mut std::task::Context<'_>; +- let mut _15: std::future::ResumeTy; ++ let mut _15: &mut std::task::Context<'_>; + let mut _16: isize; + let mut _18: !; +- let mut _19: std::future::ResumeTy; ++ let mut _19: &mut std::task::Context<'_>; + let mut _20: (); + let mut _21: {async fn body of a()}; + let mut _22: {async fn body of a()}; + let mut _23: {async fn body of a()}; + let _24: (); + let mut _25: std::task::Poll<()>; + let mut _26: std::pin::Pin<&mut {async fn body of a()}>; + let mut _27: &mut {async fn body of a()}; + let mut _28: &mut {async fn body of a()}; + let mut _29: &mut std::task::Context<'_>; + let mut _30: &mut std::task::Context<'_>; +- let mut _31: std::future::ResumeTy; ++ let mut _31: &mut std::task::Context<'_>; + let mut _32: isize; + let mut _34: !; +- let mut _35: std::future::ResumeTy; ++ let mut _35: &mut std::task::Context<'_>; + let mut _36: (); ++ let mut _37: (); ++ let mut _38: u32; ++ let mut _39: &mut {async fn body of b()}; + scope 1 { +- debug __awaitee => _6; ++ debug __awaitee => (((*_39) as variant#3).0: {async fn body of a()}); + let _17: (); + scope 2 { + debug result => _17; + } + } + scope 3 { +- debug __awaitee => _23; ++ debug __awaitee => (((*_39) as variant#4).0: {async fn body of a()}); + let _33: (); + scope 4 { + debug result => _33; + } + } + + bb0: { +- StorageLive(_3); +- StorageLive(_4); +- StorageLive(_5); +- _5 = a() -> [return: bb1, unwind: bb47]; ++ _39 = copy (_1.0: &mut {async fn body of b()}); ++ _38 = discriminant((*_39)); ++ switchInt(move _38) -> [0: bb47, 1: bb46, 2: bb45, 3: bb43, 4: bb44, otherwise: bb7]; + } + + bb1: { +- _4 = <{async fn body of a()} as IntoFuture>::into_future(move _5) -> [return: bb2, unwind: bb46]; ++ _4 = <{async fn body of a()} as IntoFuture>::into_future(move _5) -> [return: bb2, unwind: bb36]; + } + + bb2: { + StorageDead(_5); + PlaceMention(_4); +- StorageLive(_6); +- _6 = move _4; ++ nop; ++ (((*_39) as variant#3).0: {async fn body of a()}) = move _4; + goto -> bb3; + } + + bb3: { + StorageLive(_8); + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + StorageLive(_12); +- _12 = &mut _6; ++ _12 = &mut (((*_39) as variant#3).0: {async fn body of a()}); + _11 = &mut (*_12); +- _10 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _11) -> [return: bb4, unwind: bb43]; ++ _10 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _11) -> [return: bb4, unwind: bb33]; + } + + bb4: { + StorageDead(_11); + StorageLive(_13); + StorageLive(_14); + StorageLive(_15); + _15 = copy _2; +- _14 = std::future::get_context::<'_, '_>(move _15) -> [return: bb5, unwind: bb41]; ++ _14 = move _15; ++ goto -> bb5; + } + + bb5: { + _13 = &mut (*_14); + StorageDead(_15); +- _9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb6, unwind: bb42]; ++ _9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb6, unwind: bb32]; + } + + bb6: { + StorageDead(_13); + StorageDead(_10); + PlaceMention(_9); + _16 = discriminant(_9); + switchInt(move _16) -> [0: bb9, 1: bb8, otherwise: bb7]; + } + + bb7: { + unreachable; + } + + bb8: { + _8 = const (); + StorageDead(_14); + StorageDead(_12); + StorageDead(_9); + StorageDead(_8); + StorageLive(_19); + StorageLive(_20); + _20 = (); +- _19 = yield(move _20) -> [resume: bb10, drop: bb28]; ++ _0 = Poll::<()>::Pending; ++ StorageDead(_3); ++ StorageDead(_4); ++ StorageDead(_19); ++ StorageDead(_20); ++ discriminant((*_39)) = 3; ++ return; + } + + bb9: { + StorageLive(_17); + _17 = copy ((_9 as Ready).0: ()); + _3 = copy _17; + StorageDead(_17); + StorageDead(_14); + StorageDead(_12); + StorageDead(_9); + StorageDead(_8); +- drop(_6) -> [return: bb11, unwind: bb45]; ++ drop((((*_39) as variant#3).0: {async fn body of a()})) -> [return: bb11, unwind: bb35]; + } + + bb10: { + StorageDead(_20); + _2 = move _19; + StorageDead(_19); + _7 = const (); + goto -> bb3; + } + + bb11: { +- StorageDead(_6); ++ nop; + goto -> bb12; + } + + bb12: { + StorageDead(_4); + StorageDead(_3); + StorageLive(_21); + StorageLive(_22); +- _22 = a() -> [return: bb13, unwind: bb39]; ++ _22 = a() -> [return: bb13, unwind: bb30]; + } + + bb13: { +- _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb14, unwind: bb38]; ++ _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb14, unwind: bb29]; + } + + bb14: { + StorageDead(_22); + PlaceMention(_21); +- StorageLive(_23); +- _23 = move _21; ++ nop; ++ (((*_39) as variant#4).0: {async fn body of a()}) = move _21; + goto -> bb15; + } + + bb15: { + StorageLive(_24); + StorageLive(_25); + StorageLive(_26); + StorageLive(_27); + StorageLive(_28); +- _28 = &mut _23; ++ _28 = &mut (((*_39) as variant#4).0: {async fn body of a()}); + _27 = &mut (*_28); +- _26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb16, unwind: bb35]; ++ _26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb16, unwind: bb26]; + } + + bb16: { + StorageDead(_27); + StorageLive(_29); + StorageLive(_30); + StorageLive(_31); + _31 = copy _2; +- _30 = std::future::get_context::<'_, '_>(move _31) -> [return: bb17, unwind: bb33]; ++ _30 = move _31; ++ goto -> bb17; + } + + bb17: { + _29 = &mut (*_30); + StorageDead(_31); +- _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb18, unwind: bb34]; ++ _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb18, unwind: bb25]; + } + + bb18: { + StorageDead(_29); + StorageDead(_26); + PlaceMention(_25); + _32 = discriminant(_25); + switchInt(move _32) -> [0: bb20, 1: bb19, otherwise: bb7]; + } + + bb19: { + _24 = const (); + StorageDead(_30); + StorageDead(_28); + StorageDead(_25); + StorageDead(_24); + StorageLive(_35); + StorageLive(_36); + _36 = (); +- _35 = yield(move _36) -> [resume: bb21, drop: bb25]; ++ _0 = Poll::<()>::Pending; ++ StorageDead(_21); ++ StorageDead(_35); ++ StorageDead(_36); ++ discriminant((*_39)) = 4; ++ return; + } + + bb20: { + StorageLive(_33); + _33 = copy ((_25 as Ready).0: ()); +- _0 = copy _33; ++ _37 = copy _33; + StorageDead(_33); + StorageDead(_30); + StorageDead(_28); + StorageDead(_25); + StorageDead(_24); +- drop(_23) -> [return: bb22, unwind: bb37]; ++ drop((((*_39) as variant#4).0: {async fn body of a()})) -> [return: bb22, unwind: bb28]; + } + + bb21: { + StorageDead(_36); + _2 = move _35; + StorageDead(_35); + _7 = const (); + goto -> bb15; + } + + bb22: { +- StorageDead(_23); ++ nop; + goto -> bb23; + } + + bb23: { + StorageDead(_21); +- drop(_1) -> [return: bb24, unwind: bb50]; ++ goto -> bb41; + } + + bb24: { ++ _0 = Poll::<()>::Ready(move _37); ++ discriminant((*_39)) = 1; + return; + } + +- bb25: { +- StorageDead(_36); +- StorageDead(_35); +- drop(_23) -> [return: bb26, unwind: bb51]; +- } +- +- bb26: { +- StorageDead(_23); +- goto -> bb27; +- } +- +- bb27: { +- StorageDead(_21); +- goto -> bb31; +- } +- +- bb28: { +- StorageDead(_20); +- StorageDead(_19); +- drop(_6) -> [return: bb29, unwind: bb53]; +- } +- +- bb29: { +- StorageDead(_6); +- goto -> bb30; +- } +- +- bb30: { +- StorageDead(_4); +- StorageDead(_3); +- goto -> bb31; +- } +- +- bb31: { +- drop(_1) -> [return: bb32, unwind: bb50]; +- } +- +- bb32: { +- coroutine_drop; +- } +- +- bb33 (cleanup): { +- StorageDead(_31); +- goto -> bb34; +- } +- +- bb34 (cleanup): { ++ bb25 (cleanup): { + StorageDead(_29); + StorageDead(_26); + StorageDead(_30); +- goto -> bb36; ++ goto -> bb27; + } + +- bb35 (cleanup): { ++ bb26 (cleanup): { + StorageDead(_27); + StorageDead(_26); +- goto -> bb36; ++ goto -> bb27; + } + +- bb36 (cleanup): { ++ bb27 (cleanup): { + StorageDead(_28); + StorageDead(_25); + StorageDead(_24); +- drop(_23) -> [return: bb37, unwind terminate(cleanup)]; ++ drop((((*_39) as variant#4).0: {async fn body of a()})) -> [return: bb28, unwind terminate(cleanup)]; + } + +- bb37 (cleanup): { +- StorageDead(_23); +- goto -> bb40; ++ bb28 (cleanup): { ++ nop; ++ goto -> bb31; + } + +- bb38 (cleanup): { +- goto -> bb39; ++ bb29 (cleanup): { ++ goto -> bb30; + } + +- bb39 (cleanup): { ++ bb30 (cleanup): { + StorageDead(_22); +- goto -> bb40; ++ goto -> bb31; + } + +- bb40 (cleanup): { ++ bb31 (cleanup): { + StorageDead(_21); +- goto -> bb49; ++ goto -> bb39; + } + +- bb41 (cleanup): { +- StorageDead(_15); +- goto -> bb42; +- } +- +- bb42 (cleanup): { ++ bb32 (cleanup): { + StorageDead(_13); + StorageDead(_10); + StorageDead(_14); +- goto -> bb44; ++ goto -> bb34; + } + +- bb43 (cleanup): { ++ bb33 (cleanup): { + StorageDead(_11); + StorageDead(_10); +- goto -> bb44; ++ goto -> bb34; + } + +- bb44 (cleanup): { ++ bb34 (cleanup): { + StorageDead(_12); + StorageDead(_9); + StorageDead(_8); +- drop(_6) -> [return: bb45, unwind terminate(cleanup)]; ++ drop((((*_39) as variant#3).0: {async fn body of a()})) -> [return: bb35, unwind terminate(cleanup)]; + } + +- bb45 (cleanup): { +- StorageDead(_6); +- goto -> bb48; ++ bb35 (cleanup): { ++ nop; ++ goto -> bb38; + } + +- bb46 (cleanup): { +- goto -> bb47; ++ bb36 (cleanup): { ++ goto -> bb37; + } + +- bb47 (cleanup): { ++ bb37 (cleanup): { + StorageDead(_5); +- goto -> bb48; ++ goto -> bb38; + } + +- bb48 (cleanup): { ++ bb38 (cleanup): { + StorageDead(_4); + StorageDead(_3); +- goto -> bb49; ++ goto -> bb39; + } + +- bb49 (cleanup): { +- drop(_1) -> [return: bb50, unwind terminate(cleanup)]; ++ bb39 (cleanup): { ++ goto -> bb40; + } + +- bb50 (cleanup): { ++ bb40 (cleanup): { ++ goto -> bb42; ++ } ++ ++ bb41: { ++ goto -> bb24; ++ } ++ ++ bb42 (cleanup): { ++ discriminant((*_39)) = 2; + resume; + } + +- bb51 (cleanup): { +- StorageDead(_23); +- goto -> bb52; ++ bb43: { ++ StorageLive(_3); ++ StorageLive(_4); ++ StorageLive(_19); ++ StorageLive(_20); ++ _19 = move _2; ++ goto -> bb10; + } + +- bb52 (cleanup): { +- StorageDead(_21); +- goto -> bb55; ++ bb44: { ++ StorageLive(_21); ++ StorageLive(_35); ++ StorageLive(_36); ++ _35 = move _2; ++ goto -> bb21; + } + +- bb53 (cleanup): { +- StorageDead(_6); +- goto -> bb54; ++ bb45: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb45, unwind continue]; + } + +- bb54 (cleanup): { +- StorageDead(_4); +- StorageDead(_3); +- goto -> bb55; ++ bb46: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb46, unwind continue]; + } + +- bb55 (cleanup): { +- drop(_1) -> [return: bb50, unwind terminate(cleanup)]; ++ bb47: { ++ StorageLive(_3); ++ StorageLive(_4); ++ StorageLive(_5); ++ _5 = a() -> [return: bb1, unwind: bb37]; + } + } + diff --git a/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir deleted file mode 100644 index 22e4a8cee6494..0000000000000 --- a/tests/mir-opt/coroutine/async_await.b-{closure#0}.coroutine_resume.0.mir +++ /dev/null @@ -1,405 +0,0 @@ -// MIR for `b::{closure#0}` 0 coroutine_resume - -fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> { - coroutine layout { - field _s0: {async fn body of a()}; - field _s1: {async fn body of a()}; - variant_fields = { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - Suspend0 (3): [_s0], - Suspend1 (4): [_s1], - } - storage_conflicts = BitMatrix(2x2) {(_s0, _s0), (_s1, _s1)} - } - debug _task_context => _2; - coroutine debug __awaitee => _s0; - coroutine debug __awaitee => _s1; - let mut _0: std::task::Poll<()>; - let _3: (); - let mut _4: {async fn body of a()}; - let mut _5: {async fn body of a()}; - let mut _6: {async fn body of a()}; - let mut _7: (); - let _8: (); - let mut _9: std::task::Poll<()>; - let mut _10: std::pin::Pin<&mut {async fn body of a()}>; - let mut _11: &mut {async fn body of a()}; - let mut _12: &mut {async fn body of a()}; - let mut _13: &mut std::task::Context<'_>; - let mut _14: &mut std::task::Context<'_>; - let mut _15: &mut std::task::Context<'_>; - let mut _16: isize; - let mut _18: !; - let mut _19: &mut std::task::Context<'_>; - let mut _20: (); - let mut _21: {async fn body of a()}; - let mut _22: {async fn body of a()}; - let mut _23: {async fn body of a()}; - let _24: (); - let mut _25: std::task::Poll<()>; - let mut _26: std::pin::Pin<&mut {async fn body of a()}>; - let mut _27: &mut {async fn body of a()}; - let mut _28: &mut {async fn body of a()}; - let mut _29: &mut std::task::Context<'_>; - let mut _30: &mut std::task::Context<'_>; - let mut _31: &mut std::task::Context<'_>; - let mut _32: isize; - let mut _34: !; - let mut _35: &mut std::task::Context<'_>; - let mut _36: (); - let mut _37: (); - let mut _38: u32; - let mut _39: &mut {async fn body of b()}; - scope 1 { - debug __awaitee => (((*_39) as variant#3).0: {async fn body of a()}); - let _17: (); - scope 2 { - debug result => _17; - } - } - scope 3 { - debug __awaitee => (((*_39) as variant#4).0: {async fn body of a()}); - let _33: (); - scope 4 { - debug result => _33; - } - } - - bb0: { - _39 = copy (_1.0: &mut {async fn body of b()}); - _38 = discriminant((*_39)); - switchInt(move _38) -> [0: bb1, 1: bb47, 2: bb46, 3: bb44, 4: bb45, otherwise: bb8]; - } - - bb1: { - StorageLive(_3); - StorageLive(_4); - StorageLive(_5); - _5 = a() -> [return: bb2, unwind: bb38]; - } - - bb2: { - _4 = <{async fn body of a()} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind: bb37]; - } - - bb3: { - StorageDead(_5); - PlaceMention(_4); - nop; - (((*_39) as variant#3).0: {async fn body of a()}) = move _4; - goto -> bb4; - } - - bb4: { - StorageLive(_8); - StorageLive(_9); - StorageLive(_10); - StorageLive(_11); - StorageLive(_12); - _12 = &mut (((*_39) as variant#3).0: {async fn body of a()}); - _11 = &mut (*_12); - _10 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _11) -> [return: bb5, unwind: bb34]; - } - - bb5: { - StorageDead(_11); - StorageLive(_13); - StorageLive(_14); - StorageLive(_15); - _15 = copy _2; - _14 = move _15; - goto -> bb6; - } - - bb6: { - _13 = &mut (*_14); - StorageDead(_15); - _9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb7, unwind: bb33]; - } - - bb7: { - StorageDead(_13); - StorageDead(_10); - PlaceMention(_9); - _16 = discriminant(_9); - switchInt(move _16) -> [0: bb10, 1: bb9, otherwise: bb8]; - } - - bb8: { - unreachable; - } - - bb9: { - _8 = const (); - StorageDead(_14); - StorageDead(_12); - StorageDead(_9); - StorageDead(_8); - StorageLive(_19); - StorageLive(_20); - _20 = (); - _0 = Poll::<()>::Pending; - StorageDead(_3); - StorageDead(_4); - StorageDead(_19); - StorageDead(_20); - discriminant((*_39)) = 3; - return; - } - - bb10: { - StorageLive(_17); - _17 = copy ((_9 as Ready).0: ()); - _3 = copy _17; - StorageDead(_17); - StorageDead(_14); - StorageDead(_12); - StorageDead(_9); - StorageDead(_8); - drop((((*_39) as variant#3).0: {async fn body of a()})) -> [return: bb12, unwind: bb36]; - } - - bb11: { - StorageDead(_20); - _2 = move _19; - StorageDead(_19); - _7 = const (); - goto -> bb4; - } - - bb12: { - nop; - goto -> bb13; - } - - bb13: { - StorageDead(_4); - StorageDead(_3); - StorageLive(_21); - StorageLive(_22); - _22 = a() -> [return: bb14, unwind: bb31]; - } - - bb14: { - _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind: bb30]; - } - - bb15: { - StorageDead(_22); - PlaceMention(_21); - nop; - (((*_39) as variant#4).0: {async fn body of a()}) = move _21; - goto -> bb16; - } - - bb16: { - StorageLive(_24); - StorageLive(_25); - StorageLive(_26); - StorageLive(_27); - StorageLive(_28); - _28 = &mut (((*_39) as variant#4).0: {async fn body of a()}); - _27 = &mut (*_28); - _26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb17, unwind: bb27]; - } - - bb17: { - StorageDead(_27); - StorageLive(_29); - StorageLive(_30); - StorageLive(_31); - _31 = copy _2; - _30 = move _31; - goto -> bb18; - } - - bb18: { - _29 = &mut (*_30); - StorageDead(_31); - _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb19, unwind: bb26]; - } - - bb19: { - StorageDead(_29); - StorageDead(_26); - PlaceMention(_25); - _32 = discriminant(_25); - switchInt(move _32) -> [0: bb21, 1: bb20, otherwise: bb8]; - } - - bb20: { - _24 = const (); - StorageDead(_30); - StorageDead(_28); - StorageDead(_25); - StorageDead(_24); - StorageLive(_35); - StorageLive(_36); - _36 = (); - _0 = Poll::<()>::Pending; - StorageDead(_21); - StorageDead(_35); - StorageDead(_36); - discriminant((*_39)) = 4; - return; - } - - bb21: { - StorageLive(_33); - _33 = copy ((_25 as Ready).0: ()); - _37 = copy _33; - StorageDead(_33); - StorageDead(_30); - StorageDead(_28); - StorageDead(_25); - StorageDead(_24); - drop((((*_39) as variant#4).0: {async fn body of a()})) -> [return: bb23, unwind: bb29]; - } - - bb22: { - StorageDead(_36); - _2 = move _35; - StorageDead(_35); - _7 = const (); - goto -> bb16; - } - - bb23: { - nop; - goto -> bb24; - } - - bb24: { - StorageDead(_21); - goto -> bb42; - } - - bb25: { - _0 = Poll::<()>::Ready(move _37); - discriminant((*_39)) = 1; - return; - } - - bb26 (cleanup): { - StorageDead(_29); - StorageDead(_26); - StorageDead(_30); - goto -> bb28; - } - - bb27 (cleanup): { - StorageDead(_27); - StorageDead(_26); - goto -> bb28; - } - - bb28 (cleanup): { - StorageDead(_28); - StorageDead(_25); - StorageDead(_24); - drop((((*_39) as variant#4).0: {async fn body of a()})) -> [return: bb29, unwind terminate(cleanup)]; - } - - bb29 (cleanup): { - nop; - goto -> bb32; - } - - bb30 (cleanup): { - goto -> bb31; - } - - bb31 (cleanup): { - StorageDead(_22); - goto -> bb32; - } - - bb32 (cleanup): { - StorageDead(_21); - goto -> bb40; - } - - bb33 (cleanup): { - StorageDead(_13); - StorageDead(_10); - StorageDead(_14); - goto -> bb35; - } - - bb34 (cleanup): { - StorageDead(_11); - StorageDead(_10); - goto -> bb35; - } - - bb35 (cleanup): { - StorageDead(_12); - StorageDead(_9); - StorageDead(_8); - drop((((*_39) as variant#3).0: {async fn body of a()})) -> [return: bb36, unwind terminate(cleanup)]; - } - - bb36 (cleanup): { - nop; - goto -> bb39; - } - - bb37 (cleanup): { - goto -> bb38; - } - - bb38 (cleanup): { - StorageDead(_5); - goto -> bb39; - } - - bb39 (cleanup): { - StorageDead(_4); - StorageDead(_3); - goto -> bb40; - } - - bb40 (cleanup): { - goto -> bb41; - } - - bb41 (cleanup): { - goto -> bb43; - } - - bb42: { - goto -> bb25; - } - - bb43 (cleanup): { - discriminant((*_39)) = 2; - resume; - } - - bb44: { - StorageLive(_3); - StorageLive(_4); - StorageLive(_19); - StorageLive(_20); - _19 = move _2; - goto -> bb11; - } - - bb45: { - StorageLive(_21); - StorageLive(_35); - StorageLive(_36); - _35 = move _2; - goto -> bb22; - } - - bb46: { - assert(const false, "`async fn` resumed after panicking") -> [success: bb46, unwind continue]; - } - - bb47: { - assert(const false, "`async fn` resumed after completion") -> [success: bb47, unwind continue]; - } -} diff --git a/tests/mir-opt/coroutine/async_await.rs b/tests/mir-opt/coroutine/async_await.rs index 8334baa594720..4e506edb61cf5 100644 --- a/tests/mir-opt/coroutine/async_await.rs +++ b/tests/mir-opt/coroutine/async_await.rs @@ -8,7 +8,7 @@ #![crate_type = "lib"] -// EMIT_MIR async_await.a-{closure#0}.coroutine_resume.0.mir +// EMIT_MIR async_await.a-{closure#0}.StateTransform.diff async fn a() { // CHECK-LABEL: fn a::{closure#0}( // CHECK-SAME: _1: Pin<&mut {async fn body of a()}> @@ -17,7 +17,7 @@ async fn a() { // CHECK-NOT: get_context } -// EMIT_MIR async_await.b-{closure#0}.coroutine_resume.0.mir +// EMIT_MIR async_await.b-{closure#0}.StateTransform.diff pub async fn b() { // CHECK-LABEL: fn b::{closure#0}( // CHECK-SAME: _1: Pin<&mut {async fn body of b()}> diff --git a/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir deleted file mode 100644 index 60e52d51829fc..0000000000000 --- a/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.after.mir +++ /dev/null @@ -1,264 +0,0 @@ -// MIR for `main::{closure#0}` after StateTransform - -fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { - coroutine layout { - field _s0: String; - variant_fields = { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - Suspend0 (3): [_s0], - Suspend1 (4): [_s0], - } - storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} - } - debug arg => (((*_18) as variant#4).0: std::string::String); - coroutine debug arg => _s0; - let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; - let _3: std::string::String; - let mut _4: (&str, std::string::String, &std::panic::Location<'_>); - let mut _5: std::string::String; - let mut _6: &std::string::String; - let mut _7: &std::panic::Location<'_>; - let _8: std::string::String; - let mut _9: (&str, std::string::String, &std::panic::Location<'_>); - let mut _10: &str; - let _11: &str; - let mut _12: std::string::String; - let mut _13: &std::string::String; - let mut _14: &std::panic::Location<'_>; - let _15: &std::panic::Location<'_>; - let mut _16: (); - let mut _17: u32; - let mut _18: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}; - - bb0: { - _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}); - _17 = discriminant((*_18)); - switchInt(move _17) -> [0: bb1, 1: bb35, 2: bb34, 3: bb32, 4: bb33, otherwise: bb36]; - } - - bb1: { - (((*_18) as variant#4).0: std::string::String) = move _2; - StorageLive(_3); - StorageLive(_4); - StorageLive(_5); - StorageLive(_6); - _6 = &(((*_18) as variant#4).0: std::string::String); - _5 = ::clone(move _6) -> [return: bb2, unwind: bb23]; - } - - bb2: { - StorageDead(_6); - StorageLive(_7); - _7 = Location::<'_>::caller() -> [return: bb3, unwind: bb22]; - } - - bb3: { - _4 = (const "first", move _5, move _7); - StorageDead(_7); - goto -> bb4; - } - - bb4: { - StorageDead(_5); - _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4); - StorageDead(_3); - StorageDead(_4); - discriminant((*_18)) = 3; - return; - } - - bb5: { - goto -> bb6; - } - - bb6: { - StorageDead(_4); - drop(_3) -> [return: bb7, unwind: bb26]; - } - - bb7: { - StorageDead(_3); - StorageLive(_8); - StorageLive(_9); - StorageLive(_10); - StorageLive(_11); - _11 = const "second"; - _10 = &(*_11); - StorageLive(_12); - StorageLive(_13); - _13 = &(((*_18) as variant#4).0: std::string::String); - _12 = ::clone(move _13) -> [return: bb8, unwind: bb20]; - } - - bb8: { - StorageDead(_13); - StorageLive(_14); - StorageLive(_15); - _15 = Location::<'_>::caller() -> [return: bb9, unwind: bb16]; - } - - bb9: { - _14 = &(*_15); - _9 = (move _10, move _12, move _14); - StorageDead(_14); - goto -> bb10; - } - - bb10: { - StorageDead(_12); - StorageDead(_10); - _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _9); - StorageDead(_8); - StorageDead(_9); - StorageDead(_11); - StorageDead(_15); - discriminant((*_18)) = 4; - return; - } - - bb11: { - goto -> bb12; - } - - bb12: { - StorageDead(_9); - drop(_8) -> [return: bb13, unwind: bb19]; - } - - bb13: { - StorageDead(_15); - StorageDead(_11); - StorageDead(_8); - _16 = const (); - drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb14, unwind: bb28]; - } - - bb14: { - goto -> bb30; - } - - bb15: { - _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16); - discriminant((*_18)) = 1; - return; - } - - bb16 (cleanup): { - StorageDead(_14); - drop(_12) -> [return: bb17, unwind terminate(cleanup)]; - } - - bb17 (cleanup): { - StorageDead(_12); - StorageDead(_10); - goto -> bb18; - } - - bb18 (cleanup): { - StorageDead(_9); - goto -> bb19; - } - - bb19 (cleanup): { - StorageDead(_15); - goto -> bb21; - } - - bb20 (cleanup): { - StorageDead(_13); - StorageDead(_12); - StorageDead(_10); - StorageDead(_9); - goto -> bb21; - } - - bb21 (cleanup): { - StorageDead(_11); - StorageDead(_8); - goto -> bb27; - } - - bb22 (cleanup): { - StorageDead(_7); - drop(_5) -> [return: bb24, unwind terminate(cleanup)]; - } - - bb23 (cleanup): { - StorageDead(_6); - goto -> bb24; - } - - bb24 (cleanup): { - StorageDead(_5); - goto -> bb25; - } - - bb25 (cleanup): { - StorageDead(_4); - goto -> bb26; - } - - bb26 (cleanup): { - StorageDead(_3); - goto -> bb27; - } - - bb27 (cleanup): { - drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb28, unwind terminate(cleanup)]; - } - - bb28 (cleanup): { - goto -> bb29; - } - - bb29 (cleanup): { - goto -> bb31; - } - - bb30: { - goto -> bb15; - } - - bb31 (cleanup): { - discriminant((*_18)) = 2; - resume; - } - - bb32: { - StorageLive(_3); - StorageLive(_4); - _3 = move _2; - goto -> bb5; - } - - bb33: { - StorageLive(_8); - StorageLive(_9); - StorageLive(_11); - StorageLive(_15); - _8 = move _2; - goto -> bb11; - } - - bb34: { - assert(const false, "coroutine resumed after panicking") -> [success: bb34, unwind continue]; - } - - bb35: { - assert(const false, "coroutine resumed after completion") -> [success: bb35, unwind continue]; - } - - bb36: { - unreachable; - } -} - -ALLOC0 (size: 6, align: 1) { - 73 65 63 6f 6e 64 │ second -} - -ALLOC1 (size: 5, align: 1) { - 66 69 72 73 74 │ first -} diff --git a/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..17671228295e3 --- /dev/null +++ b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.diff @@ -0,0 +1,353 @@ +- // MIR for `main::{closure#0}` before StateTransform ++ // MIR for `main::{closure#0}` after StateTransform + +- fn main::{closure#0}(_1: {coroutine@$DIR/coroutine.rs:19:5: 19:18}, _2: String) -> () +- yields (&str, String, &Location<'_>) +- { +- debug arg => _2; +- let mut _0: (); ++ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { ++ coroutine layout { ++ field _s0: String; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0], ++ Suspend1 (4): [_s0], ++ } ++ storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} ++ } ++ debug arg => (((*_18) as variant#4).0: std::string::String); ++ coroutine debug arg => _s0; ++ let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; + let _3: std::string::String; + let mut _4: (&str, std::string::String, &std::panic::Location<'_>); + let mut _5: std::string::String; + let mut _6: &std::string::String; + let mut _7: &std::panic::Location<'_>; + let _8: std::string::String; + let mut _9: (&str, std::string::String, &std::panic::Location<'_>); + let mut _10: &str; + let _11: &str; + let mut _12: std::string::String; + let mut _13: &std::string::String; + let mut _14: &std::panic::Location<'_>; + let _15: &std::panic::Location<'_>; ++ let mut _16: (); ++ let mut _17: u32; ++ let mut _18: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}; + + bb0: { +- StorageLive(_3); +- StorageLive(_4); +- StorageLive(_5); +- StorageLive(_6); +- _6 = &_2; +- _5 = ::clone(move _6) -> [return: bb1, unwind: bb31]; ++ _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}); ++ _17 = discriminant((*_18)); ++ switchInt(move _17) -> [0: bb36, 1: bb34, 2: bb33, 3: bb31, 4: bb32, otherwise: bb35]; + } + + bb1: { + StorageDead(_6); + StorageLive(_7); +- _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb30]; ++ _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb21]; + } + + bb2: { + _4 = (const "first", move _5, move _7); + StorageDead(_7); + goto -> bb3; + } + + bb3: { + StorageDead(_5); +- _3 = yield(move _4) -> [resume: bb4, drop: bb18]; ++ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4); ++ StorageDead(_3); ++ StorageDead(_4); ++ discriminant((*_18)) = 3; ++ return; + } + + bb4: { + goto -> bb5; + } + + bb5: { + StorageDead(_4); +- drop(_3) -> [return: bb6, unwind: bb34]; ++ drop(_3) -> [return: bb6, unwind: bb25]; + } + + bb6: { + StorageDead(_3); + StorageLive(_8); + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + _11 = const "second"; + _10 = &(*_11); + StorageLive(_12); + StorageLive(_13); +- _13 = &_2; +- _12 = ::clone(move _13) -> [return: bb7, unwind: bb28]; ++ _13 = &(((*_18) as variant#4).0: std::string::String); ++ _12 = ::clone(move _13) -> [return: bb7, unwind: bb19]; + } + + bb7: { + StorageDead(_13); + StorageLive(_14); + StorageLive(_15); +- _15 = Location::<'_>::caller() -> [return: bb8, unwind: bb24]; ++ _15 = Location::<'_>::caller() -> [return: bb8, unwind: bb15]; + } + + bb8: { + _14 = &(*_15); + _9 = (move _10, move _12, move _14); + StorageDead(_14); + goto -> bb9; + } + + bb9: { + StorageDead(_12); + StorageDead(_10); +- _8 = yield(move _9) -> [resume: bb10, drop: bb15]; ++ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _9); ++ StorageDead(_8); ++ StorageDead(_9); ++ StorageDead(_11); ++ StorageDead(_15); ++ discriminant((*_18)) = 4; ++ return; + } + + bb10: { + goto -> bb11; + } + + bb11: { + StorageDead(_9); +- drop(_8) -> [return: bb12, unwind: bb27]; ++ drop(_8) -> [return: bb12, unwind: bb18]; + } + + bb12: { + StorageDead(_15); + StorageDead(_11); + StorageDead(_8); +- _0 = const (); +- drop(_2) -> [return: bb13, unwind: bb36]; ++ _16 = const (); ++ drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb13, unwind: bb27]; + } + + bb13: { +- drop(_1) -> [return: bb14, unwind: bb37]; ++ goto -> bb29; + } + + bb14: { ++ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16); ++ discriminant((*_18)) = 1; + return; + } + +- bb15: { +- goto -> bb16; ++ bb15 (cleanup): { ++ StorageDead(_14); ++ drop(_12) -> [return: bb16, unwind terminate(cleanup)]; + } + +- bb16: { +- StorageDead(_9); ++ bb16 (cleanup): { ++ StorageDead(_12); ++ StorageDead(_10); + goto -> bb17; + } + +- bb17: { +- StorageDead(_15); +- StorageDead(_11); +- StorageDead(_8); +- goto -> bb21; ++ bb17 (cleanup): { ++ StorageDead(_9); ++ goto -> bb18; + } + +- bb18: { +- goto -> bb19; ++ bb18 (cleanup): { ++ StorageDead(_15); ++ goto -> bb20; + } + +- bb19: { +- StorageDead(_4); ++ bb19 (cleanup): { ++ StorageDead(_13); ++ StorageDead(_12); ++ StorageDead(_10); ++ StorageDead(_9); + goto -> bb20; + } + +- bb20: { +- StorageDead(_3); +- goto -> bb21; ++ bb20 (cleanup): { ++ StorageDead(_11); ++ StorageDead(_8); ++ goto -> bb26; + } + +- bb21: { +- drop(_2) -> [return: bb22, unwind: bb38]; ++ bb21 (cleanup): { ++ StorageDead(_7); ++ drop(_5) -> [return: bb23, unwind terminate(cleanup)]; + } + +- bb22: { +- drop(_1) -> [return: bb23, unwind: bb37]; ++ bb22 (cleanup): { ++ StorageDead(_6); ++ goto -> bb23; + } + +- bb23: { +- coroutine_drop; ++ bb23 (cleanup): { ++ StorageDead(_5); ++ goto -> bb24; + } + + bb24 (cleanup): { +- StorageDead(_14); +- drop(_12) -> [return: bb25, unwind terminate(cleanup)]; ++ StorageDead(_4); ++ goto -> bb25; + } + + bb25 (cleanup): { +- StorageDead(_12); +- StorageDead(_10); ++ StorageDead(_3); + goto -> bb26; + } + + bb26 (cleanup): { +- StorageDead(_9); +- goto -> bb27; ++ drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb27, unwind terminate(cleanup)]; + } + + bb27 (cleanup): { +- StorageDead(_15); +- goto -> bb29; ++ goto -> bb28; + } + + bb28 (cleanup): { +- StorageDead(_13); +- StorageDead(_12); +- StorageDead(_10); +- StorageDead(_9); +- goto -> bb29; ++ goto -> bb30; + } + +- bb29 (cleanup): { +- StorageDead(_11); +- StorageDead(_8); +- goto -> bb35; ++ bb29: { ++ goto -> bb14; + } + + bb30 (cleanup): { +- StorageDead(_7); +- drop(_5) -> [return: bb32, unwind terminate(cleanup)]; ++ discriminant((*_18)) = 2; ++ resume; + } + +- bb31 (cleanup): { +- StorageDead(_6); +- goto -> bb32; ++ bb31: { ++ StorageLive(_3); ++ StorageLive(_4); ++ _3 = move _2; ++ goto -> bb4; + } + +- bb32 (cleanup): { +- StorageDead(_5); +- goto -> bb33; ++ bb32: { ++ StorageLive(_8); ++ StorageLive(_9); ++ StorageLive(_11); ++ StorageLive(_15); ++ _8 = move _2; ++ goto -> bb10; + } + +- bb33 (cleanup): { +- StorageDead(_4); +- goto -> bb34; ++ bb33: { ++ assert(const false, "coroutine resumed after panicking") -> [success: bb33, unwind continue]; + } + +- bb34 (cleanup): { +- StorageDead(_3); +- goto -> bb35; ++ bb34: { ++ assert(const false, "coroutine resumed after completion") -> [success: bb34, unwind continue]; + } + +- bb35 (cleanup): { +- drop(_2) -> [return: bb36, unwind terminate(cleanup)]; ++ bb35: { ++ unreachable; + } + +- bb36 (cleanup): { +- drop(_1) -> [return: bb37, unwind terminate(cleanup)]; +- } +- +- bb37 (cleanup): { +- resume; +- } +- +- bb38 (cleanup): { +- drop(_1) -> [return: bb37, unwind terminate(cleanup)]; ++ bb36: { ++ (((*_18) as variant#4).0: std::string::String) = move _2; ++ StorageLive(_3); ++ StorageLive(_4); ++ StorageLive(_5); ++ StorageLive(_6); ++ _6 = &(((*_18) as variant#4).0: std::string::String); ++ _5 = ::clone(move _6) -> [return: bb1, unwind: bb22]; + } + } + + ALLOC0 (size: 6, align: 1) { + 73 65 63 6f 6e 64 │ second + } + + ALLOC1 (size: 5, align: 1) { + 66 69 72 73 74 │ first + } + diff --git a/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir deleted file mode 100644 index 1abfe986f6867..0000000000000 --- a/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.after.mir +++ /dev/null @@ -1,264 +0,0 @@ -// MIR for `main::{closure#1}` after StateTransform - -fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { - coroutine layout { - field _s0: String; - variant_fields = { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - Suspend0 (3): [_s0], - Suspend1 (4): [_s0], - } - storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} - } - debug arg => (((*_18) as variant#4).0: std::string::String); - coroutine debug arg => _s0; - let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; - let _3: std::string::String; - let mut _4: (&str, std::string::String, &std::panic::Location<'_>); - let mut _5: std::string::String; - let mut _6: &std::string::String; - let mut _7: &std::panic::Location<'_>; - let _8: std::string::String; - let mut _9: (&str, std::string::String, &std::panic::Location<'_>); - let mut _10: &str; - let _11: &str; - let mut _12: std::string::String; - let mut _13: &std::string::String; - let mut _14: &std::panic::Location<'_>; - let _15: &std::panic::Location<'_>; - let mut _16: (); - let mut _17: u32; - let mut _18: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}; - - bb0: { - _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}); - _17 = discriminant((*_18)); - switchInt(move _17) -> [0: bb1, 1: bb35, 2: bb34, 3: bb32, 4: bb33, otherwise: bb36]; - } - - bb1: { - (((*_18) as variant#4).0: std::string::String) = move _2; - StorageLive(_3); - StorageLive(_4); - StorageLive(_5); - StorageLive(_6); - _6 = &(((*_18) as variant#4).0: std::string::String); - _5 = ::clone(move _6) -> [return: bb2, unwind: bb23]; - } - - bb2: { - StorageDead(_6); - StorageLive(_7); - _7 = Location::<'_>::caller() -> [return: bb3, unwind: bb22]; - } - - bb3: { - _4 = (const "first", move _5, move _7); - StorageDead(_7); - goto -> bb4; - } - - bb4: { - StorageDead(_5); - _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4); - StorageDead(_3); - StorageDead(_4); - discriminant((*_18)) = 3; - return; - } - - bb5: { - goto -> bb6; - } - - bb6: { - StorageDead(_4); - drop(_3) -> [return: bb7, unwind: bb26]; - } - - bb7: { - StorageDead(_3); - StorageLive(_8); - StorageLive(_9); - StorageLive(_10); - StorageLive(_11); - _11 = const "second"; - _10 = &(*_11); - StorageLive(_12); - StorageLive(_13); - _13 = &(((*_18) as variant#4).0: std::string::String); - _12 = ::clone(move _13) -> [return: bb8, unwind: bb20]; - } - - bb8: { - StorageDead(_13); - StorageLive(_14); - StorageLive(_15); - _15 = Location::<'_>::caller() -> [return: bb9, unwind: bb16]; - } - - bb9: { - _14 = &(*_15); - _9 = (move _10, move _12, move _14); - StorageDead(_14); - goto -> bb10; - } - - bb10: { - StorageDead(_12); - StorageDead(_10); - _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _9); - StorageDead(_8); - StorageDead(_9); - StorageDead(_11); - StorageDead(_15); - discriminant((*_18)) = 4; - return; - } - - bb11: { - goto -> bb12; - } - - bb12: { - StorageDead(_9); - drop(_8) -> [return: bb13, unwind: bb19]; - } - - bb13: { - StorageDead(_15); - StorageDead(_11); - StorageDead(_8); - _16 = const (); - drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb14, unwind: bb28]; - } - - bb14: { - goto -> bb30; - } - - bb15: { - _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16); - discriminant((*_18)) = 1; - return; - } - - bb16 (cleanup): { - StorageDead(_14); - drop(_12) -> [return: bb17, unwind terminate(cleanup)]; - } - - bb17 (cleanup): { - StorageDead(_12); - StorageDead(_10); - goto -> bb18; - } - - bb18 (cleanup): { - StorageDead(_9); - goto -> bb19; - } - - bb19 (cleanup): { - StorageDead(_15); - goto -> bb21; - } - - bb20 (cleanup): { - StorageDead(_13); - StorageDead(_12); - StorageDead(_10); - StorageDead(_9); - goto -> bb21; - } - - bb21 (cleanup): { - StorageDead(_11); - StorageDead(_8); - goto -> bb27; - } - - bb22 (cleanup): { - StorageDead(_7); - drop(_5) -> [return: bb24, unwind terminate(cleanup)]; - } - - bb23 (cleanup): { - StorageDead(_6); - goto -> bb24; - } - - bb24 (cleanup): { - StorageDead(_5); - goto -> bb25; - } - - bb25 (cleanup): { - StorageDead(_4); - goto -> bb26; - } - - bb26 (cleanup): { - StorageDead(_3); - goto -> bb27; - } - - bb27 (cleanup): { - drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb28, unwind terminate(cleanup)]; - } - - bb28 (cleanup): { - goto -> bb29; - } - - bb29 (cleanup): { - goto -> bb31; - } - - bb30: { - goto -> bb15; - } - - bb31 (cleanup): { - discriminant((*_18)) = 2; - resume; - } - - bb32: { - StorageLive(_3); - StorageLive(_4); - _3 = move _2; - goto -> bb5; - } - - bb33: { - StorageLive(_8); - StorageLive(_9); - StorageLive(_11); - StorageLive(_15); - _8 = move _2; - goto -> bb11; - } - - bb34: { - assert(const false, "coroutine resumed after panicking") -> [success: bb34, unwind continue]; - } - - bb35: { - assert(const false, "coroutine resumed after completion") -> [success: bb35, unwind continue]; - } - - bb36: { - unreachable; - } -} - -ALLOC0 (size: 6, align: 1) { - 73 65 63 6f 6e 64 │ second -} - -ALLOC1 (size: 5, align: 1) { - 66 69 72 73 74 │ first -} diff --git a/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.diff b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.diff new file mode 100644 index 0000000000000..97c45da8a18f1 --- /dev/null +++ b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.diff @@ -0,0 +1,353 @@ +- // MIR for `main::{closure#1}` before StateTransform ++ // MIR for `main::{closure#1}` after StateTransform + +- fn main::{closure#1}(_1: {coroutine@$DIR/coroutine.rs:26:5: 26:18}, _2: String) -> () +- yields (&str, String, &Location<'_>) +- { +- debug arg => _2; +- let mut _0: (); ++ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { ++ coroutine layout { ++ field _s0: String; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0], ++ Suspend1 (4): [_s0], ++ } ++ storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} ++ } ++ debug arg => (((*_18) as variant#4).0: std::string::String); ++ coroutine debug arg => _s0; ++ let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; + let _3: std::string::String; + let mut _4: (&str, std::string::String, &std::panic::Location<'_>); + let mut _5: std::string::String; + let mut _6: &std::string::String; + let mut _7: &std::panic::Location<'_>; + let _8: std::string::String; + let mut _9: (&str, std::string::String, &std::panic::Location<'_>); + let mut _10: &str; + let _11: &str; + let mut _12: std::string::String; + let mut _13: &std::string::String; + let mut _14: &std::panic::Location<'_>; + let _15: &std::panic::Location<'_>; ++ let mut _16: (); ++ let mut _17: u32; ++ let mut _18: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}; + + bb0: { +- StorageLive(_3); +- StorageLive(_4); +- StorageLive(_5); +- StorageLive(_6); +- _6 = &_2; +- _5 = ::clone(move _6) -> [return: bb1, unwind: bb31]; ++ _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}); ++ _17 = discriminant((*_18)); ++ switchInt(move _17) -> [0: bb36, 1: bb34, 2: bb33, 3: bb31, 4: bb32, otherwise: bb35]; + } + + bb1: { + StorageDead(_6); + StorageLive(_7); +- _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb30]; ++ _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb21]; + } + + bb2: { + _4 = (const "first", move _5, move _7); + StorageDead(_7); + goto -> bb3; + } + + bb3: { + StorageDead(_5); +- _3 = yield(move _4) -> [resume: bb4, drop: bb18]; ++ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4); ++ StorageDead(_3); ++ StorageDead(_4); ++ discriminant((*_18)) = 3; ++ return; + } + + bb4: { + goto -> bb5; + } + + bb5: { + StorageDead(_4); +- drop(_3) -> [return: bb6, unwind: bb34]; ++ drop(_3) -> [return: bb6, unwind: bb25]; + } + + bb6: { + StorageDead(_3); + StorageLive(_8); + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + _11 = const "second"; + _10 = &(*_11); + StorageLive(_12); + StorageLive(_13); +- _13 = &_2; +- _12 = ::clone(move _13) -> [return: bb7, unwind: bb28]; ++ _13 = &(((*_18) as variant#4).0: std::string::String); ++ _12 = ::clone(move _13) -> [return: bb7, unwind: bb19]; + } + + bb7: { + StorageDead(_13); + StorageLive(_14); + StorageLive(_15); +- _15 = Location::<'_>::caller() -> [return: bb8, unwind: bb24]; ++ _15 = Location::<'_>::caller() -> [return: bb8, unwind: bb15]; + } + + bb8: { + _14 = &(*_15); + _9 = (move _10, move _12, move _14); + StorageDead(_14); + goto -> bb9; + } + + bb9: { + StorageDead(_12); + StorageDead(_10); +- _8 = yield(move _9) -> [resume: bb10, drop: bb15]; ++ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _9); ++ StorageDead(_8); ++ StorageDead(_9); ++ StorageDead(_11); ++ StorageDead(_15); ++ discriminant((*_18)) = 4; ++ return; + } + + bb10: { + goto -> bb11; + } + + bb11: { + StorageDead(_9); +- drop(_8) -> [return: bb12, unwind: bb27]; ++ drop(_8) -> [return: bb12, unwind: bb18]; + } + + bb12: { + StorageDead(_15); + StorageDead(_11); + StorageDead(_8); +- _0 = const (); +- drop(_2) -> [return: bb13, unwind: bb36]; ++ _16 = const (); ++ drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb13, unwind: bb27]; + } + + bb13: { +- drop(_1) -> [return: bb14, unwind: bb37]; ++ goto -> bb29; + } + + bb14: { ++ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16); ++ discriminant((*_18)) = 1; + return; + } + +- bb15: { +- goto -> bb16; ++ bb15 (cleanup): { ++ StorageDead(_14); ++ drop(_12) -> [return: bb16, unwind terminate(cleanup)]; + } + +- bb16: { +- StorageDead(_9); ++ bb16 (cleanup): { ++ StorageDead(_12); ++ StorageDead(_10); + goto -> bb17; + } + +- bb17: { +- StorageDead(_15); +- StorageDead(_11); +- StorageDead(_8); +- goto -> bb21; ++ bb17 (cleanup): { ++ StorageDead(_9); ++ goto -> bb18; + } + +- bb18: { +- goto -> bb19; ++ bb18 (cleanup): { ++ StorageDead(_15); ++ goto -> bb20; + } + +- bb19: { +- StorageDead(_4); ++ bb19 (cleanup): { ++ StorageDead(_13); ++ StorageDead(_12); ++ StorageDead(_10); ++ StorageDead(_9); + goto -> bb20; + } + +- bb20: { +- StorageDead(_3); +- goto -> bb21; ++ bb20 (cleanup): { ++ StorageDead(_11); ++ StorageDead(_8); ++ goto -> bb26; + } + +- bb21: { +- drop(_2) -> [return: bb22, unwind: bb38]; ++ bb21 (cleanup): { ++ StorageDead(_7); ++ drop(_5) -> [return: bb23, unwind terminate(cleanup)]; + } + +- bb22: { +- drop(_1) -> [return: bb23, unwind: bb37]; ++ bb22 (cleanup): { ++ StorageDead(_6); ++ goto -> bb23; + } + +- bb23: { +- coroutine_drop; ++ bb23 (cleanup): { ++ StorageDead(_5); ++ goto -> bb24; + } + + bb24 (cleanup): { +- StorageDead(_14); +- drop(_12) -> [return: bb25, unwind terminate(cleanup)]; ++ StorageDead(_4); ++ goto -> bb25; + } + + bb25 (cleanup): { +- StorageDead(_12); +- StorageDead(_10); ++ StorageDead(_3); + goto -> bb26; + } + + bb26 (cleanup): { +- StorageDead(_9); +- goto -> bb27; ++ drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb27, unwind terminate(cleanup)]; + } + + bb27 (cleanup): { +- StorageDead(_15); +- goto -> bb29; ++ goto -> bb28; + } + + bb28 (cleanup): { +- StorageDead(_13); +- StorageDead(_12); +- StorageDead(_10); +- StorageDead(_9); +- goto -> bb29; ++ goto -> bb30; + } + +- bb29 (cleanup): { +- StorageDead(_11); +- StorageDead(_8); +- goto -> bb35; ++ bb29: { ++ goto -> bb14; + } + + bb30 (cleanup): { +- StorageDead(_7); +- drop(_5) -> [return: bb32, unwind terminate(cleanup)]; ++ discriminant((*_18)) = 2; ++ resume; + } + +- bb31 (cleanup): { +- StorageDead(_6); +- goto -> bb32; ++ bb31: { ++ StorageLive(_3); ++ StorageLive(_4); ++ _3 = move _2; ++ goto -> bb4; + } + +- bb32 (cleanup): { +- StorageDead(_5); +- goto -> bb33; ++ bb32: { ++ StorageLive(_8); ++ StorageLive(_9); ++ StorageLive(_11); ++ StorageLive(_15); ++ _8 = move _2; ++ goto -> bb10; + } + +- bb33 (cleanup): { +- StorageDead(_4); +- goto -> bb34; ++ bb33: { ++ assert(const false, "coroutine resumed after panicking") -> [success: bb33, unwind continue]; + } + +- bb34 (cleanup): { +- StorageDead(_3); +- goto -> bb35; ++ bb34: { ++ assert(const false, "coroutine resumed after completion") -> [success: bb34, unwind continue]; + } + +- bb35 (cleanup): { +- drop(_2) -> [return: bb36, unwind terminate(cleanup)]; ++ bb35: { ++ unreachable; + } + +- bb36 (cleanup): { +- drop(_1) -> [return: bb37, unwind terminate(cleanup)]; +- } +- +- bb37 (cleanup): { +- resume; +- } +- +- bb38 (cleanup): { +- drop(_1) -> [return: bb37, unwind terminate(cleanup)]; ++ bb36: { ++ (((*_18) as variant#4).0: std::string::String) = move _2; ++ StorageLive(_3); ++ StorageLive(_4); ++ StorageLive(_5); ++ StorageLive(_6); ++ _6 = &(((*_18) as variant#4).0: std::string::String); ++ _5 = ::clone(move _6) -> [return: bb1, unwind: bb22]; + } + } + + ALLOC0 (size: 6, align: 1) { + 73 65 63 6f 6e 64 │ second + } + + ALLOC1 (size: 5, align: 1) { + 66 69 72 73 74 │ first + } + diff --git a/tests/mir-opt/coroutine/coroutine.rs b/tests/mir-opt/coroutine/coroutine.rs index 41fdbee119e14..15d3cbb7c99f4 100644 --- a/tests/mir-opt/coroutine/coroutine.rs +++ b/tests/mir-opt/coroutine/coroutine.rs @@ -12,8 +12,8 @@ use std::ops::{Coroutine, CoroutineState}; use std::panic::Location; use std::pin::Pin; -// EMIT_MIR coroutine.main-{closure#0}.StateTransform.after.mir -// EMIT_MIR coroutine.main-{closure#1}.StateTransform.after.mir +// EMIT_MIR coroutine.main-{closure#0}.StateTransform.diff +// EMIT_MIR coroutine.main-{closure#1}.StateTransform.diff fn main() { let simple = #[coroutine] |arg: String| { diff --git a/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir deleted file mode 100644 index 4731aed335d9f..0000000000000 --- a/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir +++ /dev/null @@ -1,83 +0,0 @@ -// MIR for `main::{closure#0}` before StateTransform - -fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}, _2: ()) -> () -yields () - { - let mut _0: (); - let _3: Foo; - let _5: (); - let mut _6: (); - let _7: (); - let mut _8: Foo; - let _9: (); - let mut _10: Bar; - scope 1 { - debug a => _3; - let _4: Bar; - scope 2 { - debug b => _4; - } - } - - bb0: { - StorageLive(_3); - _3 = Foo(const 5_i32); - StorageLive(_4); - _4 = Bar(const 6_i32); - StorageLive(_5); - StorageLive(_6); - _6 = (); - _5 = yield(move _6) -> [resume: bb1, drop: bb6]; - } - - bb1: { - StorageDead(_6); - StorageDead(_5); - StorageLive(_7); - StorageLive(_8); - _8 = move _3; - _7 = take::(move _8) -> [return: bb2, unwind unreachable]; - } - - bb2: { - StorageDead(_8); - StorageDead(_7); - StorageLive(_9); - StorageLive(_10); - _10 = move _4; - _9 = take::(move _10) -> [return: bb3, unwind unreachable]; - } - - bb3: { - StorageDead(_10); - StorageDead(_9); - _0 = const (); - StorageDead(_4); - goto -> bb4; - } - - bb4: { - StorageDead(_3); - drop(_1) -> [return: bb5, unwind unreachable]; - } - - bb5: { - return; - } - - bb6: { - StorageDead(_6); - StorageDead(_5); - StorageDead(_4); - drop(_3) -> [return: bb7, unwind unreachable]; - } - - bb7: { - StorageDead(_3); - drop(_1) -> [return: bb8, unwind unreachable]; - } - - bb8: { - coroutine_drop; - } -} diff --git a/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir deleted file mode 100644 index 14e1782b86016..0000000000000 --- a/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir +++ /dev/null @@ -1,118 +0,0 @@ -// MIR for `main::{closure#0}` before StateTransform - -fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}, _2: ()) -> () -yields () - { - let mut _0: (); - let _3: Foo; - let _5: (); - let mut _6: (); - let _7: (); - let mut _8: Foo; - let _9: (); - let mut _10: Bar; - scope 1 { - debug a => _3; - let _4: Bar; - scope 2 { - debug b => _4; - } - } - - bb0: { - StorageLive(_3); - _3 = Foo(const 5_i32); - StorageLive(_4); - _4 = Bar(const 6_i32); - StorageLive(_5); - StorageLive(_6); - _6 = (); - _5 = yield(move _6) -> [resume: bb1, drop: bb6]; - } - - bb1: { - StorageDead(_6); - StorageDead(_5); - StorageLive(_7); - StorageLive(_8); - _8 = move _3; - _7 = take::(move _8) -> [return: bb2, unwind: bb10]; - } - - bb2: { - StorageDead(_8); - StorageDead(_7); - StorageLive(_9); - StorageLive(_10); - _10 = move _4; - _9 = take::(move _10) -> [return: bb3, unwind: bb9]; - } - - bb3: { - StorageDead(_10); - StorageDead(_9); - _0 = const (); - StorageDead(_4); - goto -> bb4; - } - - bb4: { - StorageDead(_3); - drop(_1) -> [return: bb5, unwind: bb14]; - } - - bb5: { - return; - } - - bb6: { - StorageDead(_6); - StorageDead(_5); - StorageDead(_4); - drop(_3) -> [return: bb7, unwind: bb15]; - } - - bb7: { - StorageDead(_3); - drop(_1) -> [return: bb8, unwind: bb14]; - } - - bb8: { - coroutine_drop; - } - - bb9 (cleanup): { - StorageDead(_10); - StorageDead(_9); - goto -> bb12; - } - - bb10 (cleanup): { - goto -> bb11; - } - - bb11 (cleanup): { - StorageDead(_8); - StorageDead(_7); - goto -> bb12; - } - - bb12 (cleanup): { - StorageDead(_4); - goto -> bb13; - } - - bb13 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb14, unwind terminate(cleanup)]; - } - - bb14 (cleanup): { - resume; - } - - bb15 (cleanup): { - StorageDead(_3); - drop(_1) -> [return: bb14, unwind terminate(cleanup)]; - } -} diff --git a/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.panic-abort.diff b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.panic-abort.diff new file mode 100644 index 0000000000000..9e4fb0cb64788 --- /dev/null +++ b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.panic-abort.diff @@ -0,0 +1,141 @@ +- // MIR for `main::{closure#0}` before StateTransform ++ // MIR for `main::{closure#0}` after StateTransform + +- fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}, _2: ()) -> () +- yields () +- { +- let mut _0: (); ++ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}>, _2: ()) -> CoroutineState<(), ()> { ++ coroutine layout { ++ field _s0: Foo; ++ field _s1: Bar; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1], ++ } ++ storage_conflicts = BitMatrix(2x2) {(_s0, _s0), (_s0, _s1), (_s1, _s0), (_s1, _s1)} ++ } ++ coroutine debug a => _s0; ++ let mut _0: std::ops::CoroutineState<(), ()>; + let _3: Foo; + let _5: (); + let mut _6: (); + let _7: (); + let mut _8: Foo; + let _9: (); + let mut _10: Bar; ++ let mut _11: (); ++ let mut _12: u32; ++ let mut _13: &mut {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}; + scope 1 { +- debug a => _3; ++ debug a => (((*_13) as variant#3).0: Foo); ++ coroutine debug b => _s1; + let _4: Bar; + scope 2 { +- debug b => _4; ++ debug b => (((*_13) as variant#3).1: Bar); + } + } + + bb0: { +- StorageLive(_3); +- _3 = Foo(const 5_i32); +- StorageLive(_4); +- _4 = Bar(const 6_i32); +- StorageLive(_5); +- StorageLive(_6); +- _6 = (); +- _5 = yield(move _6) -> [resume: bb1, drop: bb6]; ++ _13 = copy (_1.0: &mut {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}); ++ _12 = discriminant((*_13)); ++ switchInt(move _12) -> [0: bb10, 1: bb8, 3: bb7, otherwise: bb9]; + } + + bb1: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_7); + StorageLive(_8); +- _8 = move _3; ++ _8 = move (((*_13) as variant#3).0: Foo); + _7 = take::(move _8) -> [return: bb2, unwind unreachable]; + } + + bb2: { + StorageDead(_8); + StorageDead(_7); + StorageLive(_9); + StorageLive(_10); +- _10 = move _4; ++ _10 = move (((*_13) as variant#3).1: Bar); + _9 = take::(move _10) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_10); + StorageDead(_9); +- _0 = const (); +- StorageDead(_4); ++ _11 = const (); ++ nop; + goto -> bb4; + } + + bb4: { +- StorageDead(_3); +- drop(_1) -> [return: bb5, unwind unreachable]; ++ nop; ++ goto -> bb6; + } + + bb5: { ++ _0 = CoroutineState::<(), ()>::Complete(move _11); ++ discriminant((*_13)) = 1; + return; + } + + bb6: { +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- drop(_3) -> [return: bb7, unwind unreachable]; ++ goto -> bb5; + } + + bb7: { +- StorageDead(_3); +- drop(_1) -> [return: bb8, unwind unreachable]; ++ StorageLive(_5); ++ StorageLive(_6); ++ _5 = move _2; ++ goto -> bb1; + } + + bb8: { +- coroutine_drop; ++ assert(const false, "coroutine resumed after completion") -> [success: bb8, unwind unreachable]; ++ } ++ ++ bb9: { ++ unreachable; ++ } ++ ++ bb10: { ++ nop; ++ (((*_13) as variant#3).0: Foo) = Foo(const 5_i32); ++ nop; ++ (((*_13) as variant#3).1: Bar) = Bar(const 6_i32); ++ StorageLive(_5); ++ StorageLive(_6); ++ _6 = (); ++ _0 = CoroutineState::<(), ()>::Yielded(move _6); ++ StorageDead(_5); ++ StorageDead(_6); ++ discriminant((*_13)) = 3; ++ return; + } + } + diff --git a/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.panic-unwind.diff b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.panic-unwind.diff new file mode 100644 index 0000000000000..fa89df127094a --- /dev/null +++ b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.panic-unwind.diff @@ -0,0 +1,201 @@ +- // MIR for `main::{closure#0}` before StateTransform ++ // MIR for `main::{closure#0}` after StateTransform + +- fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}, _2: ()) -> () +- yields () +- { +- let mut _0: (); ++ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}>, _2: ()) -> CoroutineState<(), ()> { ++ coroutine layout { ++ field _s0: Foo; ++ field _s1: Bar; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0, _s1], ++ } ++ storage_conflicts = BitMatrix(2x2) {(_s0, _s0), (_s0, _s1), (_s1, _s0), (_s1, _s1)} ++ } ++ coroutine debug a => _s0; ++ let mut _0: std::ops::CoroutineState<(), ()>; + let _3: Foo; + let _5: (); + let mut _6: (); + let _7: (); + let mut _8: Foo; + let _9: (); + let mut _10: Bar; ++ let mut _11: (); ++ let mut _12: u32; ++ let mut _13: &mut {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}; + scope 1 { +- debug a => _3; ++ debug a => (((*_13) as variant#3).0: Foo); ++ coroutine debug b => _s1; + let _4: Bar; + scope 2 { +- debug b => _4; ++ debug b => (((*_13) as variant#3).1: Bar); + } + } + + bb0: { +- StorageLive(_3); +- _3 = Foo(const 5_i32); +- StorageLive(_4); +- _4 = Bar(const 6_i32); +- StorageLive(_5); +- StorageLive(_6); +- _6 = (); +- _5 = yield(move _6) -> [resume: bb1, drop: bb6]; ++ _13 = copy (_1.0: &mut {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}); ++ _12 = discriminant((*_13)); ++ switchInt(move _12) -> [0: bb18, 1: bb16, 2: bb15, 3: bb14, otherwise: bb17]; + } + + bb1: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_7); + StorageLive(_8); +- _8 = move _3; +- _7 = take::(move _8) -> [return: bb2, unwind: bb10]; ++ _8 = move (((*_13) as variant#3).0: Foo); ++ _7 = take::(move _8) -> [return: bb2, unwind: bb7]; + } + + bb2: { + StorageDead(_8); + StorageDead(_7); + StorageLive(_9); + StorageLive(_10); +- _10 = move _4; +- _9 = take::(move _10) -> [return: bb3, unwind: bb9]; ++ _10 = move (((*_13) as variant#3).1: Bar); ++ _9 = take::(move _10) -> [return: bb3, unwind: bb6]; + } + + bb3: { + StorageDead(_10); + StorageDead(_9); +- _0 = const (); +- StorageDead(_4); ++ _11 = const (); ++ nop; + goto -> bb4; + } + + bb4: { +- StorageDead(_3); +- drop(_1) -> [return: bb5, unwind: bb14]; ++ nop; ++ goto -> bb12; + } + + bb5: { ++ _0 = CoroutineState::<(), ()>::Complete(move _11); ++ discriminant((*_13)) = 1; + return; + } + +- bb6: { +- StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- drop(_3) -> [return: bb7, unwind: bb15]; ++ bb6 (cleanup): { ++ StorageDead(_10); ++ StorageDead(_9); ++ goto -> bb9; + } + +- bb7: { +- StorageDead(_3); +- drop(_1) -> [return: bb8, unwind: bb14]; ++ bb7 (cleanup): { ++ goto -> bb8; + } + +- bb8: { +- coroutine_drop; ++ bb8 (cleanup): { ++ StorageDead(_8); ++ StorageDead(_7); ++ goto -> bb9; + } + + bb9 (cleanup): { +- StorageDead(_10); +- StorageDead(_9); +- goto -> bb12; ++ nop; ++ goto -> bb10; + } + + bb10 (cleanup): { ++ nop; + goto -> bb11; + } + + bb11 (cleanup): { +- StorageDead(_8); +- StorageDead(_7); +- goto -> bb12; ++ goto -> bb13; + } + +- bb12 (cleanup): { +- StorageDead(_4); +- goto -> bb13; ++ bb12: { ++ goto -> bb5; + } + + bb13 (cleanup): { +- StorageDead(_3); +- drop(_1) -> [return: bb14, unwind terminate(cleanup)]; ++ discriminant((*_13)) = 2; ++ resume; + } + +- bb14 (cleanup): { +- resume; ++ bb14: { ++ StorageLive(_5); ++ StorageLive(_6); ++ _5 = move _2; ++ goto -> bb1; + } + +- bb15 (cleanup): { +- StorageDead(_3); +- drop(_1) -> [return: bb14, unwind terminate(cleanup)]; ++ bb15: { ++ assert(const false, "coroutine resumed after panicking") -> [success: bb15, unwind continue]; ++ } ++ ++ bb16: { ++ assert(const false, "coroutine resumed after completion") -> [success: bb16, unwind continue]; ++ } ++ ++ bb17: { ++ unreachable; ++ } ++ ++ bb18: { ++ nop; ++ (((*_13) as variant#3).0: Foo) = Foo(const 5_i32); ++ nop; ++ (((*_13) as variant#3).1: Bar) = Bar(const 6_i32); ++ StorageLive(_5); ++ StorageLive(_6); ++ _6 = (); ++ _0 = CoroutineState::<(), ()>::Yielded(move _6); ++ StorageDead(_5); ++ StorageDead(_6); ++ discriminant((*_13)) = 3; ++ return; + } + } + diff --git a/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.rs b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.rs index 0537aedcf230b..1267f7248bc17 100644 --- a/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.rs +++ b/tests/mir-opt/coroutine/coroutine_storage_dead_unwind.rs @@ -18,7 +18,7 @@ struct Bar(i32); fn take(_x: T) {} -// EMIT_MIR coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir +// EMIT_MIR coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.diff fn main() { let _gen = #[coroutine] || { diff --git a/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.StateTransform.diff new file mode 100644 index 0000000000000..b84e55cac4616 --- /dev/null +++ b/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.StateTransform.diff @@ -0,0 +1,98 @@ +- // MIR for `main::{closure#0}` before StateTransform ++ // MIR for `main::{closure#0}` after StateTransform + +- fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_tiny.rs:20:5: 20:13}, _2: u8) -> () +- yields () +- { ++ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:20:5: 20:13}>, _2: u8) -> CoroutineState<(), ()> { ++ coroutine layout { ++ field _s0: HasDrop; ++ variant_fields = { ++ Unresumed(0): [], ++ Returned (1): [], ++ Panicked (2): [], ++ Suspend0 (3): [_s0], ++ } ++ storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} ++ } + debug _x => _2; +- let mut _0: (); ++ coroutine debug _d => _s0; ++ let mut _0: std::ops::CoroutineState<(), ()>; + let _3: HasDrop; + let mut _4: !; + let mut _5: (); + let _6: u8; + let mut _7: (); + let _8: (); ++ let mut _9: (); ++ let mut _10: u32; ++ let mut _11: &mut {coroutine@$DIR/coroutine_tiny.rs:20:5: 20:13}; + scope 1 { +- debug _d => _3; ++ debug _d => (((*_11) as variant#3).0: HasDrop); + } + + bb0: { +- StorageLive(_3); +- _3 = HasDrop; +- StorageLive(_4); +- goto -> bb1; ++ _11 = copy (_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:20:5: 20:13}); ++ _10 = discriminant((*_11)); ++ switchInt(move _10) -> [0: bb6, 3: bb4, otherwise: bb5]; + } + + bb1: { + StorageLive(_6); + StorageLive(_7); + _7 = (); +- _6 = yield(move _7) -> [resume: bb2, drop: bb4]; ++ _0 = CoroutineState::<(), ()>::Yielded(move _7); ++ StorageDead(_4); ++ StorageDead(_6); ++ StorageDead(_7); ++ discriminant((*_11)) = 3; ++ return; + } + + bb2: { + StorageDead(_7); + StorageDead(_6); + StorageLive(_8); + _8 = callee() -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_8); + _5 = const (); + goto -> bb1; + } + + bb4: { +- StorageDead(_7); +- StorageDead(_6); +- StorageDead(_4); +- drop(_3) -> [return: bb5, unwind unreachable]; ++ StorageLive(_4); ++ StorageLive(_6); ++ StorageLive(_7); ++ _6 = move _2; ++ goto -> bb2; + } + + bb5: { +- StorageDead(_3); +- drop(_1) -> [return: bb6, unwind unreachable]; ++ unreachable; + } + + bb6: { +- coroutine_drop; ++ nop; ++ (((*_11) as variant#3).0: HasDrop) = HasDrop; ++ StorageLive(_4); ++ goto -> bb1; + } + } + diff --git a/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir deleted file mode 100644 index e5667215d54fd..0000000000000 --- a/tests/mir-opt/coroutine/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir +++ /dev/null @@ -1,79 +0,0 @@ -// MIR for `main::{closure#0}` 0 coroutine_resume - -fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}>, _2: u8) -> CoroutineState<(), ()> { - coroutine layout { - field _s0: HasDrop; - variant_fields = { - Unresumed(0): [], - Returned (1): [], - Panicked (2): [], - Suspend0 (3): [_s0], - } - storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} - } - debug _x => _2; - coroutine debug _d => _s0; - let mut _0: std::ops::CoroutineState<(), ()>; - let _3: HasDrop; - let mut _4: !; - let mut _5: (); - let _6: u8; - let mut _7: (); - let _8: (); - let mut _9: (); - let mut _10: u32; - let mut _11: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}; - scope 1 { - debug _d => (((*_11) as variant#3).0: HasDrop); - } - - bb0: { - _11 = copy (_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}); - _10 = discriminant((*_11)); - switchInt(move _10) -> [0: bb1, 3: bb5, otherwise: bb6]; - } - - bb1: { - nop; - (((*_11) as variant#3).0: HasDrop) = HasDrop; - StorageLive(_4); - goto -> bb2; - } - - bb2: { - StorageLive(_6); - StorageLive(_7); - _7 = (); - _0 = CoroutineState::<(), ()>::Yielded(move _7); - StorageDead(_4); - StorageDead(_6); - StorageDead(_7); - discriminant((*_11)) = 3; - return; - } - - bb3: { - StorageDead(_7); - StorageDead(_6); - StorageLive(_8); - _8 = callee() -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_8); - _5 = const (); - goto -> bb2; - } - - bb5: { - StorageLive(_4); - StorageLive(_6); - StorageLive(_7); - _6 = move _2; - goto -> bb3; - } - - bb6: { - unreachable; - } -} diff --git a/tests/mir-opt/coroutine/coroutine_tiny.rs b/tests/mir-opt/coroutine/coroutine_tiny.rs index b92628aebf96a..2f3a7744bd603 100644 --- a/tests/mir-opt/coroutine/coroutine_tiny.rs +++ b/tests/mir-opt/coroutine/coroutine_tiny.rs @@ -1,4 +1,3 @@ -//@ skip-filecheck //! Tests that coroutines that cannot return or unwind don't have unnecessary //! panic branches. @@ -15,7 +14,7 @@ impl Drop for HasDrop { fn callee() {} -// EMIT_MIR coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir +// EMIT_MIR coroutine_tiny.main-{closure#0}.StateTransform.diff fn main() { let _gen = #[coroutine] |_x: u8| { @@ -26,3 +25,6 @@ fn main() { } }; } + +// CHECK-NOT: panic +// CHECK-NOT: cleanup diff --git a/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index f8ef70bd6c9ce..617f2ad463ed3 100644 --- a/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff @@ -47,42 +47,42 @@ + let _26: (); + scope 9 { + } -+ scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { ++ scope 11 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { + } -+ scope 13 (inlined as Future>::poll) { -+ let mut _34: (); -+ let mut _35: std::option::Option<()>; -+ let mut _36: &mut std::option::Option<()>; -+ let mut _37: &mut std::future::Ready<()>; -+ let mut _38: &mut std::pin::Pin<&mut std::future::Ready<()>>; -+ scope 14 (inlined > as DerefMut>::deref_mut) { -+ let mut _39: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>; -+ let mut _40: *mut std::pin::Pin<&mut std::future::Ready<()>>; -+ scope 15 (inlined > as pin::helper::PinDerefMutHelper>::deref_mut) { -+ let mut _41: &mut &mut std::future::Ready<()>; -+ scope 16 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { ++ scope 12 (inlined as Future>::poll) { ++ let mut _33: (); ++ let mut _34: std::option::Option<()>; ++ let mut _35: &mut std::option::Option<()>; ++ let mut _36: &mut std::future::Ready<()>; ++ let mut _37: &mut std::pin::Pin<&mut std::future::Ready<()>>; ++ scope 13 (inlined > as DerefMut>::deref_mut) { ++ let mut _38: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>; ++ let mut _39: *mut std::pin::Pin<&mut std::future::Ready<()>>; ++ scope 14 (inlined > as pin::helper::PinDerefMutHelper>::deref_mut) { ++ let mut _40: &mut &mut std::future::Ready<()>; ++ scope 15 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { + } + } + } -+ scope 17 (inlined Option::<()>::take) { -+ let mut _42: std::option::Option<()>; -+ scope 18 (inlined std::mem::replace::>) { -+ scope 19 { ++ scope 16 (inlined Option::<()>::take) { ++ let mut _41: std::option::Option<()>; ++ scope 17 (inlined std::mem::replace::>) { ++ scope 18 { + } + } + } -+ scope 20 (inlined #[track_caller] Option::<()>::expect) { -+ let mut _43: isize; -+ let mut _44: !; -+ scope 21 { ++ scope 19 (inlined #[track_caller] Option::<()>::expect) { ++ let mut _42: isize; ++ let mut _43: !; ++ scope 20 { + } + } + } + } -+ scope 10 (inlined ready::<()>) { -+ let mut _33: std::option::Option<()>; ++ scope 10 (inlined as IntoFuture>::into_future) { + } -+ scope 11 (inlined as IntoFuture>::into_future) { ++ scope 21 (inlined ready::<()>) { ++ let mut _44: std::option::Option<()>; + } + } + } @@ -127,7 +127,7 @@ + StorageLive(_32); + _32 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _31 = discriminant((*_32)); -+ switchInt(move _31) -> [0: bb3, 1: bb10, 3: bb9, otherwise: bb5]; ++ switchInt(move _31) -> [0: bb10, 1: bb9, 3: bb8, otherwise: bb4]; } - bb3: { @@ -154,25 +154,6 @@ } + bb3: { -+ (((*_32) as variant#3).0: ActionPermit<'_, T>) = move ((*_32).0: ActionPermit<'_, T>); -+ StorageLive(_12); -+ StorageLive(_13); -+ StorageLive(_14); -+ _14 = (); -+ StorageLive(_33); -+ _33 = Option::<()>::Some(copy _14); -+ _13 = std::future::Ready::<()>(move _33); -+ StorageDead(_33); -+ StorageDead(_14); -+ _12 = move _13; -+ StorageDead(_13); -+ (((*_32) as variant#3).1: std::future::Ready<()>) = move _12; -+ goto -> bb4; -+ } -+ - bb4: { -- StorageDead(_2); -- return; + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); @@ -189,31 +170,33 @@ + _23 = move _24; + _22 = &mut (*_23); + StorageDead(_24); -+ StorageLive(_37); -+ StorageLive(_39); -+ StorageLive(_44); ++ StorageLive(_36); ++ StorageLive(_38); ++ StorageLive(_43); ++ StorageLive(_33); + StorageLive(_34); -+ StorageLive(_35); -+ StorageLive(_40); -+ _40 = &raw mut _19; -+ _39 = copy _40 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr); -+ StorageDead(_40); -+ _37 = no_retag copy ((*_39).0: &mut std::future::Ready<()>); ++ StorageLive(_39); ++ _39 = &raw mut _19; ++ _38 = copy _39 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr); ++ StorageDead(_39); ++ _36 = no_retag copy ((*_38).0: &mut std::future::Ready<()>); ++ StorageLive(_41); ++ _41 = Option::<()>::None; ++ _34 = copy ((*_36).0: std::option::Option<()>); ++ ((*_36).0: std::option::Option<()>) = move _41; ++ StorageDead(_41); + StorageLive(_42); -+ _42 = Option::<()>::None; -+ _35 = copy ((*_37).0: std::option::Option<()>); -+ ((*_37).0: std::option::Option<()>) = move _42; -+ StorageDead(_42); -+ StorageLive(_43); -+ _43 = discriminant(_35); -+ switchInt(move _43) -> [0: bb11, 1: bb12, otherwise: bb5]; - } ++ _42 = discriminant(_34); ++ switchInt(move _42) -> [0: bb11, 1: bb12, otherwise: bb4]; ++ } + -+ bb5: { + bb4: { +- StorageDead(_2); +- return; + unreachable; -+ } + } + -+ bb6: { ++ bb5: { + _17 = const (); + StorageDead(_23); + StorageDead(_21); @@ -230,7 +213,7 @@ + goto -> bb2; + } + -+ bb7: { ++ bb6: { + StorageLive(_26); + _26 = copy ((_18 as Ready).0: ()); + _30 = copy _26; @@ -240,16 +223,16 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable]; ++ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb7, unwind unreachable]; + } + -+ bb8: { ++ bb7: { + _7 = Poll::<()>::Ready(move _30); + discriminant((*_32)) = 1; + goto -> bb2; + } + -+ bb9: { ++ bb8: { + StorageLive(_12); + StorageLive(_28); + StorageLive(_29); @@ -258,30 +241,47 @@ + _9 = move _28; + StorageDead(_28); + _16 = const (); -+ goto -> bb4; ++ goto -> bb3; ++ } ++ ++ bb9: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb9, unwind unreachable]; + } + + bb10: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb10, unwind unreachable]; ++ (((*_32) as variant#3).0: ActionPermit<'_, T>) = move ((*_32).0: ActionPermit<'_, T>); ++ StorageLive(_12); ++ StorageLive(_13); ++ StorageLive(_14); ++ _14 = (); ++ StorageLive(_44); ++ _44 = Option::<()>::Some(copy _14); ++ _13 = std::future::Ready::<()>(move _44); ++ StorageDead(_44); ++ StorageDead(_14); ++ _12 = move _13; ++ StorageDead(_13); ++ (((*_32) as variant#3).1: std::future::Ready<()>) = move _12; ++ goto -> bb3; + } + + bb11: { -+ _44 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; ++ _43 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; + } + + bb12: { -+ _34 = move ((_35 as Some).0: ()); -+ StorageDead(_43); -+ StorageDead(_35); -+ _18 = Poll::<()>::Ready(move _34); ++ _33 = move ((_34 as Some).0: ()); ++ StorageDead(_42); + StorageDead(_34); -+ StorageDead(_44); -+ StorageDead(_39); -+ StorageDead(_37); ++ _18 = Poll::<()>::Ready(move _33); ++ StorageDead(_33); ++ StorageDead(_43); ++ StorageDead(_38); ++ StorageDead(_36); + StorageDead(_22); + StorageDead(_19); + _25 = discriminant(_18); -+ switchInt(move _25) -> [0: bb7, 1: bb6, otherwise: bb5]; ++ switchInt(move _25) -> [0: bb6, 1: bb5, otherwise: bb4]; + } + } + diff --git a/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index 18be10c534ec4..f12462a4d2b34 100644 --- a/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -47,42 +47,42 @@ + let _26: (); + scope 9 { + } -+ scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { ++ scope 11 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { + } -+ scope 13 (inlined as Future>::poll) { -+ let mut _34: (); -+ let mut _35: std::option::Option<()>; -+ let mut _36: &mut std::option::Option<()>; -+ let mut _37: &mut std::future::Ready<()>; -+ let mut _38: &mut std::pin::Pin<&mut std::future::Ready<()>>; -+ scope 14 (inlined > as DerefMut>::deref_mut) { -+ let mut _39: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>; -+ let mut _40: *mut std::pin::Pin<&mut std::future::Ready<()>>; -+ scope 15 (inlined > as pin::helper::PinDerefMutHelper>::deref_mut) { -+ let mut _41: &mut &mut std::future::Ready<()>; -+ scope 16 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { ++ scope 12 (inlined as Future>::poll) { ++ let mut _33: (); ++ let mut _34: std::option::Option<()>; ++ let mut _35: &mut std::option::Option<()>; ++ let mut _36: &mut std::future::Ready<()>; ++ let mut _37: &mut std::pin::Pin<&mut std::future::Ready<()>>; ++ scope 13 (inlined > as DerefMut>::deref_mut) { ++ let mut _38: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>; ++ let mut _39: *mut std::pin::Pin<&mut std::future::Ready<()>>; ++ scope 14 (inlined > as pin::helper::PinDerefMutHelper>::deref_mut) { ++ let mut _40: &mut &mut std::future::Ready<()>; ++ scope 15 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { + } + } + } -+ scope 17 (inlined Option::<()>::take) { -+ let mut _42: std::option::Option<()>; -+ scope 18 (inlined std::mem::replace::>) { -+ scope 19 { ++ scope 16 (inlined Option::<()>::take) { ++ let mut _41: std::option::Option<()>; ++ scope 17 (inlined std::mem::replace::>) { ++ scope 18 { + } + } + } -+ scope 20 (inlined #[track_caller] Option::<()>::expect) { -+ let mut _43: isize; -+ let mut _44: !; -+ scope 21 { ++ scope 19 (inlined #[track_caller] Option::<()>::expect) { ++ let mut _42: isize; ++ let mut _43: !; ++ scope 20 { + } + } + } + } -+ scope 10 (inlined ready::<()>) { -+ let mut _33: std::option::Option<()>; ++ scope 10 (inlined as IntoFuture>::into_future) { + } -+ scope 11 (inlined as IntoFuture>::into_future) { ++ scope 21 (inlined ready::<()>) { ++ let mut _44: std::option::Option<()>; + } + } + } @@ -127,7 +127,7 @@ + StorageLive(_32); + _32 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _31 = discriminant((*_32)); -+ switchInt(move _31) -> [0: bb5, 1: bb15, 2: bb14, 3: bb13, otherwise: bb7]; ++ switchInt(move _31) -> [0: bb15, 1: bb14, 2: bb13, 3: bb12, otherwise: bb6]; } - bb3: { @@ -165,25 +165,6 @@ - StorageDead(_2); - return; + bb5: { -+ (((*_32) as variant#3).0: ActionPermit<'_, T>) = move ((*_32).0: ActionPermit<'_, T>); -+ StorageLive(_12); -+ StorageLive(_13); -+ StorageLive(_14); -+ _14 = (); -+ StorageLive(_33); -+ _33 = Option::<()>::Some(copy _14); -+ _13 = std::future::Ready::<()>(move _33); -+ StorageDead(_33); -+ StorageDead(_14); -+ _12 = move _13; -+ StorageDead(_13); -+ (((*_32) as variant#3).1: std::future::Ready<()>) = move _12; -+ goto -> bb6; - } - -- bb5 (cleanup): { -- drop(_2) -> [return: bb6, unwind terminate(cleanup)]; -+ bb6: { + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); @@ -200,33 +181,35 @@ + _23 = move _24; + _22 = &mut (*_23); + StorageDead(_24); -+ StorageLive(_37); -+ StorageLive(_39); -+ StorageLive(_44); ++ StorageLive(_36); ++ StorageLive(_38); ++ StorageLive(_43); ++ StorageLive(_33); + StorageLive(_34); -+ StorageLive(_35); -+ StorageLive(_40); -+ _40 = &raw mut _19; -+ _39 = copy _40 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr); -+ StorageDead(_40); -+ _37 = no_retag copy ((*_39).0: &mut std::future::Ready<()>); ++ StorageLive(_39); ++ _39 = &raw mut _19; ++ _38 = copy _39 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr); ++ StorageDead(_39); ++ _36 = no_retag copy ((*_38).0: &mut std::future::Ready<()>); ++ StorageLive(_41); ++ _41 = Option::<()>::None; ++ _34 = copy ((*_36).0: std::option::Option<()>); ++ ((*_36).0: std::option::Option<()>) = move _41; ++ StorageDead(_41); + StorageLive(_42); -+ _42 = Option::<()>::None; -+ _35 = copy ((*_37).0: std::option::Option<()>); -+ ((*_37).0: std::option::Option<()>) = move _42; -+ StorageDead(_42); -+ StorageLive(_43); -+ _43 = discriminant(_35); -+ switchInt(move _43) -> [0: bb16, 1: bb17, otherwise: bb7]; ++ _42 = discriminant(_34); ++ switchInt(move _42) -> [0: bb16, 1: bb17, otherwise: bb6]; + } + +- bb5 (cleanup): { +- drop(_2) -> [return: bb6, unwind terminate(cleanup)]; ++ bb6: { ++ unreachable; } - bb6 (cleanup): { - resume; + bb7: { -+ unreachable; - } -+ -+ bb8: { + _17 = const (); + StorageDead(_23); + StorageDead(_21); @@ -241,9 +224,9 @@ + StorageDead(_29); + discriminant((*_32)) = 3; + goto -> bb4; -+ } + } + -+ bb9: { ++ bb8: { + StorageLive(_26); + _26 = copy ((_18 as Ready).0: ()); + _30 = copy _26; @@ -253,16 +236,16 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12]; ++ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb9, unwind: bb11]; + } + -+ bb10: { ++ bb9: { + _7 = Poll::<()>::Ready(move _30); + discriminant((*_32)) = 1; + goto -> bb4; + } + -+ bb11 (cleanup): { ++ bb10 (cleanup): { + StorageDead(_22); + StorageDead(_19); + StorageDead(_23); @@ -270,15 +253,15 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)]; ++ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb11, unwind terminate(cleanup)]; + } + -+ bb12 (cleanup): { ++ bb11 (cleanup): { + discriminant((*_32)) = 2; + goto -> bb2; + } + -+ bb13: { ++ bb12: { + StorageLive(_12); + StorageLive(_28); + StorageLive(_29); @@ -287,34 +270,51 @@ + _9 = move _28; + StorageDead(_28); + _16 = const (); -+ goto -> bb6; ++ goto -> bb5; ++ } ++ ++ bb13: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb13, unwind: bb2]; + } + + bb14: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb14, unwind: bb2]; ++ assert(const false, "`async fn` resumed after completion") -> [success: bb14, unwind: bb2]; + } + + bb15: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb15, unwind: bb2]; ++ (((*_32) as variant#3).0: ActionPermit<'_, T>) = move ((*_32).0: ActionPermit<'_, T>); ++ StorageLive(_12); ++ StorageLive(_13); ++ StorageLive(_14); ++ _14 = (); ++ StorageLive(_44); ++ _44 = Option::<()>::Some(copy _14); ++ _13 = std::future::Ready::<()>(move _44); ++ StorageDead(_44); ++ StorageDead(_14); ++ _12 = move _13; ++ StorageDead(_13); ++ (((*_32) as variant#3).1: std::future::Ready<()>) = move _12; ++ goto -> bb5; + } + + bb16: { -+ _44 = option::expect_failed(const "`Ready` polled after completion") -> bb11; ++ _43 = option::expect_failed(const "`Ready` polled after completion") -> bb10; + } + + bb17: { -+ _34 = move ((_35 as Some).0: ()); -+ StorageDead(_43); -+ StorageDead(_35); -+ _18 = Poll::<()>::Ready(move _34); ++ _33 = move ((_34 as Some).0: ()); ++ StorageDead(_42); + StorageDead(_34); -+ StorageDead(_44); -+ StorageDead(_39); -+ StorageDead(_37); ++ _18 = Poll::<()>::Ready(move _33); ++ StorageDead(_33); ++ StorageDead(_43); ++ StorageDead(_38); ++ StorageDead(_36); + StorageDead(_22); + StorageDead(_19); + _25 = discriminant(_18); -+ switchInt(move _25) -> [0: bb9, 1: bb8, otherwise: bb7]; ++ switchInt(move _25) -> [0: bb8, 1: bb7, otherwise: bb6]; + } + } + diff --git a/tests/ui/force-inlining/deny-async.stderr b/tests/ui/force-inlining/deny-async.stderr index d6516ed875c21..bd24bc694e8ae 100644 --- a/tests/ui/force-inlining/deny-async.stderr +++ b/tests/ui/force-inlining/deny-async.stderr @@ -20,14 +20,6 @@ LL | pub fn callee_justified() { | = note: incompatible due to: #[rustc_no_mir_inline] -error: `callee` could not be inlined into `async_caller::{closure#0}` but is required to be inlined - --> $DIR/deny-async.rs:22:5 - | -LL | callee(); - | ^^^^^^^^ ...`callee` called here - | - = note: could not be inlined due to: #[rustc_no_mir_inline] - error: `callee_justified` could not be inlined into `async_caller::{closure#0}` but is required to be inlined --> $DIR/deny-async.rs:24:5 | @@ -37,5 +29,13 @@ LL | callee_justified(); = note: could not be inlined due to: #[rustc_no_mir_inline] = note: `callee_justified` is required to be inlined to: the test requires it +error: `callee` could not be inlined into `async_caller::{closure#0}` but is required to be inlined + --> $DIR/deny-async.rs:22:5 + | +LL | callee(); + | ^^^^^^^^ ...`callee` called here + | + = note: could not be inlined due to: #[rustc_no_mir_inline] + error: aborting due to 4 previous errors diff --git a/tests/ui/rustc_public-ir-print/async-closure.stdout b/tests/ui/rustc_public-ir-print/async-closure.stdout index 3aca86ae66935..6dbc1ddf2aad9 100644 --- a/tests/ui/rustc_public-ir-print/async-closure.stdout +++ b/tests/ui/rustc_public-ir-print/async-closure.stdout @@ -48,9 +48,15 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo bb0: { _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); _6 = discriminant((*_7)); - switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3]; + switchInt(move _6) -> [0: bb3, 1: bb1, otherwise: bb2]; } bb1: { + assert(false, `async fn` resumed after completion) -> [success: bb1, unwind unreachable]; + } + bb2: { + unreachable; + } + bb3: { StorageLive(_3); _4 = no_retag ((*_7).0: &i32); _3 = (*_4); @@ -60,12 +66,6 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo discriminant((*_7)) = 1; return; } - bb2: { - assert(false, `async fn` resumed after completion) -> [success: bb2, unwind unreachable]; - } - bb3: { - unreachable; - } } fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: Poll<()>; @@ -80,9 +80,15 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c bb0: { _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); _6 = discriminant((*_7)); - switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3]; + switchInt(move _6) -> [0: bb3, 1: bb1, otherwise: bb2]; } bb1: { + assert(false, `async fn` resumed after completion) -> [success: bb1, unwind unreachable]; + } + bb2: { + unreachable; + } + bb3: { StorageLive(_3); _4 = no_retag ((*_7).0: &i32); _3 = (*_4); @@ -92,10 +98,4 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c discriminant((*_7)) = 1; return; } - bb2: { - assert(false, `async fn` resumed after completion) -> [success: bb2, unwind unreachable]; - } - bb3: { - unreachable; - } } From b4b1b574c07925716988182b1fb74751fa13a193 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Thu, 14 May 2026 22:41:19 +0000 Subject: [PATCH 05/16] Avoid as_mut.unwrap dance, empty vectors are cheap. --- .../rustc_mir_transform/src/elaborate_drop.rs | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index c835ff7dbe070..0eb7db8dbed2d 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -842,9 +842,9 @@ where let mut values = Vec::with_capacity(adt.variants().len()); let mut normal_blocks = Vec::with_capacity(adt.variants().len()); let mut unwind_blocks = - if unwind.is_cleanup() { None } else { Some(Vec::with_capacity(adt.variants().len())) }; + Vec::with_capacity(if unwind.is_cleanup() { 0 } else { adt.variants().len() }); let mut dropline_blocks = - if dropline.is_none() { None } else { Some(Vec::with_capacity(adt.variants().len())) }; + Vec::with_capacity(if dropline.is_none() { 0 } else { adt.variants().len() }); let mut have_otherwise_with_drop_glue = false; let mut have_otherwise = false; @@ -880,7 +880,6 @@ where // I want to minimize the divergence between MSVC // and non-MSVC. - let unwind_blocks = unwind_blocks.as_mut().unwrap(); let unwind_ladder = vec![Unwind::InCleanup; fields.len() + 1]; let dropline_ladder: Vec> = vec![None; fields.len() + 1]; let halfladder = @@ -890,7 +889,7 @@ where let (normal, _, drop_bb) = self.drop_ladder(fields, succ, unwind, dropline); normal_blocks.push(normal); if dropline.is_some() { - dropline_blocks.as_mut().unwrap().push(drop_bb.unwrap()); + dropline_blocks.push(drop_bb.unwrap()); } } else { have_otherwise = true; @@ -911,28 +910,22 @@ where } else if !have_otherwise_with_drop_glue { normal_blocks.push(self.goto_block(succ, unwind)); if let Unwind::To(unwind) = unwind { - unwind_blocks.as_mut().unwrap().push(self.goto_block(unwind, Unwind::InCleanup)); + unwind_blocks.push(self.goto_block(unwind, Unwind::InCleanup)); } } else { normal_blocks.push(self.drop_block(succ, unwind)); if let Unwind::To(unwind) = unwind { - unwind_blocks.as_mut().unwrap().push(self.drop_block(unwind, Unwind::InCleanup)); + unwind_blocks.push(self.drop_block(unwind, Unwind::InCleanup)); } } ( self.adt_switch_block(adt, normal_blocks, &values, succ, unwind), unwind.map(|unwind| { - self.adt_switch_block( - adt, - unwind_blocks.unwrap(), - &values, - unwind, - Unwind::InCleanup, - ) + self.adt_switch_block(adt, unwind_blocks, &values, unwind, Unwind::InCleanup) }), dropline.map(|dropline| { - self.adt_switch_block(adt, dropline_blocks.unwrap(), &values, dropline, unwind) + self.adt_switch_block(adt, dropline_blocks, &values, dropline, unwind) }), ) } From c1a724b424c4f94770ef06ff9369ade47dee812a Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 15:04:00 +0000 Subject: [PATCH 06/16] 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 eb5c760141d3a3680df9c3a773becabaae53030c Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 16:43:05 +0000 Subject: [PATCH 07/16] 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 | 193 +++ ...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 | 134 ++ 25 files changed, 5958 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..08e574a55cd1f --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.double-{closure#0}.coroutine_drop_async.0.mir @@ -0,0 +1,193 @@ +// 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: { + goto -> bb10; + } + + bb23: { + goto -> bb10; + } + + bb24: { + goto -> bb15; + } + + bb25: { + 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..db2ac18a32f4e --- /dev/null +++ b/tests/mir-opt/coroutine/async_drop.simple-{closure#0}.coroutine_drop_async.0.mir @@ -0,0 +1,134 @@ +// 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: { + goto -> bb8; + } + + bb17: { + goto -> bb8; + } + + bb18: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb18, unwind continue]; + } + + bb19: { + _0 = Poll::<()>::Ready(const ()); + return; + } +} From b3a348d5d6581bd63db4f1f5bef1ddd9d7210c81 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 9 May 2026 18:17:48 +0000 Subject: [PATCH 08/16] Call deref_finder when building bodies instead of after it. --- 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 a00fad4bd599a..409feea7ef99f 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1293,6 +1293,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); } @@ -1629,30 +1632,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 372f7117a0119..8116c7b542a4b 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 52738d7da492da40350590cee07ed3b3ff7a2d77 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 15:50:08 +0000 Subject: [PATCH 09/16] Fix deref separation for async drop shim. --- .../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..aaacb5907e3a2 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 respectig 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 78e4152be14cb6ae7eeaf9832d89e2b2fe116944 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 10 May 2026 15:51:30 +0000 Subject: [PATCH 10/16] Simplify build_adrop_for_coroutine_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 aaacb5907e3a2..81352452ad8c2 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 respectig 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 b22b945ce7d08b80fde053b20f908e0f8bcfa095 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 08:38:32 +0000 Subject: [PATCH 11/16] Avoid modifying succ block in build_async_drop. --- .../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 0eb7db8dbed2d..08feedf9e650b 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, @@ -1005,7 +993,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) } @@ -1067,15 +1055,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, @@ -1331,15 +1315,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 9272c0b78a725e61aa3e2e46197488e5c3d99f4f Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 08:38:53 +0000 Subject: [PATCH 12/16] Avoid modifying existing blocks. --- .../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 | 40 +- ...0}.coroutine_drop_async.0.panic-unwind.mir | 66 +- ...losure#0}.[Foo;1].MentionedItems.after.mir | 68 +- 24 files changed, 1881 insertions(+), 1414 deletions(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 08feedf9e650b..b93c669cbd5c9 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( @@ -1397,4 +1396,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 08e574a55cd1f..ccb7c3b430c42 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,97 +91,116 @@ 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: { - goto -> bb10; + bb26: { + goto -> bb14; } - bb23: { - goto -> bb10; + bb27: { + goto -> bb14; } - bb24: { - goto -> bb15; + bb28: { + goto -> bb19; } - bb25: { - goto -> bb15; + bb29: { + 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 db2ac18a32f4e..c22d96c0569a0 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,67 +64,76 @@ 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: { - goto -> bb8; + bb18: { + goto -> bb10; } - bb17: { - goto -> bb8; + bb19: { + 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 0a1cab37427c8..6aff23778ae78 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,57 +42,62 @@ 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: { - goto -> bb4; + drop(((*_19).0: T)) -> [return: bb11, unwind unreachable]; } bb13: { - goto -> bb4; + goto -> bb5; } bb14: { + 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 62fbf10356558..a9a507c5c628c 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,79 +43,88 @@ 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: { - goto -> bb7; + bb18: { + goto -> bb9; } - bb17: { - goto -> bb7; + bb19: { + 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 011cf207d70d930f82a65d733a9e07db51f79703 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Fri, 15 May 2026 13:17:52 +0000 Subject: [PATCH 13/16] Do not resove trait impl during elaboration. --- .../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 b93c669cbd5c9..83aecfdf95cde 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 e3245805c372639abeea9967155571bbd107d823 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 08:57:39 +0000 Subject: [PATCH 14/16] Simplify type computation. --- .../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 | 109 ++- ...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 | 64 +- ...#0}.coroutine_drop_async.0.panic-abort.mir | 57 +- ...0}.coroutine_drop_async.0.panic-unwind.mir | 59 +- ...losure#0}.[Foo;1].MentionedItems.after.mir | 44 +- 24 files changed, 1440 insertions(+), 1602 deletions(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 83aecfdf95cde..903004421a925 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, @@ -926,8 +905,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 ccb7c3b430c42..d3eafaeba7b68 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,7 +173,7 @@ fn double::{closure#0}(_1: Pin<&mut {async fn body of double()}>, _2: &mut Conte } bb25 (cleanup): { - discriminant((*_38)) = 2; + discriminant((*_35)) = 2; resume; } 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 c22d96c0569a0..5d7ecdfb5c6f7 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,7 +115,7 @@ fn simple::{closure#0}(_1: Pin<&mut {async fn body of simple()}>, _2: &mut Conte } bb17 (cleanup): { - discriminant((*_24)) = 2; + discriminant((*_22)) = 2; resume; } 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 6aff23778ae78..00d8e3a02f1c7 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,7 +85,7 @@ 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: { 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 a9a507c5c628c..2c4697e0127f8 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,11 +103,11 @@ 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; } 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 5d556b03d45edef8db29fad3e82a91256ee16839 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 08:22:26 +0000 Subject: [PATCH 15/16] Expand async drops during drop elaboration. --- 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 | 193 +- ...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 | 110 +- ...#0}.coroutine_drop_async.0.panic-abort.mir | 95 +- ...0}.coroutine_drop_async.0.panic-unwind.mir | 113 +- ...losure#0}.[Foo;1].MentionedItems.after.mir | 205 +- 32 files changed, 6683 insertions(+), 3454 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 0569c1b986d1a..f661a85505c94 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 8b015e6cecaae..d7182ef7e2450 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 409feea7ef99f..fa22c94f8e2d4 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 { @@ -1501,24 +1499,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 8116c7b542a4b..3e5abb2b3f7d7 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 903004421a925..5f44e02ae7a0a 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 d3eafaeba7b68..96603c3ada31a 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,102 +109,142 @@ 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: { - 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: { - goto -> bb14; + _2 = move _31; + StorageDead(_31); + goto -> bb26; } bb28: { - goto -> bb19; + _0 = Poll::<()>::Ready(const ()); + return; } bb29: { - 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); + goto -> bb11; + } + + bb33: { + StorageLive(_14); + goto -> bb18; + } + + bb34: { + StorageLive(_24); + goto -> bb21; + } + + bb35: { + StorageLive(_31); + 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 5d7ecdfb5c6f7..575ddd4416306 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,46 +96,64 @@ 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: { - goto -> bb10; + goto -> bb19; } bb19: { - 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); + goto -> bb9; + } + + bb22: { + StorageLive(_13); + 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 00d8e3a02f1c7..2802e3585b867 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,41 +69,59 @@ 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: { - goto -> bb5; + goto -> bb15; } bb14: { - goto -> bb5; + goto -> bb12; } bb15: { + drop(((*_23).0: T)) -> [return: bb14, unwind unreachable]; + } + + bb16: { + StorageLive(_5); + goto -> bb4; + } + + bb17: { + StorageLive(_12); + 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 2c4697e0127f8..a767f97bcba4f 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,71 +64,91 @@ 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: { - goto -> bb9; + goto -> bb16; } bb19: { - 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); + goto -> bb7; + } + + bb22: { + StorageLive(_12); + 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 7fe62e4038094eb22da5f075a72c62b9ac53aa13 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 May 2026 18:41:05 +0000 Subject: [PATCH 16/16] Remove async_fut. --- 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 f4e08e08ef8db..dc0721fbeec84 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1548,9 +1548,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 c60fb92a7a200..900dd693b1257 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -590,9 +590,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 1f8efa72ea867..a648517e5eb8d 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 d7182ef7e2450..cd61b7b4aa9fc 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 1cd11bbd9ce4f..7920ca82aaf3a 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 3e5abb2b3f7d7..9c1d2509a2743 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 5f44e02ae7a0a..83a877cfe3235 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, }, ); } @@ -1322,7 +1321,6 @@ where unwind: unwind.into_action(), replace: false, drop: None, - async_fut: None, }, ); } @@ -1558,7 +1556,6 @@ where unwind: self.unwind.into_action(), replace: false, drop: self.dropline, - async_fut: None, }, ); self.elaborate_drop(blk); @@ -1578,7 +1575,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 31871c62fa7a2..99d95d7e625c7 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 81352452ad8c2..3bd5a13ed9d17 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,