Auto merge of #147493 - cjgillot:single-pin, r=oli-obk

StateTransform: Only load pin field once.

The current implementation starts by transforming all instances of `_1` into `(*_1)`, and then traverses the body again to transform `(*_1)` into `(*(_1.0))`, and again for `Derefer`.

This PR changes the implementation to only traverse the body once. As `_1.0` cannot be not modified inside the body (we just changed its type!), we have no risk of loading from the wrong pointer.
This commit is contained in:
bors
2025-10-25 16:04:41 +00:00
12 changed files with 203 additions and 270 deletions

View File

@@ -132,8 +132,8 @@ struct SelfArgVisitor<'tcx> {
}
impl<'tcx> SelfArgVisitor<'tcx> {
fn new(tcx: TyCtxt<'tcx>, elem: ProjectionElem<Local, Ty<'tcx>>) -> Self {
Self { tcx, new_base: Place { local: SELF_ARG, projection: tcx.mk_place_elems(&[elem]) } }
fn new(tcx: TyCtxt<'tcx>, new_base: Place<'tcx>) -> Self {
Self { tcx, new_base }
}
}
@@ -146,16 +146,14 @@ impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> {
assert_ne!(*local, SELF_ARG);
}
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, _: Location) {
if place.local == SELF_ARG {
replace_base(place, self.new_base, self.tcx);
} else {
self.visit_local(&mut place.local, context, location);
}
for elem in place.projection.iter() {
if let PlaceElem::Index(local) = elem {
assert_ne!(local, SELF_ARG);
}
for elem in place.projection.iter() {
if let PlaceElem::Index(local) = elem {
assert_ne!(local, SELF_ARG);
}
}
}
@@ -515,20 +513,22 @@ fn make_aggregate_adt<'tcx>(
#[tracing::instrument(level = "trace", skip(tcx, body))]
fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let coroutine_ty = body.local_decls.raw[1].ty;
let coroutine_ty = body.local_decls[SELF_ARG].ty;
let ref_coroutine_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty);
// Replace the by value coroutine argument
body.local_decls.raw[1].ty = ref_coroutine_ty;
body.local_decls[SELF_ARG].ty = ref_coroutine_ty;
// Add a deref to accesses of the coroutine state
SelfArgVisitor::new(tcx, ProjectionElem::Deref).visit_body(body);
SelfArgVisitor::new(tcx, tcx.mk_place_deref(SELF_ARG.into())).visit_body(body);
}
#[tracing::instrument(level = "trace", skip(tcx, body))]
fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let ref_coroutine_ty = body.local_decls.raw[1].ty;
let coroutine_ty = body.local_decls[SELF_ARG].ty;
let ref_coroutine_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty);
let pin_did = tcx.require_lang_item(LangItem::Pin, body.span);
let pin_adt_ref = tcx.adt_def(pin_did);
@@ -536,11 +536,33 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body
let pin_ref_coroutine_ty = Ty::new_adt(tcx, pin_adt_ref, args);
// Replace the by ref coroutine argument
body.local_decls.raw[1].ty = pin_ref_coroutine_ty;
body.local_decls[SELF_ARG].ty = pin_ref_coroutine_ty;
let unpinned_local = body.local_decls.push(LocalDecl::new(ref_coroutine_ty, body.span));
// Add the Pin field access to accesses of the coroutine state
SelfArgVisitor::new(tcx, ProjectionElem::Field(FieldIdx::ZERO, ref_coroutine_ty))
.visit_body(body);
SelfArgVisitor::new(tcx, tcx.mk_place_deref(unpinned_local.into())).visit_body(body);
let source_info = SourceInfo::outermost(body.span);
let pin_field = tcx.mk_place_field(SELF_ARG.into(), FieldIdx::ZERO, ref_coroutine_ty);
let statements = &mut body.basic_blocks.as_mut_preserves_cfg()[START_BLOCK].statements;
// Miri requires retags to be the very first thing in the body.
// We insert this assignment just after.
let insert_point = statements
.iter()
.position(|stmt| !matches!(stmt.kind, StatementKind::Retag(..)))
.unwrap_or(statements.len());
statements.insert(
insert_point,
Statement::new(
source_info,
StatementKind::Assign(Box::new((
unpinned_local.into(),
Rvalue::Use(Operand::Copy(pin_field)),
))),
),
);
}
/// Transforms the `body` of the coroutine applying the following transforms:
@@ -1292,8 +1314,6 @@ fn create_coroutine_resume_function<'tcx>(
let default_block = insert_term_block(body, TerminatorKind::Unreachable);
insert_switch(body, cases, &transform, default_block);
make_coroutine_state_argument_indirect(tcx, body);
match transform.coroutine_kind {
CoroutineKind::Coroutine(_)
| CoroutineKind::Desugared(CoroutineDesugaring::Async | CoroutineDesugaring::AsyncGen, _) =>
@@ -1302,7 +1322,9 @@ fn create_coroutine_resume_function<'tcx>(
}
// Iterator::next doesn't accept a pinned argument,
// unlike for all other coroutine kinds.
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {}
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
make_coroutine_state_argument_indirect(tcx, body);
}
}
// Make sure we remove dead blocks to remove

View File

@@ -684,12 +684,13 @@ pub(super) fn create_coroutine_drop_shim_async<'tcx>(
let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info);
make_coroutine_state_argument_indirect(tcx, &mut body);
match transform.coroutine_kind {
// Iterator::next doesn't accept a pinned argument,
// unlike for all other coroutine kinds.
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {}
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
make_coroutine_state_argument_indirect(tcx, &mut body);
}
_ => {
make_coroutine_state_argument_pinned(tcx, &mut body);
}

View File

@@ -2,7 +2,7 @@
fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _2;
debug x => ((*(_1.0: &mut {async fn body of a<T>()})).0: T);
debug x => ((*_20).0: T);
let mut _0: std::task::Poll<()>;
let _3: T;
let mut _4: impl std::future::Future<Output = ()>;
@@ -21,12 +21,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
let mut _17: isize;
let mut _18: ();
let mut _19: u32;
let mut _20: &mut {async fn body of a<T>()};
scope 1 {
debug x => (((*(_1.0: &mut {async fn body of a<T>()})) as variant#4).0: T);
debug x => (((*_20) as variant#4).0: T);
}
bb0: {
_19 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
_20 = copy (_1.0: &mut {async fn body of a<T>()});
_19 = discriminant((*_20));
switchInt(move _19) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14];
}
@@ -43,13 +45,13 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
bb3: {
_0 = Poll::<()>::Pending;
discriminant((*(_1.0: &mut {async fn body of a<T>()}))) = 4;
discriminant((*_20)) = 4;
return;
}
bb4: {
StorageLive(_16);
_15 = &mut (((*(_1.0: &mut {async fn body of a<T>()})) as variant#4).1: impl std::future::Future<Output = ()>);
_15 = &mut (((*_20) as variant#4).1: impl std::future::Future<Output = ()>);
_16 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _15) -> [return: bb7, unwind unreachable];
}
@@ -81,7 +83,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
}
bb11: {
drop(((*(_1.0: &mut {async fn body of a<T>()})).0: T)) -> [return: bb10, unwind unreachable];
drop(((*_20).0: T)) -> [return: bb10, unwind unreachable];
}
bb12: {

View File

@@ -2,7 +2,7 @@
fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _2;
debug x => ((*(_1.0: &mut {async fn body of a<T>()})).0: T);
debug x => ((*_20).0: T);
let mut _0: std::task::Poll<()>;
let _3: T;
let mut _4: impl std::future::Future<Output = ()>;
@@ -21,12 +21,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
let mut _17: isize;
let mut _18: ();
let mut _19: u32;
let mut _20: &mut {async fn body of a<T>()};
scope 1 {
debug x => (((*(_1.0: &mut {async fn body of a<T>()})) as variant#4).0: T);
debug x => (((*_20) as variant#4).0: T);
}
bb0: {
_19 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
_20 = copy (_1.0: &mut {async fn body of a<T>()});
_19 = discriminant((*_20));
switchInt(move _19) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19];
}
@@ -57,13 +59,13 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
bb6: {
_0 = Poll::<()>::Pending;
discriminant((*(_1.0: &mut {async fn body of a<T>()}))) = 4;
discriminant((*_20)) = 4;
return;
}
bb7: {
StorageLive(_16);
_15 = &mut (((*(_1.0: &mut {async fn body of a<T>()})) as variant#4).1: impl std::future::Future<Output = ()>);
_15 = &mut (((*_20) as variant#4).1: impl std::future::Future<Output = ()>);
_16 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _15) -> [return: bb10, unwind: bb15];
}
@@ -95,11 +97,11 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
}
bb14: {
drop(((*(_1.0: &mut {async fn body of a<T>()})).0: T)) -> [return: bb13, unwind: bb4];
drop(((*_20).0: T)) -> [return: bb13, unwind: bb4];
}
bb15 (cleanup): {
discriminant((*(_1.0: &mut {async fn body of a<T>()}))) = 2;
discriminant((*_20)) = 2;
resume;
}

View File

@@ -14,9 +14,11 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) ->
let mut _0: std::task::Poll<()>;
let mut _3: ();
let mut _4: u32;
let mut _5: &mut {async fn body of a()};
bb0: {
_4 = discriminant((*(_1.0: &mut {async fn body of a()})));
_5 = copy (_1.0: &mut {async fn body of a()});
_4 = discriminant((*_5));
switchInt(move _4) -> [0: bb1, 1: bb4, otherwise: bb5];
}
@@ -27,7 +29,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) ->
bb2: {
_0 = Poll::<()>::Ready(move _3);
discriminant((*(_1.0: &mut {async fn body of a()}))) = 1;
discriminant((*_5)) = 1;
return;
}

View File

@@ -86,15 +86,16 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
let mut _36: ();
let mut _37: ();
let mut _38: u32;
let mut _39: &mut {async fn body of b()};
scope 1 {
debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()});
debug __awaitee => (((*_39) as variant#3).0: {async fn body of a()});
let _17: ();
scope 2 {
debug result => _17;
}
}
scope 3 {
debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()});
debug __awaitee => (((*_39) as variant#4).0: {async fn body of a()});
let _33: ();
scope 4 {
debug result => _33;
@@ -102,7 +103,8 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
}
bb0: {
_38 = discriminant((*(_1.0: &mut {async fn body of b()})));
_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];
}
@@ -121,7 +123,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
StorageDead(_5);
PlaceMention(_4);
nop;
(((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()}) = move _4;
(((*_39) as variant#3).0: {async fn body of a()}) = move _4;
goto -> bb4;
}
@@ -131,7 +133,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
StorageLive(_10);
StorageLive(_11);
StorageLive(_12);
_12 = &mut (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()});
_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];
}
@@ -178,7 +180,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
StorageDead(_4);
StorageDead(_19);
StorageDead(_20);
discriminant((*(_1.0: &mut {async fn body of b()}))) = 3;
discriminant((*_39)) = 3;
return;
}
@@ -191,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((((*(_1.0: &mut {async fn body of b()})) 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 unreachable];
}
bb11: {
@@ -223,7 +225,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
StorageDead(_22);
PlaceMention(_21);
nop;
(((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}) = move _21;
(((*_39) as variant#4).0: {async fn body of a()}) = move _21;
goto -> bb16;
}
@@ -233,7 +235,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
StorageLive(_26);
StorageLive(_27);
StorageLive(_28);
_28 = &mut (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()});
_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];
}
@@ -275,7 +277,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
StorageDead(_21);
StorageDead(_35);
StorageDead(_36);
discriminant((*(_1.0: &mut {async fn body of b()}))) = 4;
discriminant((*_39)) = 4;
return;
}
@@ -288,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((((*(_1.0: &mut {async fn body of b()})) 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 unreachable];
}
bb22: {
@@ -311,7 +313,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
bb25: {
_0 = Poll::<()>::Ready(move _37);
discriminant((*(_1.0: &mut {async fn body of b()}))) = 1;
discriminant((*_39)) = 1;
return;
}

View File

@@ -23,7 +23,7 @@
} */
fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> {
debug arg => (((*(_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18})) as variant#4).0: std::string::String);
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;
let mut _4: (&str, std::string::String, &std::panic::Location<'_>);
@@ -41,13 +41,6 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2
let mut _16: ();
let mut _17: u32;
let mut _18: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18};
let mut _19: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18};
let mut _20: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18};
let mut _21: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18};
let mut _22: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18};
let mut _23: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18};
let mut _24: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18};
let mut _25: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18};
bb0: {
_18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
@@ -56,14 +49,12 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2
}
bb1: {
_19 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
(((*_19) as variant#4).0: std::string::String) = move _2;
(((*_18) as variant#4).0: std::string::String) = move _2;
StorageLive(_3);
StorageLive(_4);
StorageLive(_5);
StorageLive(_6);
_20 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
_6 = &(((*_20) as variant#4).0: std::string::String);
_6 = &(((*_18) as variant#4).0: std::string::String);
_5 = <String as Clone>::clone(move _6) -> [return: bb2, unwind unreachable];
}
@@ -84,8 +75,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2
_0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4);
StorageDead(_3);
StorageDead(_4);
_21 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
discriminant((*_21)) = 3;
discriminant((*_18)) = 3;
return;
}
@@ -108,8 +98,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2
_10 = &(*_11);
StorageLive(_12);
StorageLive(_13);
_22 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
_13 = &(((*_22) as variant#4).0: std::string::String);
_13 = &(((*_18) as variant#4).0: std::string::String);
_12 = <String as Clone>::clone(move _13) -> [return: bb8, unwind unreachable];
}
@@ -135,8 +124,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2
StorageDead(_9);
StorageDead(_11);
StorageDead(_15);
_23 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
discriminant((*_23)) = 4;
discriminant((*_18)) = 4;
return;
}
@@ -154,8 +142,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2
StorageDead(_11);
StorageDead(_8);
_16 = const ();
_24 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
drop((((*_24) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable];
drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable];
}
bb14: {
@@ -164,8 +151,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2
bb15: {
_0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16);
_25 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
discriminant((*_25)) = 1;
discriminant((*_18)) = 1;
return;
}

View File

@@ -23,7 +23,7 @@
} */
fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> {
debug arg => (((*(_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18})) as variant#4).0: std::string::String);
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;
let mut _4: (&str, std::string::String, &std::panic::Location<'_>);
@@ -41,13 +41,6 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2
let mut _16: ();
let mut _17: u32;
let mut _18: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18};
let mut _19: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18};
let mut _20: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18};
let mut _21: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18};
let mut _22: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18};
let mut _23: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18};
let mut _24: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18};
let mut _25: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18};
bb0: {
_18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
@@ -56,14 +49,12 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2
}
bb1: {
_19 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
(((*_19) as variant#4).0: std::string::String) = move _2;
(((*_18) as variant#4).0: std::string::String) = move _2;
StorageLive(_3);
StorageLive(_4);
StorageLive(_5);
StorageLive(_6);
_20 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
_6 = &(((*_20) as variant#4).0: std::string::String);
_6 = &(((*_18) as variant#4).0: std::string::String);
_5 = <String as Clone>::clone(move _6) -> [return: bb2, unwind unreachable];
}
@@ -84,8 +75,7 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2
_0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4);
StorageDead(_3);
StorageDead(_4);
_21 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
discriminant((*_21)) = 3;
discriminant((*_18)) = 3;
return;
}
@@ -108,8 +98,7 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2
_10 = &(*_11);
StorageLive(_12);
StorageLive(_13);
_22 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
_13 = &(((*_22) as variant#4).0: std::string::String);
_13 = &(((*_18) as variant#4).0: std::string::String);
_12 = <String as Clone>::clone(move _13) -> [return: bb8, unwind unreachable];
}
@@ -135,8 +124,7 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2
StorageDead(_9);
StorageDead(_11);
StorageDead(_15);
_23 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
discriminant((*_23)) = 4;
discriminant((*_18)) = 4;
return;
}
@@ -154,8 +142,7 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2
StorageDead(_11);
StorageDead(_8);
_16 = const ();
_24 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
drop((((*_24) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable];
drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable];
}
bb14: {
@@ -164,8 +151,7 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2
bb15: {
_0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16);
_25 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
discriminant((*_25)) = 1;
discriminant((*_18)) = 1;
return;
}

View File

@@ -32,18 +32,20 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}
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 => (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop);
debug _d => (((*_11) as variant#3).0: HasDrop);
}
bb0: {
_10 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})));
_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;
(((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop) = HasDrop;
(((*_11) as variant#3).0: HasDrop) = HasDrop;
StorageLive(_4);
goto -> bb2;
}
@@ -56,7 +58,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}
StorageDead(_4);
StorageDead(_6);
StorageDead(_7);
discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}))) = 3;
discriminant((*_11)) = 3;
return;
}

View File

@@ -41,13 +41,6 @@
+ let mut _30: ();
+ let mut _31: u32;
+ let mut _32: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _33: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _34: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _35: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _36: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _37: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _38: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ scope 7 {
+ let mut _15: std::future::Ready<()>;
+ scope 8 {
@@ -57,37 +50,37 @@
+ scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
+ }
+ scope 13 (inlined <std::future::Ready<()> as Future>::poll) {
+ let mut _41: ();
+ let mut _42: std::option::Option<()>;
+ let mut _43: &mut std::option::Option<()>;
+ let mut _44: &mut std::future::Ready<()>;
+ let mut _45: &mut std::pin::Pin<&mut std::future::Ready<()>>;
+ 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 <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
+ let mut _46: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>;
+ let mut _47: *mut std::pin::Pin<&mut std::future::Ready<()>>;
+ 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 <pin::helper::PinHelper<&mut std::future::Ready<()>> as pin::helper::PinDerefMutHelper>::deref_mut) {
+ let mut _48: &mut &mut std::future::Ready<()>;
+ let mut _41: &mut &mut std::future::Ready<()>;
+ scope 16 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
+ }
+ }
+ }
+ scope 17 (inlined Option::<()>::take) {
+ let mut _49: std::option::Option<()>;
+ let mut _42: std::option::Option<()>;
+ scope 18 (inlined std::mem::replace::<Option<()>>) {
+ scope 19 {
+ }
+ }
+ }
+ scope 20 (inlined #[track_caller] Option::<()>::expect) {
+ let mut _50: isize;
+ let mut _51: !;
+ let mut _43: isize;
+ let mut _44: !;
+ scope 21 {
+ }
+ }
+ }
+ }
+ scope 10 (inlined ready::<()>) {
+ let mut _40: std::option::Option<()>;
+ let mut _33: std::option::Option<()>;
+ }
+ scope 11 (inlined <std::future::Ready<()> as IntoFuture>::into_future) {
+ }
@@ -132,13 +125,6 @@
+ StorageLive(_30);
+ StorageLive(_31);
+ StorageLive(_32);
+ StorageLive(_33);
+ StorageLive(_34);
+ StorageLive(_35);
+ StorageLive(_36);
+ StorageLive(_37);
+ StorageLive(_38);
+ StorageLive(_39);
+ _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];
@@ -151,13 +137,6 @@
+ }
+
+ bb2: {
+ StorageDead(_39);
+ StorageDead(_38);
+ StorageDead(_37);
+ StorageDead(_36);
+ StorageDead(_35);
+ StorageDead(_34);
+ StorageDead(_33);
+ StorageDead(_32);
+ StorageDead(_31);
+ StorageDead(_30);
@@ -175,22 +154,19 @@
}
+ bb3: {
+ _33 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _34 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ (((*_33) as variant#3).0: ActionPermit<'_, T>) = move ((*_34).0: ActionPermit<'_, T>);
+ (((*_32) as variant#3).0: ActionPermit<'_, T>) = move ((*_32).0: ActionPermit<'_, T>);
+ StorageLive(_12);
+ StorageLive(_13);
+ StorageLive(_14);
+ _14 = ();
+ StorageLive(_40);
+ _40 = Option::<()>::Some(copy _14);
+ _13 = std::future::Ready::<()>(move _40);
+ StorageDead(_40);
+ StorageLive(_33);
+ _33 = Option::<()>::Some(copy _14);
+ _13 = std::future::Ready::<()>(move _33);
+ StorageDead(_33);
+ StorageDead(_14);
+ _12 = move _13;
+ StorageDead(_13);
+ _35 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ (((*_35) as variant#3).1: std::future::Ready<()>) = move _12;
+ (((*_32) as variant#3).1: std::future::Ready<()>) = move _12;
+ goto -> bb4;
+ }
+
@@ -202,8 +178,7 @@
+ StorageLive(_19);
+ StorageLive(_20);
+ StorageLive(_21);
+ _36 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _21 = &mut (((*_36) as variant#3).1: std::future::Ready<()>);
+ _21 = &mut (((*_32) as variant#3).1: std::future::Ready<()>);
+ _20 = &mut (*_21);
+ _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 };
+ StorageDead(_20);
@@ -214,24 +189,24 @@
+ _23 = move _24;
+ _22 = &mut (*_23);
+ StorageDead(_24);
+ StorageLive(_37);
+ StorageLive(_39);
+ StorageLive(_44);
+ StorageLive(_46);
+ StorageLive(_51);
+ StorageLive(_41);
+ 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 = copy ((*_39).0: &mut std::future::Ready<()>);
+ StorageLive(_42);
+ StorageLive(_47);
+ _47 = &raw mut _19;
+ _46 = copy _47 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr);
+ StorageDead(_47);
+ _44 = copy ((*_46).0: &mut std::future::Ready<()>);
+ StorageLive(_49);
+ _49 = Option::<()>::None;
+ _42 = copy ((*_44).0: std::option::Option<()>);
+ ((*_44).0: std::option::Option<()>) = copy _49;
+ StorageDead(_49);
+ StorageLive(_50);
+ _50 = discriminant(_42);
+ switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5];
+ _42 = Option::<()>::None;
+ _35 = copy ((*_37).0: std::option::Option<()>);
+ ((*_37).0: std::option::Option<()>) = copy _42;
+ StorageDead(_42);
+ StorageLive(_43);
+ _43 = discriminant(_35);
+ switchInt(move _43) -> [0: bb11, 1: bb12, otherwise: bb5];
}
+
+ bb5: {
@@ -251,8 +226,7 @@
+ StorageDead(_12);
+ StorageDead(_28);
+ StorageDead(_29);
+ _37 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_37)) = 3;
+ discriminant((*_32)) = 3;
+ goto -> bb2;
+ }
+
@@ -266,14 +240,12 @@
+ StorageDead(_18);
+ StorageDead(_17);
+ StorageDead(_12);
+ _38 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ drop((((*_38) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable];
+ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable];
+ }
+
+ bb8: {
+ _7 = Poll::<()>::Ready(move _30);
+ _39 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_39)) = 1;
+ discriminant((*_32)) = 1;
+ goto -> bb2;
+ }
+
@@ -294,18 +266,18 @@
+ }
+
+ bb11: {
+ _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
+ _44 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
+ }
+
+ bb12: {
+ _41 = move ((_42 as Some).0: ());
+ StorageDead(_50);
+ StorageDead(_42);
+ _18 = Poll::<()>::Ready(move _41);
+ StorageDead(_41);
+ StorageDead(_51);
+ StorageDead(_46);
+ _34 = move ((_35 as Some).0: ());
+ StorageDead(_43);
+ StorageDead(_35);
+ _18 = Poll::<()>::Ready(move _34);
+ StorageDead(_34);
+ StorageDead(_44);
+ StorageDead(_39);
+ StorageDead(_37);
+ StorageDead(_22);
+ StorageDead(_19);
+ _25 = discriminant(_18);

View File

@@ -41,15 +41,6 @@
+ let mut _30: ();
+ let mut _31: u32;
+ let mut _32: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _33: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _34: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _35: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _36: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _37: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _38: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _41: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ scope 7 {
+ let mut _15: std::future::Ready<()>;
+ scope 8 {
@@ -59,37 +50,37 @@
+ scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
+ }
+ scope 13 (inlined <std::future::Ready<()> as Future>::poll) {
+ let mut _43: ();
+ let mut _44: std::option::Option<()>;
+ let mut _45: &mut std::option::Option<()>;
+ let mut _46: &mut std::future::Ready<()>;
+ let mut _47: &mut std::pin::Pin<&mut std::future::Ready<()>>;
+ 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 <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
+ let mut _48: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>;
+ let mut _49: *mut std::pin::Pin<&mut std::future::Ready<()>>;
+ 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 <pin::helper::PinHelper<&mut std::future::Ready<()>> as pin::helper::PinDerefMutHelper>::deref_mut) {
+ let mut _50: &mut &mut std::future::Ready<()>;
+ let mut _41: &mut &mut std::future::Ready<()>;
+ scope 16 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
+ }
+ }
+ }
+ scope 17 (inlined Option::<()>::take) {
+ let mut _51: std::option::Option<()>;
+ let mut _42: std::option::Option<()>;
+ scope 18 (inlined std::mem::replace::<Option<()>>) {
+ scope 19 {
+ }
+ }
+ }
+ scope 20 (inlined #[track_caller] Option::<()>::expect) {
+ let mut _52: isize;
+ let mut _53: !;
+ let mut _43: isize;
+ let mut _44: !;
+ scope 21 {
+ }
+ }
+ }
+ }
+ scope 10 (inlined ready::<()>) {
+ let mut _42: std::option::Option<()>;
+ let mut _33: std::option::Option<()>;
+ }
+ scope 11 (inlined <std::future::Ready<()> as IntoFuture>::into_future) {
+ }
@@ -134,15 +125,6 @@
+ StorageLive(_30);
+ StorageLive(_31);
+ StorageLive(_32);
+ StorageLive(_33);
+ StorageLive(_34);
+ StorageLive(_35);
+ StorageLive(_36);
+ StorageLive(_37);
+ StorageLive(_38);
+ StorageLive(_39);
+ StorageLive(_40);
+ StorageLive(_41);
+ _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];
@@ -163,15 +145,6 @@
+ }
+
+ bb4: {
+ StorageDead(_41);
+ StorageDead(_40);
+ StorageDead(_39);
+ StorageDead(_38);
+ StorageDead(_37);
+ StorageDead(_36);
+ StorageDead(_35);
+ StorageDead(_34);
+ StorageDead(_33);
+ StorageDead(_32);
+ StorageDead(_31);
+ StorageDead(_30);
@@ -192,22 +165,19 @@
- StorageDead(_2);
- return;
+ bb5: {
+ _33 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _34 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ (((*_33) as variant#3).0: ActionPermit<'_, T>) = move ((*_34).0: ActionPermit<'_, T>);
+ (((*_32) as variant#3).0: ActionPermit<'_, T>) = move ((*_32).0: ActionPermit<'_, T>);
+ StorageLive(_12);
+ StorageLive(_13);
+ StorageLive(_14);
+ _14 = ();
+ StorageLive(_42);
+ _42 = Option::<()>::Some(copy _14);
+ _13 = std::future::Ready::<()>(move _42);
+ StorageDead(_42);
+ StorageLive(_33);
+ _33 = Option::<()>::Some(copy _14);
+ _13 = std::future::Ready::<()>(move _33);
+ StorageDead(_33);
+ StorageDead(_14);
+ _12 = move _13;
+ StorageDead(_13);
+ _35 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ (((*_35) as variant#3).1: std::future::Ready<()>) = move _12;
+ (((*_32) as variant#3).1: std::future::Ready<()>) = move _12;
+ goto -> bb6;
}
@@ -219,8 +189,7 @@
+ StorageLive(_19);
+ StorageLive(_20);
+ StorageLive(_21);
+ _36 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _21 = &mut (((*_36) as variant#3).1: std::future::Ready<()>);
+ _21 = &mut (((*_32) as variant#3).1: std::future::Ready<()>);
+ _20 = &mut (*_21);
+ _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 };
+ StorageDead(_20);
@@ -231,24 +200,24 @@
+ _23 = move _24;
+ _22 = &mut (*_23);
+ StorageDead(_24);
+ StorageLive(_46);
+ StorageLive(_48);
+ StorageLive(_53);
+ StorageLive(_43);
+ StorageLive(_37);
+ StorageLive(_39);
+ StorageLive(_44);
+ StorageLive(_49);
+ _49 = &raw mut _19;
+ _48 = copy _49 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr);
+ StorageDead(_49);
+ _46 = copy ((*_48).0: &mut std::future::Ready<()>);
+ StorageLive(_51);
+ _51 = Option::<()>::None;
+ _44 = copy ((*_46).0: std::option::Option<()>);
+ ((*_46).0: std::option::Option<()>) = copy _51;
+ StorageDead(_51);
+ StorageLive(_52);
+ _52 = discriminant(_44);
+ switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7];
+ 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 = copy ((*_39).0: &mut std::future::Ready<()>);
+ StorageLive(_42);
+ _42 = Option::<()>::None;
+ _35 = copy ((*_37).0: std::option::Option<()>);
+ ((*_37).0: std::option::Option<()>) = copy _42;
+ StorageDead(_42);
+ StorageLive(_43);
+ _43 = discriminant(_35);
+ switchInt(move _43) -> [0: bb16, 1: bb17, otherwise: bb7];
}
- bb6 (cleanup): {
@@ -270,8 +239,7 @@
+ StorageDead(_12);
+ StorageDead(_28);
+ StorageDead(_29);
+ _37 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_37)) = 3;
+ discriminant((*_32)) = 3;
+ goto -> bb4;
+ }
+
@@ -285,14 +253,12 @@
+ StorageDead(_18);
+ StorageDead(_17);
+ StorageDead(_12);
+ _38 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ drop((((*_38) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12];
+ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12];
+ }
+
+ bb10: {
+ _7 = Poll::<()>::Ready(move _30);
+ _39 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_39)) = 1;
+ discriminant((*_32)) = 1;
+ goto -> bb4;
+ }
+
@@ -304,13 +270,11 @@
+ StorageDead(_18);
+ StorageDead(_17);
+ StorageDead(_12);
+ _40 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ drop((((*_40) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)];
+ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)];
+ }
+
+ bb12 (cleanup): {
+ _41 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_41)) = 2;
+ discriminant((*_32)) = 2;
+ goto -> bb2;
+ }
+
@@ -335,18 +299,18 @@
+ }
+
+ bb16: {
+ _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
+ _44 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
+ }
+
+ bb17: {
+ _43 = move ((_44 as Some).0: ());
+ StorageDead(_52);
+ StorageDead(_44);
+ _18 = Poll::<()>::Ready(move _43);
+ _34 = move ((_35 as Some).0: ());
+ StorageDead(_43);
+ StorageDead(_53);
+ StorageDead(_48);
+ StorageDead(_46);
+ StorageDead(_35);
+ _18 = Poll::<()>::Ready(move _34);
+ StorageDead(_34);
+ StorageDead(_44);
+ StorageDead(_39);
+ StorageDead(_37);
+ StorageDead(_22);
+ StorageDead(_19);
+ _25 = discriminant(_18);

View File

@@ -42,10 +42,8 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo
let mut _5: ();
let mut _6: u32;
let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
let mut _9: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
debug _task_context => _2;
debug y => (*((*(_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})).0: &i32));
debug y => (*((*_7).0: &i32));
debug y => _3;
bb0: {
_7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
@@ -54,14 +52,12 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo
}
bb1: {
StorageLive(_3);
_8 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
_4 = ((*_8).0: &i32);
_4 = ((*_7).0: &i32);
_3 = (*_4);
_5 = ();
StorageDead(_3);
_0 = std::task::Poll::Ready(move _5);
_9 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
discriminant((*_9)) = 1;
discriminant((*_7)) = 1;
return;
}
bb2: {
@@ -78,10 +74,8 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c
let mut _5: ();
let mut _6: u32;
let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
let mut _9: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
debug _task_context => _2;
debug y => (*((*(_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})).0: &i32));
debug y => (*((*_7).0: &i32));
debug y => _3;
bb0: {
_7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
@@ -90,14 +84,12 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c
}
bb1: {
StorageLive(_3);
_8 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
_4 = ((*_8).0: &i32);
_4 = ((*_7).0: &i32);
_3 = (*_4);
_5 = ();
StorageDead(_3);
_0 = std::task::Poll::Ready(move _5);
_9 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
discriminant((*_9)) = 1;
discriminant((*_7)) = 1;
return;
}
bb2: {