From 5e529b0e94ff5873f48ecdc7c802e31442183d57 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Wed, 8 Oct 2025 19:44:41 +0000 Subject: [PATCH 1/3] Only load pin field once. --- compiler/rustc_mir_transform/src/coroutine.rs | 55 ++++--- .../rustc_mir_transform/src/coroutine/drop.rs | 7 +- ...#0}.coroutine_drop_async.0.panic-abort.mir | 14 +- ...0}.coroutine_drop_async.0.panic-unwind.mir | 16 ++- ...await.a-{closure#0}.coroutine_resume.0.mir | 6 +- ...await.b-{closure#0}.coroutine_resume.0.mir | 26 ++-- ....main-{closure#0}.StateTransform.after.mir | 30 ++-- ....main-{closure#1}.StateTransform.after.mir | 30 ++-- ...ny.main-{closure#0}.coroutine_resume.0.mir | 10 +- ...y.run2-{closure#0}.Inline.panic-abort.diff | 120 ++++++---------- ....run2-{closure#0}.Inline.panic-unwind.diff | 134 +++++++----------- .../async-closure.stdout | 20 +-- 12 files changed, 198 insertions(+), 270 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index c136df812a3f0..a5b8b41e276ae 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -130,8 +130,8 @@ struct SelfArgVisitor<'tcx> { } impl<'tcx> SelfArgVisitor<'tcx> { - fn new(tcx: TyCtxt<'tcx>, elem: ProjectionElem>) -> 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 } } } @@ -144,16 +144,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); } } } @@ -484,19 +482,21 @@ fn make_aggregate_adt<'tcx>( } 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); } 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); @@ -504,11 +504,28 @@ 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); + body.basic_blocks_mut()[START_BLOCK].statements.insert( + 0, + Statement::new( + source_info, + StatementKind::Assign(Box::new(( + unpinned_local.into(), + Rvalue::CopyForDeref(tcx.mk_place_field( + SELF_ARG.into(), + FieldIdx::ZERO, + ref_coroutine_ty, + )), + ))), + ), + ); } /// Allocates a new local and replaces all references of `local` with it. Returns the new local. @@ -1274,8 +1291,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, _) => @@ -1284,7 +1299,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 diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index fd2d8b2b0563e..6fbee2f203416 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -676,12 +676,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); } diff --git a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir index 050aac7c3ff05..b81a16322fc1f 100644 --- a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir +++ b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir @@ -2,7 +2,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { debug _task_context => _2; - debug x => ((*(_1.0: &mut {async fn body of a()})).0: T); + debug x => ((*_20).0: T); let mut _0: std::task::Poll<()>; let _3: T; let mut _4: impl std::future::Future; @@ -21,12 +21,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) let mut _17: std::pin::Pin<&mut impl std::future::Future>; let mut _18: isize; let mut _19: u32; + let mut _20: &mut {async fn body of a()}; scope 1 { - debug x => (((*(_1.0: &mut {async fn body of a()})) as variant#4).0: T); + debug x => (((*_20) as variant#4).0: T); } bb0: { - _19 = discriminant((*(_1.0: &mut {async fn body of a()}))); + _20 = deref_copy (_1.0: &mut {async fn body of a()}); + _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()}>, _2: &mut Context<'_>) bb3: { _0 = Poll::<()>::Pending; - discriminant((*(_1.0: &mut {async fn body of a()}))) = 4; + discriminant((*_20)) = 4; return; } bb4: { StorageLive(_17); - _16 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); + _16 = &mut (((*_20) as variant#4).1: impl std::future::Future); _17 = Pin::<&mut impl Future>::new_unchecked(move _16) -> [return: bb7, unwind unreachable]; } @@ -81,7 +83,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb11: { - drop(((*(_1.0: &mut {async fn body of a()})).0: T)) -> [return: bb10, unwind unreachable]; + drop(((*_20).0: T)) -> [return: bb10, unwind unreachable]; } bb12: { diff --git a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir index 796e95ff3d825..cda899474b931 100644 --- a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir +++ b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir @@ -2,7 +2,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { debug _task_context => _2; - debug x => ((*(_1.0: &mut {async fn body of a()})).0: T); + debug x => ((*_20).0: T); let mut _0: std::task::Poll<()>; let _3: T; let mut _4: impl std::future::Future; @@ -21,12 +21,14 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) let mut _17: std::pin::Pin<&mut impl std::future::Future>; let mut _18: isize; let mut _19: u32; + let mut _20: &mut {async fn body of a()}; scope 1 { - debug x => (((*(_1.0: &mut {async fn body of a()})) as variant#4).0: T); + debug x => (((*_20) as variant#4).0: T); } bb0: { - _19 = discriminant((*(_1.0: &mut {async fn body of a()}))); + _20 = deref_copy (_1.0: &mut {async fn body of a()}); + _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()}>, _2: &mut Context<'_>) bb6: { _0 = Poll::<()>::Pending; - discriminant((*(_1.0: &mut {async fn body of a()}))) = 4; + discriminant((*_20)) = 4; return; } bb7: { StorageLive(_17); - _16 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); + _16 = &mut (((*_20) as variant#4).1: impl std::future::Future); _17 = Pin::<&mut impl Future>::new_unchecked(move _16) -> [return: bb10, unwind: bb15]; } @@ -95,11 +97,11 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb14: { - drop(((*(_1.0: &mut {async fn body of a()})).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()}))) = 2; + discriminant((*_20)) = 2; resume; } diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir index 2e2876cb3fcf2..b42f22f93825d 100644 --- a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir @@ -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 = deref_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; } diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir index 20fc4112ef288..2700ee253a45d 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -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 = deref_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; } diff --git a/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir b/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir index d8fdb446135b3..29fee4bb46465 100644 --- a/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir +++ b/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir @@ -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 = deref_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 = deref_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 = deref_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 = ::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 = deref_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 = deref_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 = ::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 = deref_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 = 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]; + 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 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); - discriminant((*_25)) = 1; + discriminant((*_18)) = 1; return; } diff --git a/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir b/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir index dd17afad656b8..a96fcaa9b3694 100644 --- a/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir +++ b/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir @@ -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 = deref_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 = deref_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 = deref_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 = ::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 = deref_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 = deref_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 = ::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 = deref_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 = 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]; + 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 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); - discriminant((*_25)) = 1; + discriminant((*_18)) = 1; return; } diff --git a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir index 9905cc3e00f99..5d66b42c000c8 100644 --- a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir @@ -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 = deref_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; } diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index 0203ff52d63f8..f888101503cee 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff @@ -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 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 > 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 > 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::>) { + 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 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 = 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]; @@ -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 = 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()}); -+ (((*_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 = deref_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 = deref_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 = deref_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 = deref_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 = deref_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); diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index 6c8cad3e992e7..d8ec238b4a874 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -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 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 > 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 > 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::>) { + 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 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 = 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]; @@ -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 = 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()}); -+ (((*_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 = deref_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 = deref_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 = deref_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 = deref_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 = deref_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 = 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)]; ++ drop((((*_32) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)]; + } + + bb12 (cleanup): { -+ _41 = deref_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); diff --git a/tests/ui/rustc_public-ir-print/async-closure.stdout b/tests/ui/rustc_public-ir-print/async-closure.stdout index 5113dc5048b93..f5b5a26a06c6c 100644 --- a/tests/ui/rustc_public-ir-print/async-closure.stdout +++ b/tests/ui/rustc_public-ir-print/async-closure.stdout @@ -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 = CopyForDeref((_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 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - _4 = CopyForDeref(((*_8).0: &i32)); + _4 = CopyForDeref(((*_7).0: &i32)); _3 = (*_4); _5 = (); StorageDead(_3); _0 = std::task::Poll::Ready(move _5); - _9 = CopyForDeref((_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 = CopyForDeref((_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 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - _4 = CopyForDeref(((*_8).0: &i32)); + _4 = CopyForDeref(((*_7).0: &i32)); _3 = (*_4); _5 = (); StorageDead(_3); _0 = std::task::Poll::Ready(move _5); - _9 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - discriminant((*_9)) = 1; + discriminant((*_7)) = 1; return; } bb2: { From 1d7f4eb1082bcb8582854856130d0c19bbcfd88e Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Wed, 8 Oct 2025 22:44:32 +0000 Subject: [PATCH 2/3] Simplify assignment. --- compiler/rustc_mir_transform/src/coroutine.rs | 8 +++----- ...d.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir | 2 +- ....a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir | 2 +- .../async_await.a-{closure#0}.coroutine_resume.0.mir | 2 +- .../async_await.b-{closure#0}.coroutine_resume.0.mir | 2 +- .../coroutine.main-{closure#0}.StateTransform.after.mir | 2 +- .../coroutine.main-{closure#1}.StateTransform.after.mir | 2 +- ...coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir | 2 +- ...oroutine_body.run2-{closure#0}.Inline.panic-abort.diff | 2 +- ...routine_body.run2-{closure#0}.Inline.panic-unwind.diff | 2 +- tests/ui/rustc_public-ir-print/async-closure.stdout | 4 ++-- 11 files changed, 14 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index a5b8b41e276ae..1765b530fb512 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -512,17 +512,15 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut 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); + body.basic_blocks_mut()[START_BLOCK].statements.insert( 0, Statement::new( source_info, StatementKind::Assign(Box::new(( unpinned_local.into(), - Rvalue::CopyForDeref(tcx.mk_place_field( - SELF_ARG.into(), - FieldIdx::ZERO, - ref_coroutine_ty, - )), + Rvalue::Use(Operand::Copy(pin_field)), ))), ), ); diff --git a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir index b81a16322fc1f..8cb062ba397c8 100644 --- a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir +++ b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir @@ -27,7 +27,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb0: { - _20 = deref_copy (_1.0: &mut {async fn body of a()}); + _20 = copy (_1.0: &mut {async fn body of a()}); _19 = discriminant((*_20)); switchInt(move _19) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14]; } diff --git a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir index cda899474b931..682ecc87a2969 100644 --- a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir +++ b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir @@ -27,7 +27,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb0: { - _20 = deref_copy (_1.0: &mut {async fn body of a()}); + _20 = copy (_1.0: &mut {async fn body of a()}); _19 = discriminant((*_20)); switchInt(move _19) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19]; } diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir index b42f22f93825d..6cad5b105d3e3 100644 --- a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir @@ -17,7 +17,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> let mut _5: &mut {async fn body of a()}; bb0: { - _5 = deref_copy (_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]; } diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir index 2700ee253a45d..96ee37185db16 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -103,7 +103,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> } bb0: { - _39 = deref_copy (_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]; } diff --git a/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir b/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir index 29fee4bb46465..b61215dc28cb4 100644 --- a/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir +++ b/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir @@ -43,7 +43,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2 let mut _18: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; bb0: { - _18 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + _18 = 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]; } diff --git a/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir b/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir index a96fcaa9b3694..aac028a9e6c0e 100644 --- a/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir +++ b/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir @@ -43,7 +43,7 @@ fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2 let mut _18: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; bb0: { - _18 = deref_copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + _18 = 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]; } diff --git a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir index 5d66b42c000c8..222c7144ef07d 100644 --- a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir @@ -38,7 +38,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13} } bb0: { - _11 = deref_copy (_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]; } diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index f888101503cee..d680e20a9ac50 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff @@ -125,7 +125,7 @@ + StorageLive(_30); + StorageLive(_31); + StorageLive(_32); -+ _32 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _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]; } diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index d8ec238b4a874..a2ce269aea312 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -125,7 +125,7 @@ + StorageLive(_30); + StorageLive(_31); + StorageLive(_32); -+ _32 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _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]; } diff --git a/tests/ui/rustc_public-ir-print/async-closure.stdout b/tests/ui/rustc_public-ir-print/async-closure.stdout index f5b5a26a06c6c..e248aafdc85cb 100644 --- a/tests/ui/rustc_public-ir-print/async-closure.stdout +++ b/tests/ui/rustc_public-ir-print/async-closure.stdout @@ -46,7 +46,7 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo debug y => (*((*_7).0: &i32)); debug y => _3; bb0: { - _7 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); + _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]; } @@ -78,7 +78,7 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c debug y => (*((*_7).0: &i32)); debug y => _3; bb0: { - _7 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); + _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]; } From 081e7494feec13c5acdab591e703ca22ded0e6ae Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Wed, 8 Oct 2025 22:45:09 +0000 Subject: [PATCH 3/3] Insert assignment after Retag. --- compiler/rustc_mir_transform/src/coroutine.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 1765b530fb512..6b697455d7610 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -514,8 +514,15 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body let source_info = SourceInfo::outermost(body.span); let pin_field = tcx.mk_place_field(SELF_ARG.into(), FieldIdx::ZERO, ref_coroutine_ty); - body.basic_blocks_mut()[START_BLOCK].statements.insert( - 0, + 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((