Rollup merge of #146552 - cjgillot:resume-noremap, r=jackh726
StateTransform: Do not renumber resume local. MIR parameters are not explicitly assigned-to when entering the MIR body. If we want to save their values inside the coroutine state, we need to do so explicitly. This was done by renaming the `_2` local, and introducing an explicit assignment pre-transform. This particular trick confuses me. This version makes explicit that we are assigning parameters to saved locals. r? ``@dingxiangfei2009``
This commit is contained in:
commit
577f18ffe2
17 changed files with 639 additions and 225 deletions
|
|
@ -471,7 +471,7 @@ impl<'tcx> Body<'tcx> {
|
|||
|
||||
/// Returns an iterator over all function arguments.
|
||||
#[inline]
|
||||
pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
|
||||
pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator + use<> {
|
||||
(1..self.arg_count + 1).map(Local::new)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty};
|
|||
rustc_index::newtype_index! {
|
||||
#[derive(HashStable)]
|
||||
#[encodable]
|
||||
#[debug_format = "_{}"]
|
||||
#[debug_format = "_s{}"]
|
||||
pub struct CoroutineSavedLocal {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1340,14 +1340,13 @@ fn create_cases<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
if operation == Operation::Resume {
|
||||
if operation == Operation::Resume && point.resume_arg != CTX_ARG.into() {
|
||||
// Move the resume argument to the destination place of the `Yield` terminator
|
||||
let resume_arg = CTX_ARG;
|
||||
statements.push(Statement::new(
|
||||
source_info,
|
||||
StatementKind::Assign(Box::new((
|
||||
point.resume_arg,
|
||||
Rvalue::Use(Operand::Move(resume_arg.into())),
|
||||
Rvalue::Use(Operand::Move(CTX_ARG.into())),
|
||||
))),
|
||||
));
|
||||
}
|
||||
|
|
@ -1439,7 +1438,10 @@ fn check_field_tys_sized<'tcx>(
|
|||
}
|
||||
|
||||
impl<'tcx> crate::MirPass<'tcx> for StateTransform {
|
||||
#[instrument(level = "debug", skip(self, tcx, body), ret)]
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
debug!(def_id = ?body.source.def_id());
|
||||
|
||||
let Some(old_yield_ty) = body.yield_ty() else {
|
||||
// This only applies to coroutines
|
||||
return;
|
||||
|
|
@ -1518,31 +1520,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
|
|||
cleanup_async_drops(body);
|
||||
}
|
||||
|
||||
// We also replace the resume argument and insert an `Assign`.
|
||||
// This is needed because the resume argument `_2` might be live across a `yield`, in which
|
||||
// case there is no `Assign` to it that the transform can turn into a store to the coroutine
|
||||
// state. After the yield the slot in the coroutine state would then be uninitialized.
|
||||
let resume_local = CTX_ARG;
|
||||
let resume_ty = body.local_decls[resume_local].ty;
|
||||
let old_resume_local = replace_local(resume_local, resume_ty, body, tcx);
|
||||
|
||||
// When first entering the coroutine, move the resume argument into its old local
|
||||
// (which is now a generator interior).
|
||||
let source_info = SourceInfo::outermost(body.span);
|
||||
let stmts = &mut body.basic_blocks_mut()[START_BLOCK].statements;
|
||||
stmts.insert(
|
||||
0,
|
||||
Statement::new(
|
||||
source_info,
|
||||
StatementKind::Assign(Box::new((
|
||||
old_resume_local.into(),
|
||||
Rvalue::Use(Operand::Move(resume_local.into())),
|
||||
))),
|
||||
),
|
||||
);
|
||||
|
||||
let always_live_locals = always_storage_live_locals(body);
|
||||
|
||||
let movable = coroutine_kind.movability() == hir::Movability::Movable;
|
||||
let liveness_info =
|
||||
locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
|
||||
|
|
@ -1583,6 +1561,21 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
|
|||
};
|
||||
transform.visit_body(body);
|
||||
|
||||
// MIR parameters are not explicitly assigned-to when entering the MIR body.
|
||||
// If we want to save their values inside the coroutine state, we need to do so explicitly.
|
||||
let source_info = SourceInfo::outermost(body.span);
|
||||
let args_iter = body.args_iter();
|
||||
body.basic_blocks.as_mut()[START_BLOCK].statements.splice(
|
||||
0..0,
|
||||
args_iter.filter_map(|local| {
|
||||
let (ty, variant_index, idx) = transform.remap[local]?;
|
||||
let lhs = transform.make_field(variant_index, idx, ty);
|
||||
let rhs = Rvalue::Use(Operand::Move(local.into()));
|
||||
let assign = StatementKind::Assign(Box::new((lhs, rhs)));
|
||||
Some(Statement::new(source_info, assign))
|
||||
}),
|
||||
);
|
||||
|
||||
// Update our MIR struct to reflect the changes we've made
|
||||
body.arg_count = 2; // self, resume arg
|
||||
body.spread_arg = None;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// MIR for `a::{closure#0}` 0 coroutine_drop_async
|
||||
|
||||
fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>) -> Poll<()> {
|
||||
debug _task_context => _19;
|
||||
debug _task_context => _2;
|
||||
debug x => ((*(_1.0: &mut {async fn body of a<T>()})).0: T);
|
||||
let mut _0: std::task::Poll<()>;
|
||||
let _3: T;
|
||||
|
|
@ -20,15 +20,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
|
|||
let mut _16: &mut impl std::future::Future<Output = ()>;
|
||||
let mut _17: std::pin::Pin<&mut impl std::future::Future<Output = ()>>;
|
||||
let mut _18: isize;
|
||||
let mut _19: &mut std::task::Context<'_>;
|
||||
let mut _20: u32;
|
||||
let mut _19: u32;
|
||||
scope 1 {
|
||||
debug x => (((*(_1.0: &mut {async fn body of a<T>()})) as variant#4).0: T);
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_20 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
|
||||
switchInt(move _20) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14];
|
||||
_19 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
|
||||
switchInt(move _19) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// MIR for `a::{closure#0}` 0 coroutine_drop_async
|
||||
|
||||
fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>) -> Poll<()> {
|
||||
debug _task_context => _19;
|
||||
debug _task_context => _2;
|
||||
debug x => ((*(_1.0: &mut {async fn body of a<T>()})).0: T);
|
||||
let mut _0: std::task::Poll<()>;
|
||||
let _3: T;
|
||||
|
|
@ -20,15 +20,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a<T>()}>, _2: &mut Context<'_>)
|
|||
let mut _16: &mut impl std::future::Future<Output = ()>;
|
||||
let mut _17: std::pin::Pin<&mut impl std::future::Future<Output = ()>>;
|
||||
let mut _18: isize;
|
||||
let mut _19: &mut std::task::Context<'_>;
|
||||
let mut _20: u32;
|
||||
let mut _19: u32;
|
||||
scope 1 {
|
||||
debug x => (((*(_1.0: &mut {async fn body of a<T>()})) as variant#4).0: T);
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_20 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
|
||||
switchInt(move _20) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19];
|
||||
_19 = discriminant((*(_1.0: &mut {async fn body of a<T>()})));
|
||||
switchInt(move _19) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
|||
|
|
@ -10,19 +10,17 @@
|
|||
} */
|
||||
|
||||
fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> {
|
||||
debug _task_context => _4;
|
||||
debug _task_context => _2;
|
||||
let mut _0: std::task::Poll<()>;
|
||||
let mut _3: ();
|
||||
let mut _4: &mut std::task::Context<'_>;
|
||||
let mut _5: u32;
|
||||
let mut _4: u32;
|
||||
|
||||
bb0: {
|
||||
_5 = discriminant((*(_1.0: &mut {async fn body of a()})));
|
||||
switchInt(move _5) -> [0: bb1, 1: bb4, otherwise: bb5];
|
||||
_4 = discriminant((*(_1.0: &mut {async fn body of a()})));
|
||||
switchInt(move _4) -> [0: bb1, 1: bb4, otherwise: bb5];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_4 = move _2;
|
||||
_3 = const ();
|
||||
goto -> bb3;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// MIR for `b::{closure#0}` 0 coroutine_resume
|
||||
/* coroutine_layout = CoroutineLayout {
|
||||
field_tys: {
|
||||
_0: CoroutineSavedTy {
|
||||
_s0: CoroutineSavedTy {
|
||||
ty: Coroutine(
|
||||
DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
|
||||
[
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
},
|
||||
ignore_for_traits: false,
|
||||
},
|
||||
_1: CoroutineSavedTy {
|
||||
_s1: CoroutineSavedTy {
|
||||
ty: Coroutine(
|
||||
DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
|
||||
[
|
||||
|
|
@ -40,17 +40,17 @@
|
|||
Unresumed(0): [],
|
||||
Returned (1): [],
|
||||
Panicked (2): [],
|
||||
Suspend0 (3): [_0],
|
||||
Suspend1 (4): [_1],
|
||||
Suspend0 (3): [_s0],
|
||||
Suspend1 (4): [_s1],
|
||||
},
|
||||
storage_conflicts: BitMatrix(2x2) {
|
||||
(_0, _0),
|
||||
(_1, _1),
|
||||
(_s0, _s0),
|
||||
(_s1, _s1),
|
||||
},
|
||||
} */
|
||||
|
||||
fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> {
|
||||
debug _task_context => _38;
|
||||
debug _task_context => _2;
|
||||
let mut _0: std::task::Poll<()>;
|
||||
let _3: ();
|
||||
let mut _4: {async fn body of a()};
|
||||
|
|
@ -85,8 +85,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
|
|||
let mut _35: &mut std::task::Context<'_>;
|
||||
let mut _36: ();
|
||||
let mut _37: ();
|
||||
let mut _38: &mut std::task::Context<'_>;
|
||||
let mut _39: u32;
|
||||
let mut _38: u32;
|
||||
scope 1 {
|
||||
debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()});
|
||||
let _17: ();
|
||||
|
|
@ -103,12 +102,11 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
|
|||
}
|
||||
|
||||
bb0: {
|
||||
_39 = discriminant((*(_1.0: &mut {async fn body of b()})));
|
||||
switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8];
|
||||
_38 = discriminant((*(_1.0: &mut {async fn body of b()})));
|
||||
switchInt(move _38) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_38 = move _2;
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
|
|
@ -143,7 +141,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
|
|||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
_15 = copy _38;
|
||||
_15 = copy _2;
|
||||
_14 = move _15;
|
||||
goto -> bb6;
|
||||
}
|
||||
|
|
@ -198,7 +196,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
|
|||
|
||||
bb11: {
|
||||
StorageDead(_20);
|
||||
_38 = move _19;
|
||||
_2 = move _19;
|
||||
StorageDead(_19);
|
||||
_7 = const ();
|
||||
goto -> bb4;
|
||||
|
|
@ -245,7 +243,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
|
|||
StorageLive(_29);
|
||||
StorageLive(_30);
|
||||
StorageLive(_31);
|
||||
_31 = copy _38;
|
||||
_31 = copy _2;
|
||||
_30 = move _31;
|
||||
goto -> bb18;
|
||||
}
|
||||
|
|
@ -295,7 +293,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
|
|||
|
||||
bb22: {
|
||||
StorageDead(_36);
|
||||
_38 = move _35;
|
||||
_2 = move _35;
|
||||
StorageDead(_35);
|
||||
_7 = const ();
|
||||
goto -> bb16;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,207 @@
|
|||
// 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:18:6: 18: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: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);
|
||||
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: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 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
|
||||
_17 = discriminant((*_18));
|
||||
switchInt(move _17) -> [0: bb1, 1: bb19, 3: bb17, 4: bb18, otherwise: bb20];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_19 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
|
||||
(((*_19) as variant#4).0: std::string::String) = move _2;
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_20 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
|
||||
_6 = &(((*_20) as variant#4).0: std::string::String);
|
||||
_5 = <String as Clone>::clone(move _6) -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
_7 = Location::<'_>::caller() -> [return: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
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);
|
||||
_21 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
|
||||
discriminant((*_21)) = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
goto -> bb6;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_4);
|
||||
drop(_3) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_3);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_11 = const "second";
|
||||
_10 = &(*_11);
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
_22 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
|
||||
_13 = &(((*_22) as variant#4).0: std::string::String);
|
||||
_12 = <String as Clone>::clone(move _13) -> [return: bb8, unwind unreachable];
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
_15 = Location::<'_>::caller() -> [return: bb9, unwind unreachable];
|
||||
}
|
||||
|
||||
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);
|
||||
_23 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
|
||||
discriminant((*_23)) = 4;
|
||||
return;
|
||||
}
|
||||
|
||||
bb11: {
|
||||
goto -> bb12;
|
||||
}
|
||||
|
||||
bb12: {
|
||||
StorageDead(_9);
|
||||
drop(_8) -> [return: bb13, unwind unreachable];
|
||||
}
|
||||
|
||||
bb13: {
|
||||
StorageDead(_15);
|
||||
StorageDead(_11);
|
||||
StorageDead(_8);
|
||||
_16 = const ();
|
||||
_24 = deref_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];
|
||||
}
|
||||
|
||||
bb14: {
|
||||
goto -> bb16;
|
||||
}
|
||||
|
||||
bb15: {
|
||||
_0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16);
|
||||
_25 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18});
|
||||
discriminant((*_25)) = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
bb16: {
|
||||
goto -> bb15;
|
||||
}
|
||||
|
||||
bb17: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_3 = move _2;
|
||||
goto -> bb5;
|
||||
}
|
||||
|
||||
bb18: {
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
StorageLive(_11);
|
||||
StorageLive(_15);
|
||||
_8 = move _2;
|
||||
goto -> bb11;
|
||||
}
|
||||
|
||||
bb19: {
|
||||
assert(const false, "coroutine resumed after completion") -> [success: bb19, unwind unreachable];
|
||||
}
|
||||
|
||||
bb20: {
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
ALLOC0 (size: 6, align: 1) {
|
||||
73 65 63 6f 6e 64 │ second
|
||||
}
|
||||
|
||||
ALLOC1 (size: 5, align: 1) {
|
||||
66 69 72 73 74 │ first
|
||||
}
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
// 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:25:6: 25: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: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);
|
||||
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: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 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
|
||||
_17 = discriminant((*_18));
|
||||
switchInt(move _17) -> [0: bb1, 1: bb19, 3: bb17, 4: bb18, otherwise: bb20];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_19 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
|
||||
(((*_19) as variant#4).0: std::string::String) = move _2;
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_20 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
|
||||
_6 = &(((*_20) as variant#4).0: std::string::String);
|
||||
_5 = <String as Clone>::clone(move _6) -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
_7 = Location::<'_>::caller() -> [return: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
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);
|
||||
_21 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
|
||||
discriminant((*_21)) = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
goto -> bb6;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_4);
|
||||
drop(_3) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_3);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_11 = const "second";
|
||||
_10 = &(*_11);
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
_22 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
|
||||
_13 = &(((*_22) as variant#4).0: std::string::String);
|
||||
_12 = <String as Clone>::clone(move _13) -> [return: bb8, unwind unreachable];
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
_15 = Location::<'_>::caller() -> [return: bb9, unwind unreachable];
|
||||
}
|
||||
|
||||
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);
|
||||
_23 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
|
||||
discriminant((*_23)) = 4;
|
||||
return;
|
||||
}
|
||||
|
||||
bb11: {
|
||||
goto -> bb12;
|
||||
}
|
||||
|
||||
bb12: {
|
||||
StorageDead(_9);
|
||||
drop(_8) -> [return: bb13, unwind unreachable];
|
||||
}
|
||||
|
||||
bb13: {
|
||||
StorageDead(_15);
|
||||
StorageDead(_11);
|
||||
StorageDead(_8);
|
||||
_16 = const ();
|
||||
_24 = deref_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];
|
||||
}
|
||||
|
||||
bb14: {
|
||||
goto -> bb16;
|
||||
}
|
||||
|
||||
bb15: {
|
||||
_0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16);
|
||||
_25 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18});
|
||||
discriminant((*_25)) = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
bb16: {
|
||||
goto -> bb15;
|
||||
}
|
||||
|
||||
bb17: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_3 = move _2;
|
||||
goto -> bb5;
|
||||
}
|
||||
|
||||
bb18: {
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
StorageLive(_11);
|
||||
StorageLive(_15);
|
||||
_8 = move _2;
|
||||
goto -> bb11;
|
||||
}
|
||||
|
||||
bb19: {
|
||||
assert(const false, "coroutine resumed after completion") -> [success: bb19, unwind unreachable];
|
||||
}
|
||||
|
||||
bb20: {
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
ALLOC0 (size: 6, align: 1) {
|
||||
73 65 63 6f 6e 64 │ second
|
||||
}
|
||||
|
||||
ALLOC1 (size: 5, align: 1) {
|
||||
66 69 72 73 74 │ first
|
||||
}
|
||||
29
tests/mir-opt/building/coroutine.rs
Normal file
29
tests/mir-opt/building/coroutine.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// skip-filecheck
|
||||
//@ edition:2024
|
||||
//@ compile-flags: -Zmir-opt-level=0 -C panic=abort
|
||||
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(closure_track_caller)]
|
||||
#![feature(coroutine_trait)]
|
||||
#![feature(coroutines)]
|
||||
|
||||
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
|
||||
fn main() {
|
||||
let simple = #[coroutine]
|
||||
|arg: String| {
|
||||
yield ("first", arg.clone(), Location::caller());
|
||||
yield ("second", arg.clone(), Location::caller());
|
||||
};
|
||||
|
||||
let track_caller = #[track_caller]
|
||||
#[coroutine]
|
||||
|arg: String| {
|
||||
yield ("first", arg.clone(), Location::caller());
|
||||
yield ("second", arg.clone(), Location::caller());
|
||||
};
|
||||
}
|
||||
|
|
@ -7,15 +7,14 @@ fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12
|
|||
let _4: ();
|
||||
let mut _5: ();
|
||||
let mut _6: ();
|
||||
let mut _7: ();
|
||||
let mut _8: u32;
|
||||
let mut _7: u32;
|
||||
scope 1 {
|
||||
debug _s => (((*_1) as variant#3).0: std::string::String);
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_8 = discriminant((*_1));
|
||||
switchInt(move _8) -> [0: bb5, 3: bb8, otherwise: bb9];
|
||||
_7 = discriminant((*_1));
|
||||
switchInt(move _7) -> [0: bb5, 3: bb8, otherwise: bb9];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
|||
|
|
@ -7,15 +7,14 @@ fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12
|
|||
let _4: ();
|
||||
let mut _5: ();
|
||||
let mut _6: ();
|
||||
let mut _7: ();
|
||||
let mut _8: u32;
|
||||
let mut _7: u32;
|
||||
scope 1 {
|
||||
debug _s => (((*_1) as variant#3).0: std::string::String);
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_8 = discriminant((*_1));
|
||||
switchInt(move _8) -> [0: bb7, 3: bb10, otherwise: bb11];
|
||||
_7 = discriminant((*_1));
|
||||
switchInt(move _7) -> [0: bb7, 3: bb10, otherwise: bb11];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// MIR for `main::{closure#0}` 0 coroutine_resume
|
||||
/* coroutine_layout = CoroutineLayout {
|
||||
field_tys: {
|
||||
_0: CoroutineSavedTy {
|
||||
_s0: CoroutineSavedTy {
|
||||
ty: HasDrop,
|
||||
source_info: SourceInfo {
|
||||
span: $DIR/coroutine_tiny.rs:22:13: 22:15 (#0),
|
||||
|
|
@ -14,15 +14,15 @@
|
|||
Unresumed(0): [],
|
||||
Returned (1): [],
|
||||
Panicked (2): [],
|
||||
Suspend0 (3): [_0],
|
||||
Suspend0 (3): [_s0],
|
||||
},
|
||||
storage_conflicts: BitMatrix(1x1) {
|
||||
(_0, _0),
|
||||
(_s0, _s0),
|
||||
},
|
||||
} */
|
||||
|
||||
fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}>, _2: u8) -> CoroutineState<(), ()> {
|
||||
debug _x => _10;
|
||||
debug _x => _2;
|
||||
let mut _0: std::ops::CoroutineState<(), ()>;
|
||||
let _3: HasDrop;
|
||||
let mut _4: !;
|
||||
|
|
@ -31,19 +31,17 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}
|
|||
let mut _7: ();
|
||||
let _8: ();
|
||||
let mut _9: ();
|
||||
let _10: u8;
|
||||
let mut _11: u32;
|
||||
let mut _10: u32;
|
||||
scope 1 {
|
||||
debug _d => (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop);
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_11 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})));
|
||||
switchInt(move _11) -> [0: bb1, 3: bb5, otherwise: bb6];
|
||||
_10 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})));
|
||||
switchInt(move _10) -> [0: bb1, 3: bb5, otherwise: bb6];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_10 = move _2;
|
||||
nop;
|
||||
(((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop) = HasDrop;
|
||||
StorageLive(_4);
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
+ let mut _28: &mut std::task::Context<'_>;
|
||||
+ let mut _29: ();
|
||||
+ let mut _30: ();
|
||||
+ let mut _31: &mut std::task::Context<'_>;
|
||||
+ let mut _32: u32;
|
||||
+ 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()};
|
||||
|
|
@ -48,7 +48,6 @@
|
|||
+ 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()};
|
||||
+ scope 7 {
|
||||
+ let mut _15: std::future::Ready<()>;
|
||||
+ scope 8 {
|
||||
|
|
@ -58,14 +57,14 @@
|
|||
+ scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
|
||||
+ }
|
||||
+ scope 13 (inlined <std::future::Ready<()> as Future>::poll) {
|
||||
+ let mut _42: ();
|
||||
+ let mut _43: std::option::Option<()>;
|
||||
+ let mut _44: &mut std::option::Option<()>;
|
||||
+ let mut _45: &mut std::future::Ready<()>;
|
||||
+ let mut _46: &mut std::pin::Pin<&mut std::future::Ready<()>>;
|
||||
+ 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<()>>;
|
||||
+ scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
|
||||
+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
|
||||
+ let mut _47: &mut &mut std::future::Ready<()>;
|
||||
+ let mut _46: &mut &mut std::future::Ready<()>;
|
||||
+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
|
||||
+ }
|
||||
+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
|
||||
|
|
@ -75,22 +74,22 @@
|
|||
+ }
|
||||
+ }
|
||||
+ scope 19 (inlined Option::<()>::take) {
|
||||
+ let mut _48: std::option::Option<()>;
|
||||
+ let mut _47: std::option::Option<()>;
|
||||
+ scope 20 (inlined std::mem::replace::<Option<()>>) {
|
||||
+ scope 21 {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 22 (inlined #[track_caller] Option::<()>::expect) {
|
||||
+ let mut _49: isize;
|
||||
+ let mut _50: !;
|
||||
+ let mut _48: isize;
|
||||
+ let mut _49: !;
|
||||
+ scope 23 {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 10 (inlined ready::<()>) {
|
||||
+ let mut _41: std::option::Option<()>;
|
||||
+ let mut _40: std::option::Option<()>;
|
||||
+ }
|
||||
+ scope 11 (inlined <std::future::Ready<()> as IntoFuture>::into_future) {
|
||||
+ }
|
||||
|
|
@ -145,10 +144,9 @@
|
|||
+ StorageLive(_37);
|
||||
+ StorageLive(_38);
|
||||
+ StorageLive(_39);
|
||||
+ StorageLive(_40);
|
||||
+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _32 = discriminant((*_33));
|
||||
+ switchInt(move _32) -> [0: bb3, 1: bb10, 3: bb9, otherwise: bb5];
|
||||
+ _32 = deref_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];
|
||||
}
|
||||
|
||||
- bb3: {
|
||||
|
|
@ -158,7 +156,6 @@
|
|||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_40);
|
||||
+ StorageDead(_39);
|
||||
+ StorageDead(_38);
|
||||
+ StorageDead(_37);
|
||||
|
|
@ -186,23 +183,22 @@
|
|||
}
|
||||
|
||||
+ bb3: {
|
||||
+ _31 = move _9;
|
||||
+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ (((*_34) as variant#3).0: ActionPermit<'_, T>) = move ((*_35).0: ActionPermit<'_, T>);
|
||||
+ (((*_33) as variant#3).0: ActionPermit<'_, T>) = move ((*_34).0: ActionPermit<'_, T>);
|
||||
+ StorageLive(_12);
|
||||
+ StorageLive(_13);
|
||||
+ StorageLive(_14);
|
||||
+ _14 = ();
|
||||
+ StorageLive(_41);
|
||||
+ _41 = Option::<()>::Some(copy _14);
|
||||
+ _13 = std::future::Ready::<()>(move _41);
|
||||
+ StorageDead(_41);
|
||||
+ StorageLive(_40);
|
||||
+ _40 = Option::<()>::Some(copy _14);
|
||||
+ _13 = std::future::Ready::<()>(move _40);
|
||||
+ StorageDead(_40);
|
||||
+ StorageDead(_14);
|
||||
+ _12 = move _13;
|
||||
+ StorageDead(_13);
|
||||
+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ (((*_36) as variant#3).1: std::future::Ready<()>) = move _12;
|
||||
+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ (((*_35) as variant#3).1: std::future::Ready<()>) = move _12;
|
||||
+ goto -> bb4;
|
||||
+ }
|
||||
+
|
||||
|
|
@ -214,39 +210,39 @@
|
|||
+ StorageLive(_19);
|
||||
+ StorageLive(_20);
|
||||
+ StorageLive(_21);
|
||||
+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>);
|
||||
+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _21 = &mut (((*_36) as variant#3).1: std::future::Ready<()>);
|
||||
+ _20 = &mut (*_21);
|
||||
+ _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 };
|
||||
+ StorageDead(_20);
|
||||
+ StorageLive(_22);
|
||||
+ StorageLive(_23);
|
||||
+ StorageLive(_24);
|
||||
+ _24 = copy _31;
|
||||
+ _24 = copy _9;
|
||||
+ _23 = move _24;
|
||||
+ _22 = &mut (*_23);
|
||||
+ StorageDead(_24);
|
||||
+ StorageLive(_44);
|
||||
+ StorageLive(_45);
|
||||
+ StorageLive(_46);
|
||||
+ StorageLive(_50);
|
||||
+ StorageLive(_49);
|
||||
+ StorageLive(_41);
|
||||
+ StorageLive(_42);
|
||||
+ StorageLive(_43);
|
||||
+ StorageLive(_44);
|
||||
+ _46 = &mut _19;
|
||||
+ _45 = &mut _19;
|
||||
+ StorageLive(_46);
|
||||
+ _46 = &mut (_19.0: &mut std::future::Ready<()>);
|
||||
+ _44 = copy (_19.0: &mut std::future::Ready<()>);
|
||||
+ StorageDead(_46);
|
||||
+ _43 = &mut ((*_44).0: std::option::Option<()>);
|
||||
+ StorageLive(_47);
|
||||
+ _47 = &mut (_19.0: &mut std::future::Ready<()>);
|
||||
+ _45 = copy (_19.0: &mut std::future::Ready<()>);
|
||||
+ _47 = Option::<()>::None;
|
||||
+ _42 = copy ((*_44).0: std::option::Option<()>);
|
||||
+ ((*_44).0: std::option::Option<()>) = copy _47;
|
||||
+ StorageDead(_47);
|
||||
+ _44 = &mut ((*_45).0: std::option::Option<()>);
|
||||
+ StorageDead(_43);
|
||||
+ StorageLive(_48);
|
||||
+ _48 = Option::<()>::None;
|
||||
+ _43 = copy ((*_45).0: std::option::Option<()>);
|
||||
+ ((*_45).0: std::option::Option<()>) = copy _48;
|
||||
+ StorageDead(_48);
|
||||
+ StorageDead(_44);
|
||||
+ StorageLive(_49);
|
||||
+ _49 = discriminant(_43);
|
||||
+ switchInt(move _49) -> [0: bb11, 1: bb12, otherwise: bb5];
|
||||
+ _48 = discriminant(_42);
|
||||
+ switchInt(move _48) -> [0: bb11, 1: bb12, otherwise: bb5];
|
||||
}
|
||||
+
|
||||
+ bb5: {
|
||||
|
|
@ -266,8 +262,8 @@
|
|||
+ StorageDead(_12);
|
||||
+ StorageDead(_28);
|
||||
+ StorageDead(_29);
|
||||
+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_38)) = 3;
|
||||
+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_37)) = 3;
|
||||
+ goto -> bb2;
|
||||
+ }
|
||||
+
|
||||
|
|
@ -281,14 +277,14 @@
|
|||
+ StorageDead(_18);
|
||||
+ StorageDead(_17);
|
||||
+ StorageDead(_12);
|
||||
+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable];
|
||||
+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ drop((((*_38) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb8: {
|
||||
+ _7 = Poll::<()>::Ready(move _30);
|
||||
+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_40)) = 1;
|
||||
+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_39)) = 1;
|
||||
+ goto -> bb2;
|
||||
+ }
|
||||
+
|
||||
|
|
@ -298,7 +294,7 @@
|
|||
+ StorageLive(_29);
|
||||
+ _28 = move _9;
|
||||
+ StorageDead(_29);
|
||||
+ _31 = move _28;
|
||||
+ _9 = move _28;
|
||||
+ StorageDead(_28);
|
||||
+ _16 = const ();
|
||||
+ goto -> bb4;
|
||||
|
|
@ -309,18 +305,18 @@
|
|||
+ }
|
||||
+
|
||||
+ bb11: {
|
||||
+ _50 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
|
||||
+ _49 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
|
||||
+ }
|
||||
+
|
||||
+ bb12: {
|
||||
+ _42 = move ((_43 as Some).0: ());
|
||||
+ StorageDead(_49);
|
||||
+ StorageDead(_43);
|
||||
+ _18 = Poll::<()>::Ready(move _42);
|
||||
+ _41 = move ((_42 as Some).0: ());
|
||||
+ StorageDead(_48);
|
||||
+ StorageDead(_42);
|
||||
+ StorageDead(_50);
|
||||
+ StorageDead(_46);
|
||||
+ _18 = Poll::<()>::Ready(move _41);
|
||||
+ StorageDead(_41);
|
||||
+ StorageDead(_49);
|
||||
+ StorageDead(_45);
|
||||
+ StorageDead(_44);
|
||||
+ StorageDead(_22);
|
||||
+ StorageDead(_19);
|
||||
+ _25 = discriminant(_18);
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
+ let mut _28: &mut std::task::Context<'_>;
|
||||
+ let mut _29: ();
|
||||
+ let mut _30: ();
|
||||
+ let mut _31: &mut std::task::Context<'_>;
|
||||
+ let mut _32: u32;
|
||||
+ 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()};
|
||||
|
|
@ -50,7 +50,6 @@
|
|||
+ 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()};
|
||||
+ let mut _42: &mut {async fn body of ActionPermit<'_, T>::perform()};
|
||||
+ scope 7 {
|
||||
+ let mut _15: std::future::Ready<()>;
|
||||
+ scope 8 {
|
||||
|
|
@ -60,14 +59,14 @@
|
|||
+ scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
|
||||
+ }
|
||||
+ scope 13 (inlined <std::future::Ready<()> as Future>::poll) {
|
||||
+ let mut _44: ();
|
||||
+ let mut _45: std::option::Option<()>;
|
||||
+ let mut _46: &mut std::option::Option<()>;
|
||||
+ let mut _47: &mut std::future::Ready<()>;
|
||||
+ let mut _48: &mut std::pin::Pin<&mut std::future::Ready<()>>;
|
||||
+ 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<()>>;
|
||||
+ scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
|
||||
+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
|
||||
+ let mut _49: &mut &mut std::future::Ready<()>;
|
||||
+ let mut _48: &mut &mut std::future::Ready<()>;
|
||||
+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
|
||||
+ }
|
||||
+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
|
||||
|
|
@ -77,22 +76,22 @@
|
|||
+ }
|
||||
+ }
|
||||
+ scope 19 (inlined Option::<()>::take) {
|
||||
+ let mut _50: std::option::Option<()>;
|
||||
+ let mut _49: std::option::Option<()>;
|
||||
+ scope 20 (inlined std::mem::replace::<Option<()>>) {
|
||||
+ scope 21 {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 22 (inlined #[track_caller] Option::<()>::expect) {
|
||||
+ let mut _51: isize;
|
||||
+ let mut _52: !;
|
||||
+ let mut _50: isize;
|
||||
+ let mut _51: !;
|
||||
+ scope 23 {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 10 (inlined ready::<()>) {
|
||||
+ let mut _43: std::option::Option<()>;
|
||||
+ let mut _42: std::option::Option<()>;
|
||||
+ }
|
||||
+ scope 11 (inlined <std::future::Ready<()> as IntoFuture>::into_future) {
|
||||
+ }
|
||||
|
|
@ -149,10 +148,9 @@
|
|||
+ StorageLive(_39);
|
||||
+ StorageLive(_40);
|
||||
+ StorageLive(_41);
|
||||
+ StorageLive(_42);
|
||||
+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _32 = discriminant((*_33));
|
||||
+ switchInt(move _32) -> [0: bb5, 1: bb15, 2: bb14, 3: bb13, otherwise: bb7];
|
||||
+ _32 = deref_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];
|
||||
}
|
||||
|
||||
- bb3: {
|
||||
|
|
@ -170,7 +168,6 @@
|
|||
+ }
|
||||
+
|
||||
+ bb4: {
|
||||
+ StorageDead(_42);
|
||||
+ StorageDead(_41);
|
||||
+ StorageDead(_40);
|
||||
+ StorageDead(_39);
|
||||
|
|
@ -203,23 +200,22 @@
|
|||
- StorageDead(_2);
|
||||
- return;
|
||||
+ bb5: {
|
||||
+ _31 = move _9;
|
||||
+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ (((*_34) as variant#3).0: ActionPermit<'_, T>) = move ((*_35).0: ActionPermit<'_, T>);
|
||||
+ (((*_33) as variant#3).0: ActionPermit<'_, T>) = move ((*_34).0: ActionPermit<'_, T>);
|
||||
+ StorageLive(_12);
|
||||
+ StorageLive(_13);
|
||||
+ StorageLive(_14);
|
||||
+ _14 = ();
|
||||
+ StorageLive(_43);
|
||||
+ _43 = Option::<()>::Some(copy _14);
|
||||
+ _13 = std::future::Ready::<()>(move _43);
|
||||
+ StorageDead(_43);
|
||||
+ StorageLive(_42);
|
||||
+ _42 = Option::<()>::Some(copy _14);
|
||||
+ _13 = std::future::Ready::<()>(move _42);
|
||||
+ StorageDead(_42);
|
||||
+ StorageDead(_14);
|
||||
+ _12 = move _13;
|
||||
+ StorageDead(_13);
|
||||
+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ (((*_36) as variant#3).1: std::future::Ready<()>) = move _12;
|
||||
+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ (((*_35) as variant#3).1: std::future::Ready<()>) = move _12;
|
||||
+ goto -> bb6;
|
||||
}
|
||||
|
||||
|
|
@ -231,39 +227,39 @@
|
|||
+ StorageLive(_19);
|
||||
+ StorageLive(_20);
|
||||
+ StorageLive(_21);
|
||||
+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>);
|
||||
+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ _21 = &mut (((*_36) as variant#3).1: std::future::Ready<()>);
|
||||
+ _20 = &mut (*_21);
|
||||
+ _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 };
|
||||
+ StorageDead(_20);
|
||||
+ StorageLive(_22);
|
||||
+ StorageLive(_23);
|
||||
+ StorageLive(_24);
|
||||
+ _24 = copy _31;
|
||||
+ _24 = copy _9;
|
||||
+ _23 = move _24;
|
||||
+ _22 = &mut (*_23);
|
||||
+ StorageDead(_24);
|
||||
+ StorageLive(_46);
|
||||
+ StorageLive(_47);
|
||||
+ StorageLive(_48);
|
||||
+ StorageLive(_52);
|
||||
+ StorageLive(_51);
|
||||
+ StorageLive(_43);
|
||||
+ StorageLive(_44);
|
||||
+ StorageLive(_45);
|
||||
+ StorageLive(_46);
|
||||
+ _48 = &mut _19;
|
||||
+ _47 = &mut _19;
|
||||
+ StorageLive(_48);
|
||||
+ _48 = &mut (_19.0: &mut std::future::Ready<()>);
|
||||
+ _46 = copy (_19.0: &mut std::future::Ready<()>);
|
||||
+ StorageDead(_48);
|
||||
+ _45 = &mut ((*_46).0: std::option::Option<()>);
|
||||
+ StorageLive(_49);
|
||||
+ _49 = &mut (_19.0: &mut std::future::Ready<()>);
|
||||
+ _47 = copy (_19.0: &mut std::future::Ready<()>);
|
||||
+ _49 = Option::<()>::None;
|
||||
+ _44 = copy ((*_46).0: std::option::Option<()>);
|
||||
+ ((*_46).0: std::option::Option<()>) = copy _49;
|
||||
+ StorageDead(_49);
|
||||
+ _46 = &mut ((*_47).0: std::option::Option<()>);
|
||||
+ StorageDead(_45);
|
||||
+ StorageLive(_50);
|
||||
+ _50 = Option::<()>::None;
|
||||
+ _45 = copy ((*_47).0: std::option::Option<()>);
|
||||
+ ((*_47).0: std::option::Option<()>) = copy _50;
|
||||
+ StorageDead(_50);
|
||||
+ StorageDead(_46);
|
||||
+ StorageLive(_51);
|
||||
+ _51 = discriminant(_45);
|
||||
+ switchInt(move _51) -> [0: bb16, 1: bb17, otherwise: bb7];
|
||||
+ _50 = discriminant(_44);
|
||||
+ switchInt(move _50) -> [0: bb16, 1: bb17, otherwise: bb7];
|
||||
}
|
||||
|
||||
- bb6 (cleanup): {
|
||||
|
|
@ -285,8 +281,8 @@
|
|||
+ StorageDead(_12);
|
||||
+ StorageDead(_28);
|
||||
+ StorageDead(_29);
|
||||
+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_38)) = 3;
|
||||
+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_37)) = 3;
|
||||
+ goto -> bb4;
|
||||
+ }
|
||||
+
|
||||
|
|
@ -300,14 +296,14 @@
|
|||
+ StorageDead(_18);
|
||||
+ StorageDead(_17);
|
||||
+ StorageDead(_12);
|
||||
+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12];
|
||||
+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ drop((((*_38) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12];
|
||||
+ }
|
||||
+
|
||||
+ bb10: {
|
||||
+ _7 = Poll::<()>::Ready(move _30);
|
||||
+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_40)) = 1;
|
||||
+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_39)) = 1;
|
||||
+ goto -> bb4;
|
||||
+ }
|
||||
+
|
||||
|
|
@ -319,13 +315,13 @@
|
|||
+ StorageDead(_18);
|
||||
+ StorageDead(_17);
|
||||
+ StorageDead(_12);
|
||||
+ _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)];
|
||||
+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ drop((((*_40) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)];
|
||||
+ }
|
||||
+
|
||||
+ bb12 (cleanup): {
|
||||
+ _42 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_42)) = 2;
|
||||
+ _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
|
||||
+ discriminant((*_41)) = 2;
|
||||
+ goto -> bb2;
|
||||
+ }
|
||||
+
|
||||
|
|
@ -335,7 +331,7 @@
|
|||
+ StorageLive(_29);
|
||||
+ _28 = move _9;
|
||||
+ StorageDead(_29);
|
||||
+ _31 = move _28;
|
||||
+ _9 = move _28;
|
||||
+ StorageDead(_28);
|
||||
+ _16 = const ();
|
||||
+ goto -> bb6;
|
||||
|
|
@ -350,18 +346,18 @@
|
|||
+ }
|
||||
+
|
||||
+ bb16: {
|
||||
+ _52 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
|
||||
+ _51 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
|
||||
+ }
|
||||
+
|
||||
+ bb17: {
|
||||
+ _44 = move ((_45 as Some).0: ());
|
||||
+ StorageDead(_51);
|
||||
+ StorageDead(_45);
|
||||
+ _18 = Poll::<()>::Ready(move _44);
|
||||
+ _43 = move ((_44 as Some).0: ());
|
||||
+ StorageDead(_50);
|
||||
+ StorageDead(_44);
|
||||
+ StorageDead(_52);
|
||||
+ StorageDead(_48);
|
||||
+ _18 = Poll::<()>::Ready(move _43);
|
||||
+ StorageDead(_43);
|
||||
+ StorageDead(_51);
|
||||
+ StorageDead(_47);
|
||||
+ StorageDead(_46);
|
||||
+ StorageDead(_22);
|
||||
+ StorageDead(_19);
|
||||
+ _25 = discriminant(_18);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ compile-flags: -Z unpretty=stable-mir --crate-type lib -C panic=abort -Zmir-opt-level=0
|
||||
//@ check-pass
|
||||
//@ only-x86_64
|
||||
//@ only-64bit
|
||||
//@ edition: 2024
|
||||
//@ needs-unwind unwind edges are different with panic=abort
|
||||
|
||||
|
|
|
|||
|
|
@ -40,30 +40,28 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo
|
|||
let _3: i32;
|
||||
let mut _4: &i32;
|
||||
let mut _5: ();
|
||||
let mut _6: &mut Context<'_>;
|
||||
let mut _7: u32;
|
||||
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};
|
||||
let mut _10: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
|
||||
debug _task_context => _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 => _3;
|
||||
bb0: {
|
||||
_8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
_7 = discriminant((*_8));
|
||||
switchInt(move _7) -> [0: bb1, 1: bb2, otherwise: bb3];
|
||||
_7 = CopyForDeref((_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];
|
||||
}
|
||||
bb1: {
|
||||
_6 = move _2;
|
||||
StorageLive(_3);
|
||||
_9 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
_4 = CopyForDeref(((*_9).0: &i32));
|
||||
_8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
_4 = CopyForDeref(((*_8).0: &i32));
|
||||
_3 = (*_4);
|
||||
_5 = ();
|
||||
StorageDead(_3);
|
||||
_0 = std::task::Poll::Ready(move _5);
|
||||
_10 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
discriminant((*_10)) = 1;
|
||||
_9 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
discriminant((*_9)) = 1;
|
||||
return;
|
||||
}
|
||||
bb2: {
|
||||
|
|
@ -78,30 +76,28 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c
|
|||
let _3: i32;
|
||||
let mut _4: &i32;
|
||||
let mut _5: ();
|
||||
let mut _6: &mut Context<'_>;
|
||||
let mut _7: u32;
|
||||
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};
|
||||
let mut _10: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
|
||||
debug _task_context => _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 => _3;
|
||||
bb0: {
|
||||
_8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
_7 = discriminant((*_8));
|
||||
switchInt(move _7) -> [0: bb1, 1: bb2, otherwise: bb3];
|
||||
_7 = CopyForDeref((_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];
|
||||
}
|
||||
bb1: {
|
||||
_6 = move _2;
|
||||
StorageLive(_3);
|
||||
_9 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
_4 = CopyForDeref(((*_9).0: &i32));
|
||||
_8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
_4 = CopyForDeref(((*_8).0: &i32));
|
||||
_3 = (*_4);
|
||||
_5 = ();
|
||||
StorageDead(_3);
|
||||
_0 = std::task::Poll::Ready(move _5);
|
||||
_10 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
discriminant((*_10)) = 1;
|
||||
_9 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
|
||||
discriminant((*_9)) = 1;
|
||||
return;
|
||||
}
|
||||
bb2: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue