From 20b1084d8312867846fe8c5be40d443b69847acb Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Wed, 20 Aug 2025 23:24:03 +0000 Subject: [PATCH] Replace ResumeTy with an unsafe binder ty. --- compiler/rustc_ast_lowering/src/expr.rs | 9 +- .../rustc_borrowck/src/places_conflict.rs | 10 +- .../src/debuginfo/metadata.rs | 3 + compiler/rustc_hir/src/lang_items.rs | 3 +- compiler/rustc_middle/src/ty/sty.rs | 23 ++ compiler/rustc_mir_transform/src/coroutine.rs | 130 ++------- .../rustc_mir_transform/src/coroutine/drop.rs | 16 +- .../src/shim/async_destructor_ctor.rs | 3 +- compiler/rustc_ty_utils/src/abi.rs | 24 +- library/core/src/future/mod.rs | 15 +- library/core/src/lib.rs | 1 + ...oo-{closure#0}-{closure#0}.built.after.mir | 2 +- ...-{closure#0}-{synthetic#0}.built.after.mir | 2 +- ...0}-{closure#0}-{closure#0}.built.after.mir | 2 +- ...-{closure#0}-{synthetic#0}.built.after.mir | 2 +- ...0}-{closure#1}-{closure#0}.built.after.mir | 2 +- ...-{closure#1}-{synthetic#0}.built.after.mir | 2 +- ...#0}.coroutine_drop_async.0.panic-abort.mir | 8 +- ...0}.coroutine_drop_async.0.panic-unwind.mir | 8 +- ...await.a-{closure#0}.coroutine_resume.0.mir | 4 +- ...await.b-{closure#0}.coroutine_resume.0.mir | 274 ++++++++---------- ...y.run2-{closure#0}.Inline.panic-abort.diff | 177 ++++++----- ....run2-{closure#0}.Inline.panic-unwind.diff | 186 ++++++------ .../async-closures/def-path.stderr | 4 +- 24 files changed, 399 insertions(+), 511 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index bb6b25baf013d..e65e7a232179f 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -927,10 +927,13 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::LangItem::PinNewUnchecked, arena_vec![self; ref_mut_awaitee], ); - let get_context = self.expr_call_lang_item_fn_mut( + let get_context = self.expr( gen_future_span, - hir::LangItem::GetContext, - arena_vec![self; task_context], + hir::ExprKind::UnsafeBinderCast( + UnsafeBinderCastKind::Unwrap, + self.arena.alloc(task_context), + None, + ), ); let call = match await_kind { FutureKind::Future => self.expr_call_lang_item_fn( diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index cf3e82426e8a0..efe35163bc1e5 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -307,6 +307,11 @@ fn place_projection_conflict<'tcx>( debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE"); Overlap::EqualOrDisjoint } + (ProjectionElem::UnwrapUnsafeBinder(_), ProjectionElem::UnwrapUnsafeBinder(_)) => { + // casts to other types may always conflict irrespective of the type being cast to. + debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE"); + Overlap::EqualOrDisjoint + } (ProjectionElem::Field(f1, _), ProjectionElem::Field(f2, _)) => { if f1 == f2 { // same field (e.g., `a.y` vs. `a.y`) - recur. @@ -512,6 +517,7 @@ fn place_projection_conflict<'tcx>( | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subtype(_) | ProjectionElem::OpaqueCast { .. } + | ProjectionElem::UnwrapUnsafeBinder { .. } | ProjectionElem::Subslice { .. } | ProjectionElem::Downcast(..), _, @@ -520,9 +526,5 @@ fn place_projection_conflict<'tcx>( pi1_elem, pi2_elem ), - - (ProjectionElem::UnwrapUnsafeBinder(_), _) => { - todo!() - } } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index dc3a84b6a151a..65c5c285b8a46 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -474,6 +474,9 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>( AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span), }, ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id), + ty::UnsafeBinder(binder) => { + return type_di_node(cx, cx.tcx.instantiate_bound_regions_with_erased(*binder)); + } _ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t), }; diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 67d2f15d41472..0c12db91a72f0 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -382,8 +382,7 @@ language_item_table! { // FIXME(swatinem): the following lang items are used for async lowering and // should become obsolete eventually. - ResumeTy, sym::ResumeTy, resume_ty, Target::Struct, GenericRequirement::None; - GetContext, sym::get_context, get_context_fn, Target::Fn, GenericRequirement::None; + ResumeTy, sym::ResumeTy, resume_ty, Target::TyAlias, GenericRequirement::None; Context, sym::Context, context, Target::Struct, GenericRequirement::None; FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 755fc68d86f34..852b1220c4567 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -909,6 +909,29 @@ impl<'tcx> Ty<'tcx> { Ty::new_generic_adt(tcx, def_id, ty) } + /// Creates a `unsafe<'a, 'b> &'a mut Context<'b>` [`Ty`]. + pub fn new_resume_ty(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + let context_did = tcx.require_lang_item(LangItem::Context, DUMMY_SP); + let context_adt_ref = tcx.adt_def(context_did); + + let lt = |n| { + ty::Region::new_bound( + tcx, + ty::INNERMOST, + ty::BoundRegion { var: ty::BoundVar::from_u32(n), kind: BoundRegionKind::Anon }, + ) + }; + + let context_args = tcx.mk_args(&[lt(1).into()]); + let context_ty = Ty::new_adt(tcx, context_adt_ref, context_args); + let context_mut_ref = Ty::new_mut_ref(tcx, lt(0), context_ty); + let bound_vars = tcx.mk_bound_variable_kinds(&[ + BoundVariableKind::Region(BoundRegionKind::Anon), + BoundVariableKind::Region(BoundRegionKind::Anon), + ]); + Ty::new_unsafe_binder(tcx, ty::Binder::bind_with_vars(context_mut_ref, bound_vars)) + } + /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes. pub fn new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { let context_did = tcx.require_lang_item(LangItem::Context, DUMMY_SP); diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 4603c695dedd5..7ced69b4b334d 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -211,6 +211,9 @@ struct TransformVisitor<'tcx> { old_yield_ty: Ty<'tcx>, old_ret_ty: Ty<'tcx>, + + /// The rvalue that should be assigned to yield `resume_arg` place. + resume_rvalue: Rvalue<'tcx>, } impl<'tcx> TransformVisitor<'tcx> { @@ -533,100 +536,6 @@ fn replace_local<'tcx>( new_local } -/// Transforms the `body` of the coroutine applying the following transforms: -/// -/// - Eliminates all the `get_context` calls that async lowering created. -/// - Replace all `Local` `ResumeTy` types with `&mut Context<'_>` (`context_mut_ref`). -/// -/// The `Local`s that have their types replaced are: -/// - The `resume` argument itself. -/// - The argument to `get_context`. -/// - The yielded value of a `yield`. -/// -/// The `ResumeTy` hides a `&mut Context<'_>` behind an unsafe raw pointer, and the -/// `get_context` function is being used to convert that back to a `&mut Context<'_>`. -/// -/// Ideally the async lowering would not use the `ResumeTy`/`get_context` indirection, -/// but rather directly use `&mut Context<'_>`, however that would currently -/// lead to higher-kinded lifetime errors. -/// See . -/// -/// The async lowering step and the type / lifetime inference / checking are -/// still using the `ResumeTy` indirection for the time being, and that indirection -/// is removed here. After this transform, the coroutine body only knows about `&mut Context<'_>`. -fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty<'tcx> { - let context_mut_ref = Ty::new_task_context(tcx); - - // replace the type of the `resume` argument - replace_resume_ty_local(tcx, body, CTX_ARG, context_mut_ref); - - let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, body.span); - - for bb in body.basic_blocks.indices() { - let bb_data = &body[bb]; - if bb_data.is_cleanup { - continue; - } - - match &bb_data.terminator().kind { - TerminatorKind::Call { func, .. } => { - let func_ty = func.ty(body, tcx); - if let ty::FnDef(def_id, _) = *func_ty.kind() - && def_id == get_context_def_id - { - let local = eliminate_get_context_call(&mut body[bb]); - replace_resume_ty_local(tcx, body, local, context_mut_ref); - } - } - TerminatorKind::Yield { resume_arg, .. } => { - replace_resume_ty_local(tcx, body, resume_arg.local, context_mut_ref); - } - _ => {} - } - } - context_mut_ref -} - -fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local { - let terminator = bb_data.terminator.take().unwrap(); - let TerminatorKind::Call { args, destination, target, .. } = terminator.kind else { - bug!(); - }; - let [arg] = *Box::try_from(args).unwrap(); - let local = arg.node.place().unwrap().local; - - let arg = Rvalue::Use(arg.node); - let assign = - Statement::new(terminator.source_info, StatementKind::Assign(Box::new((destination, arg)))); - bb_data.statements.push(assign); - bb_data.terminator = Some(Terminator { - source_info: terminator.source_info, - kind: TerminatorKind::Goto { target: target.unwrap() }, - }); - local -} - -#[cfg_attr(not(debug_assertions), allow(unused))] -fn replace_resume_ty_local<'tcx>( - tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, - local: Local, - context_mut_ref: Ty<'tcx>, -) { - let local_ty = std::mem::replace(&mut body.local_decls[local].ty, context_mut_ref); - // We have to replace the `ResumeTy` that is used for type and borrow checking - // with `&mut Context<'_>` in MIR. - #[cfg(debug_assertions)] - { - if let ty::Adt(resume_ty_adt, _) = local_ty.kind() { - let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, body.span)); - assert_eq!(*resume_ty_adt, expected_adt); - } else { - panic!("expected `ResumeTy`, found `{:?}`", local_ty); - }; - } -} - /// Transforms the `body` of the coroutine applying the following transform: /// /// - Remove the `resume` argument. @@ -1342,12 +1251,11 @@ fn create_cases<'tcx>( if operation == Operation::Resume { // 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())), + transform.resume_rvalue.clone(), ))), )); } @@ -1504,12 +1412,8 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { ) && has_expandable_async_drops(tcx, body, coroutine_ty); // Replace all occurrences of `ResumeTy` with `&mut Context<'_>` within async bodies. - if matches!( - coroutine_kind, - CoroutineKind::Desugared(CoroutineDesugaring::Async | CoroutineDesugaring::AsyncGen, _) - ) { - let context_mut_ref = transform_async_context(tcx, body); - expand_async_drops(tcx, body, context_mut_ref, coroutine_kind, coroutine_ty); + if has_async_drops { + expand_async_drops(tcx, body, coroutine_kind, coroutine_ty); if let Some(dumper) = MirDumper::new(tcx, "coroutine_async_drop_expand", body) { dumper.dump_mir(body); @@ -1522,22 +1426,27 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { // 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); + let resume_ty = body.local_decls[CTX_ARG].ty; + let old_resume_local = replace_local(CTX_ARG, 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; + let stmts = &mut body.basic_blocks.as_mut()[START_BLOCK].statements; + let resume_rvalue = if matches!( + coroutine_kind, + CoroutineKind::Desugared(CoroutineDesugaring::Async | CoroutineDesugaring::AsyncGen, _) + ) { + body.local_decls[CTX_ARG].ty = Ty::new_task_context(tcx); + Rvalue::WrapUnsafeBinder(Operand::Move(CTX_ARG.into()), resume_ty) + } else { + Rvalue::Use(Operand::Move(CTX_ARG.into())) + }; stmts.insert( 0, Statement::new( source_info, - StatementKind::Assign(Box::new(( - old_resume_local.into(), - Rvalue::Use(Operand::Move(resume_local.into())), - ))), + StatementKind::Assign(Box::new((old_resume_local.into(), resume_rvalue.clone()))), ), ); @@ -1580,6 +1489,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { discr_ty, old_ret_ty, old_yield_ty, + resume_rvalue, }; transform.visit_body(body); diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index fd2d8b2b0563e..1c28033d62e66 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -252,10 +252,11 @@ pub(super) fn has_expandable_async_drops<'tcx>( pub(super) fn expand_async_drops<'tcx>( tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, - context_mut_ref: Ty<'tcx>, coroutine_kind: hir::CoroutineKind, coroutine_ty: Ty<'tcx>, ) { + let resume_ty = Ty::new_resume_ty(tcx); + let context_mut_ref = Ty::new_task_context(tcx); let dropline = gather_dropline_blocks(body); // Clean drop and async_fut fields if potentially async drop is not expanded (stays sync) let remove_asyncness = |block: &mut BasicBlockData<'tcx>| { @@ -323,8 +324,8 @@ pub(super) fn expand_async_drops<'tcx>( // First state-loop yield for mainline let context_ref_place = - Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span))); - let arg = Rvalue::Use(Operand::Move(Place::from(CTX_ARG))); + Place::from(body.local_decls.push(LocalDecl::new(resume_ty, source_info.span))); + let arg = Rvalue::Use(Operand::Move(CTX_ARG.into())); body[bb].statements.push(Statement::new( source_info, StatementKind::Assign(Box::new((context_ref_place, arg))), @@ -358,8 +359,11 @@ pub(super) fn expand_async_drops<'tcx>( let mut dropline_context_ref: Option> = None; let mut dropline_call_bb: Option = None; if !is_dropline_bb { - let context_ref_place2: Place<'_> = Place::from( - body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)), + let context_ref_local2 = + body.local_decls.push(LocalDecl::new(resume_ty, source_info.span)); + let context_ref_place2 = tcx.mk_place_elem( + context_ref_local2.into(), + PlaceElem::UnwrapUnsafeBinder(context_mut_ref), ); let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield let (pin_bb2, fut_pin_place2) = @@ -385,7 +389,7 @@ pub(super) fn expand_async_drops<'tcx>( ); dropline_transition_bb = Some(pin_bb2); dropline_yield_bb = Some(drop_yield_block); - dropline_context_ref = Some(context_ref_place2); + dropline_context_ref = Some(context_ref_local2.into()); dropline_call_bb = Some(drop_call_bb); } diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 18d09473c191e..3579955e56773 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -64,8 +64,7 @@ pub(super) fn build_async_drop_shim<'tcx>( let needs_async_drop = drop_ty.needs_async_drop(tcx, typing_env); let needs_sync_drop = !needs_async_drop && drop_ty.needs_drop(tcx, typing_env); - let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); - let resume_ty = Ty::new_adt(tcx, resume_adt, ty::List::empty()); + let resume_ty = Ty::new_resume_ty(tcx); let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig( [ty, resume_ty], diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index e4ed084b073b6..51db3da3658ec 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -159,16 +159,11 @@ fn fn_sig_for_fn_abi<'tcx>( // with `&mut Context<'_>` which is used in codegen. #[cfg(debug_assertions)] { - if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() { - let expected_adt = - tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); - assert_eq!(*resume_ty_adt, expected_adt); - } else { - panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty); - }; + let resume_ty = Ty::new_resume_ty(tcx); + assert_eq!(resume_ty, sig.resume_ty); } - let context_mut_ref = Ty::new_task_context(tcx); + let context_mut_ref = Ty::new_task_context(tcx); (Some(context_mut_ref), ret_ty) } hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => { @@ -191,20 +186,15 @@ fn fn_sig_for_fn_abi<'tcx>( // Yield type is already `Poll>` let ret_ty = sig.yield_ty; - // We have to replace the `ResumeTy` that is used for type and borrow checking + // We have to replace the `{:?}` that is used for type and borrow checking // with `&mut Context<'_>` which is used in codegen. #[cfg(debug_assertions)] { - if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() { - let expected_adt = - tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); - assert_eq!(*resume_ty_adt, expected_adt); - } else { - panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty); - }; + let resume_ty = Ty::new_resume_ty(tcx); + assert_eq!(resume_ty, sig.resume_ty); } - let context_mut_ref = Ty::new_task_context(tcx); + let context_mut_ref = Ty::new_task_context(tcx); (Some(context_mut_ref), ret_ty) } hir::CoroutineKind::Coroutine(_) => { diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index 2b16a568b4031..ebc6e376477e6 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -9,7 +9,6 @@ //! [`await`]: ../../std/keyword.await.html //! [async book]: https://rust-lang.github.io/async-book/ -use crate::ptr::NonNull; use crate::task::Context; mod async_drop; @@ -47,22 +46,10 @@ pub use self::join::join; #[lang = "ResumeTy"] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "none")] -#[derive(Debug, Copy, Clone)] -pub struct ResumeTy(NonNull>); +pub type ResumeTy = unsafe<'a, 'b> &'a mut Context<'b>; #[unstable(feature = "gen_future", issue = "none")] unsafe impl Send for ResumeTy {} #[unstable(feature = "gen_future", issue = "none")] unsafe impl Sync for ResumeTy {} - -#[lang = "get_context"] -#[doc(hidden)] -#[unstable(feature = "gen_future", issue = "none")] -#[must_use] -#[inline] -pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { - // SAFETY: the caller must guarantee that `cx.0` is a valid pointer - // that fulfills all the requirements for a mutable reference. - unsafe { &mut *cx.0.as_ptr().cast() } -} diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 86a68e18b0af4..9c69cfbd1bf17 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -186,6 +186,7 @@ #![feature(transparent_unions)] #![feature(try_blocks)] #![feature(unboxed_closures)] +#![feature(unsafe_binders)] #![feature(unsized_fn_params)] #![feature(with_negative_coherence)] // tidy-alphabetical-end diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir index b43af549b232c..372ba3cbbc11a 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `foo::{closure#0}::{closure#0}` after built -fn foo::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> () +fn foo::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: unsafe<'a, 'b> &'a mut Context<'b>) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir index 5623b6d64e973..19204f8d01c39 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `foo::{closure#0}::{synthetic#0}` after built -fn foo::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> () +fn foo::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: unsafe<'a, 'b> &'a mut Context<'b>) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir index 4d484b16b5072..1e6099604cac8 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{closure#0}` after built -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: unsafe<'a, 'b> &'a mut std::task::Context<'b>) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir index ace780f773e89..272765819257a 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{synthetic#0}` after built -fn main::{closure#0}::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: unsafe<'a, 'b> &'a mut std::task::Context<'b>) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir index f50ad689f447e..efd569b00abea 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#1}::{closure#0}` after built -fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: unsafe<'a, 'b> &'a mut std::task::Context<'b>) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir index 62d8adeedcb64..0a3b5255373fd 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#1}::{synthetic#0}` after built -fn main::{closure#0}::{closure#1}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#1}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: unsafe<'a, 'b> &'a mut std::task::Context<'b>) -> () yields () { debug _task_context => _2; 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 347e4119cd0e0..182c0efb0b11d 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 @@ -12,15 +12,15 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) let mut _8: *mut T; let mut _9: (); let mut _10: std::task::Poll<()>; - let mut _11: &mut std::task::Context<'_>; + let mut _11: unsafe<'a, 'b> &'a mut std::task::Context<'b>; let mut _12: &mut impl std::future::Future; let mut _13: std::pin::Pin<&mut impl std::future::Future>; let mut _14: isize; - let mut _15: &mut std::task::Context<'_>; + let mut _15: unsafe<'a, 'b> &'a mut std::task::Context<'b>; let mut _16: &mut impl std::future::Future; let mut _17: std::pin::Pin<&mut impl std::future::Future>; let mut _18: isize; - let mut _19: &mut std::task::Context<'_>; + let mut _19: unsafe<'a, 'b> &'a mut std::task::Context<'b>; let mut _20: u32; scope 1 { debug x => (((*(_1.0: &mut {async fn body of a()})) as variant#4).0: T); @@ -65,7 +65,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb7: { - _10 = as Future>::poll(move _17, move _15) -> [return: bb6, unwind unreachable]; + _10 = as Future>::poll(move _17, move unwrap_binder!(_15; &mut Context<'_>)) -> [return: bb6, unwind unreachable]; } bb8: { 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 b1cf5373f9191..081fc02fcf30c 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 @@ -12,15 +12,15 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) let mut _8: *mut T; let mut _9: (); let mut _10: std::task::Poll<()>; - let mut _11: &mut std::task::Context<'_>; + let mut _11: unsafe<'a, 'b> &'a mut std::task::Context<'b>; let mut _12: &mut impl std::future::Future; let mut _13: std::pin::Pin<&mut impl std::future::Future>; let mut _14: isize; - let mut _15: &mut std::task::Context<'_>; + let mut _15: unsafe<'a, 'b> &'a mut std::task::Context<'b>; let mut _16: &mut impl std::future::Future; let mut _17: std::pin::Pin<&mut impl std::future::Future>; let mut _18: isize; - let mut _19: &mut std::task::Context<'_>; + let mut _19: unsafe<'a, 'b> &'a mut std::task::Context<'b>; let mut _20: u32; scope 1 { debug x => (((*(_1.0: &mut {async fn body of a()})) as variant#4).0: T); @@ -79,7 +79,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb10: { - _10 = as Future>::poll(move _17, move _15) -> [return: bb9, unwind: bb3]; + _10 = as Future>::poll(move _17, move unwrap_binder!(_15; &mut Context<'_>)) -> [return: bb9, unwind: bb3]; } bb11: { 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 7480324b17791..bf108fce1c017 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 @@ -13,7 +13,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> debug _task_context => _4; let mut _0: std::task::Poll<()>; let mut _3: (); - let mut _4: &mut std::task::Context<'_>; + let mut _4: unsafe<'a, 'b> &'a mut std::task::Context<'b>; let mut _5: u32; bb0: { @@ -22,7 +22,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> } bb1: { - _4 = move _2; + _4 = wrap_binder!(move _2; unsafe<'a, 'b> &'a mut std::task::Context<'b>); _3 = const (); goto -> bb3; } 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 9bff257e06392..ad857c5ae0601 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 @@ -6,7 +6,7 @@ DefId(0:5 ~ async_await[ccf8]::a::{closure#0}), [ (), - std::future::ResumeTy, + Binder { value: &'^0 mut std::task::Context<'^1>, bound_vars: [Region(BrAnon), Region(BrAnon)] }, (), (), (), @@ -23,7 +23,7 @@ DefId(0:5 ~ async_await[ccf8]::a::{closure#0}), [ (), - std::future::ResumeTy, + Binder { value: &'^0 mut std::task::Context<'^1>, bound_vars: [Region(BrAnon), Region(BrAnon)] }, (), (), (), @@ -50,7 +50,7 @@ } */ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> { - debug _task_context => _38; + debug _task_context => _36; let mut _0: std::task::Poll<()>; let _3: (); let mut _4: {async fn body of a()}; @@ -63,52 +63,50 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> let mut _11: &mut {async fn body of a()}; let mut _12: &mut {async fn body of a()}; let mut _13: &mut std::task::Context<'_>; - let mut _14: &mut std::task::Context<'_>; - let mut _15: &mut std::task::Context<'_>; - let mut _16: isize; - let mut _18: !; - let mut _19: &mut std::task::Context<'_>; - let mut _20: (); + let mut _14: isize; + let mut _16: !; + let mut _17: unsafe<'a, 'b> &'a mut std::task::Context<'b>; + let mut _18: (); + let mut _19: {async fn body of a()}; + let mut _20: {async fn body of a()}; let mut _21: {async fn body of a()}; - let mut _22: {async fn body of a()}; - let mut _23: {async fn body of a()}; - let _24: (); - let mut _25: std::task::Poll<()>; - let mut _26: std::pin::Pin<&mut {async fn body of a()}>; - let mut _27: &mut {async fn body of a()}; - let mut _28: &mut {async fn body of a()}; - let mut _29: &mut std::task::Context<'_>; - let mut _30: &mut std::task::Context<'_>; - let mut _31: &mut std::task::Context<'_>; - let mut _32: isize; - let mut _34: !; - let mut _35: &mut std::task::Context<'_>; - let mut _36: (); - let mut _37: (); - let mut _38: &mut std::task::Context<'_>; - let mut _39: u32; + let _22: (); + let mut _23: std::task::Poll<()>; + let mut _24: std::pin::Pin<&mut {async fn body of a()}>; + let mut _25: &mut {async fn body of a()}; + let mut _26: &mut {async fn body of a()}; + let mut _27: &mut std::task::Context<'_>; + let mut _28: isize; + let mut _30: !; + let mut _31: unsafe<'a, 'b> &'a mut std::task::Context<'b>; + let mut _32: (); + let mut _33: &mut std::task::Context<'_>; + let mut _34: &mut std::task::Context<'_>; + let mut _35: (); + let mut _36: unsafe<'a, 'b> &'a mut std::task::Context<'b>; + let mut _37: u32; scope 1 { debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()}); - let _17: (); + let _15: (); scope 2 { - debug result => _17; + debug result => _15; } } scope 3 { debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}); - let _33: (); + let _29: (); scope 4 { - debug result => _33; + debug result => _29; } } bb0: { - _39 = discriminant((*(_1.0: &mut {async fn body of b()}))); - switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8]; + _37 = discriminant((*(_1.0: &mut {async fn body of b()}))); + switchInt(move _37) -> [0: bb1, 1: bb27, 3: bb25, 4: bb26, otherwise: bb7]; } bb1: { - _38 = move _2; + _36 = wrap_binder!(move _2; unsafe<'a, 'b> &'a mut std::task::Context<'b>); StorageLive(_3); StorageLive(_4); StorageLive(_5); @@ -141,204 +139,184 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb5: { StorageDead(_11); StorageLive(_13); - StorageLive(_14); - StorageLive(_15); - _15 = copy _38; - _14 = move _15; - goto -> bb6; + _33 = deref_copy unwrap_binder!(_36; &mut Context<'_>); + _13 = &mut (*_33); + _9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb6, unwind unreachable]; } bb6: { - _13 = &mut (*_14); - StorageDead(_15); - _9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable]; - } - - bb7: { StorageDead(_13); StorageDead(_10); PlaceMention(_9); - _16 = discriminant(_9); - switchInt(move _16) -> [0: bb10, 1: bb9, otherwise: bb8]; + _14 = discriminant(_9); + switchInt(move _14) -> [0: bb9, 1: bb8, otherwise: bb7]; } - bb8: { + bb7: { unreachable; } - bb9: { + bb8: { _8 = const (); - StorageDead(_14); StorageDead(_12); StorageDead(_9); StorageDead(_8); - StorageLive(_19); - StorageLive(_20); - _20 = (); + StorageLive(_17); + StorageLive(_18); + _18 = (); _0 = Poll::<()>::Pending; StorageDead(_3); StorageDead(_4); - StorageDead(_19); - StorageDead(_20); + StorageDead(_17); + StorageDead(_18); discriminant((*(_1.0: &mut {async fn body of b()}))) = 3; return; } - bb10: { - StorageLive(_17); - _17 = copy ((_9 as Ready).0: ()); - _3 = copy _17; - StorageDead(_17); - StorageDead(_14); + bb9: { + StorageLive(_15); + _15 = copy ((_9 as Ready).0: ()); + _3 = copy _15; + StorageDead(_15); 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((((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()})) -> [return: bb11, unwind unreachable]; } - bb11: { - StorageDead(_20); - _38 = move _19; - StorageDead(_19); + bb10: { + StorageDead(_18); + _36 = move _17; + StorageDead(_17); _7 = const (); goto -> bb4; } - bb12: { + bb11: { nop; - goto -> bb13; + goto -> bb12; } - bb13: { + bb12: { StorageDead(_4); StorageDead(_3); - StorageLive(_21); - StorageLive(_22); - _22 = a() -> [return: bb14, unwind unreachable]; + StorageLive(_19); + StorageLive(_20); + _20 = a() -> [return: bb13, unwind unreachable]; } - bb14: { - _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; + bb13: { + _19 = <{async fn body of a()} as IntoFuture>::into_future(move _20) -> [return: bb14, unwind unreachable]; } - bb15: { - StorageDead(_22); - PlaceMention(_21); + bb14: { + StorageDead(_20); + PlaceMention(_19); nop; - (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}) = move _21; - goto -> bb16; + (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}) = move _19; + goto -> bb15; } - bb16: { + bb15: { + StorageLive(_22); + StorageLive(_23); StorageLive(_24); StorageLive(_25); StorageLive(_26); + _26 = &mut (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}); + _25 = &mut (*_26); + _24 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _25) -> [return: bb16, unwind unreachable]; + } + + bb16: { + StorageDead(_25); StorageLive(_27); - StorageLive(_28); - _28 = &mut (((*(_1.0: &mut {async fn body of b()})) 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]; + _34 = deref_copy unwrap_binder!(_36; &mut Context<'_>); + _27 = &mut (*_34); + _23 = <{async fn body of a()} as Future>::poll(move _24, move _27) -> [return: bb17, unwind unreachable]; } bb17: { StorageDead(_27); - StorageLive(_29); - StorageLive(_30); - StorageLive(_31); - _31 = copy _38; - _30 = move _31; - goto -> bb18; + StorageDead(_24); + PlaceMention(_23); + _28 = discriminant(_23); + switchInt(move _28) -> [0: bb19, 1: bb18, otherwise: bb7]; } bb18: { - _29 = &mut (*_30); + _22 = const (); + StorageDead(_26); + StorageDead(_23); + StorageDead(_22); + StorageLive(_31); + StorageLive(_32); + _32 = (); + _0 = Poll::<()>::Pending; + StorageDead(_19); StorageDead(_31); - _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; + StorageDead(_32); + discriminant((*(_1.0: &mut {async fn body of b()}))) = 4; + return; } bb19: { + StorageLive(_29); + _29 = copy ((_23 as Ready).0: ()); + _35 = copy _29; StorageDead(_29); StorageDead(_26); - PlaceMention(_25); - _32 = discriminant(_25); - switchInt(move _32) -> [0: bb21, 1: bb20, otherwise: bb8]; + StorageDead(_23); + StorageDead(_22); + drop((((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()})) -> [return: bb21, unwind unreachable]; } bb20: { - _24 = const (); - StorageDead(_30); - StorageDead(_28); - StorageDead(_25); - StorageDead(_24); - StorageLive(_35); - StorageLive(_36); - _36 = (); - _0 = Poll::<()>::Pending; - StorageDead(_21); - StorageDead(_35); - StorageDead(_36); - discriminant((*(_1.0: &mut {async fn body of b()}))) = 4; - return; + StorageDead(_32); + _36 = move _31; + StorageDead(_31); + _7 = const (); + goto -> bb15; } bb21: { - StorageLive(_33); - _33 = copy ((_25 as Ready).0: ()); - _37 = copy _33; - StorageDead(_33); - StorageDead(_30); - 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]; + nop; + goto -> bb22; } bb22: { - StorageDead(_36); - _38 = move _35; - StorageDead(_35); - _7 = const (); - goto -> bb16; - } - - bb23: { - nop; + StorageDead(_19); goto -> bb24; } - bb24: { - StorageDead(_21); - goto -> bb26; - } - - bb25: { - _0 = Poll::<()>::Ready(move _37); + bb23: { + _0 = Poll::<()>::Ready(move _35); discriminant((*(_1.0: &mut {async fn body of b()}))) = 1; return; } - bb26: { - goto -> bb25; + bb24: { + goto -> bb23; } - bb27: { + bb25: { StorageLive(_3); StorageLive(_4); - StorageLive(_19); - StorageLive(_20); - _19 = move _2; - goto -> bb11; + StorageLive(_17); + StorageLive(_18); + _17 = wrap_binder!(move _2; unsafe<'a, 'b> &'a mut std::task::Context<'b>); + goto -> bb10; } - bb28: { - StorageLive(_21); - StorageLive(_35); - StorageLive(_36); - _35 = move _2; - goto -> bb22; + bb26: { + StorageLive(_19); + StorageLive(_31); + StorageLive(_32); + _31 = wrap_binder!(move _2; unsafe<'a, 'b> &'a mut std::task::Context<'b>); + goto -> bb20; } - bb29: { - assert(const false, "`async fn` resumed after completion") -> [success: bb29, unwind unreachable]; + bb27: { + assert(const false, "`async fn` resumed after completion") -> [success: bb27, unwind unreachable]; } } 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 22e6ea722ddaf..8637f4bc3a9f7 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 @@ -32,15 +32,15 @@ + let mut _20: &mut std::future::Ready<()>; + let mut _21: &mut std::future::Ready<()>; + let mut _22: &mut std::task::Context<'_>; -+ let mut _23: &mut std::task::Context<'_>; -+ let mut _24: &mut std::task::Context<'_>; -+ let mut _25: isize; -+ let mut _27: !; ++ let mut _23: isize; ++ let mut _25: !; ++ let mut _26: unsafe<'a, 'b> &'a mut std::task::Context<'b>; ++ let mut _27: (); + 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 _30: unsafe<'a, 'b> &'a mut std::task::Context<'b>; ++ 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,24 +48,23 @@ + 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 { -+ let _26: (); ++ let _24: (); + scope 9 { + } + scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { + } + scope 13 (inlined 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 > 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::>) { + 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 as IntoFuture>::into_future) { + } @@ -133,8 +132,10 @@ + StorageLive(_11); + StorageLive(_15); + StorageLive(_16); ++ StorageLive(_23); + StorageLive(_25); -+ StorageLive(_27); ++ StorageLive(_28); ++ StorageLive(_29); + StorageLive(_30); + StorageLive(_31); + StorageLive(_32); @@ -145,10 +146,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 +158,6 @@ + } + + bb2: { -+ StorageDead(_40); + StorageDead(_39); + StorageDead(_38); + StorageDead(_37); @@ -169,8 +168,10 @@ + StorageDead(_32); + StorageDead(_31); + StorageDead(_30); -+ StorageDead(_27); ++ StorageDead(_29); ++ StorageDead(_28); + StorageDead(_25); ++ StorageDead(_23); + StorageDead(_16); + StorageDead(_15); + StorageDead(_11); @@ -186,23 +187,23 @@ } + bb3: { -+ _31 = move _9; ++ _30 = wrap_binder!(move _9; unsafe<'a, 'b> &'a mut std::task::Context<'b>); ++ _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 +215,35 @@ + 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; -+ _23 = move _24; -+ _22 = &mut (*_23); -+ StorageDead(_24); ++ _28 = deref_copy unwrap_binder!(_30; &mut Context<'_>); ++ _22 = &mut (*_28); ++ 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: { @@ -255,51 +252,49 @@ + + bb6: { + _17 = const (); -+ StorageDead(_23); + StorageDead(_21); + StorageDead(_18); + StorageDead(_17); -+ StorageLive(_28); -+ StorageLive(_29); -+ _29 = (); ++ StorageLive(_26); ++ StorageLive(_27); ++ _27 = (); + _7 = Poll::<()>::Pending; + StorageDead(_12); -+ StorageDead(_28); -+ StorageDead(_29); -+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_38)) = 3; ++ StorageDead(_26); ++ StorageDead(_27); ++ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_37)) = 3; + goto -> bb2; + } + + bb7: { -+ StorageLive(_26); -+ _26 = copy ((_18 as Ready).0: ()); -+ _30 = copy _26; -+ StorageDead(_26); -+ StorageDead(_23); ++ StorageLive(_24); ++ _24 = copy ((_18 as Ready).0: ()); ++ _29 = copy _24; ++ StorageDead(_24); + StorageDead(_21); + 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; ++ _7 = Poll::<()>::Ready(move _29); ++ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_39)) = 1; + goto -> bb2; + } + + bb9: { + StorageLive(_12); -+ StorageLive(_28); -+ StorageLive(_29); -+ _28 = move _9; -+ StorageDead(_29); -+ _31 = move _28; -+ StorageDead(_28); ++ StorageLive(_26); ++ StorageLive(_27); ++ _26 = wrap_binder!(move _9; unsafe<'a, 'b> &'a mut std::task::Context<'b>); ++ StorageDead(_27); ++ _30 = move _26; ++ StorageDead(_26); + _16 = const (); + goto -> bb4; + } @@ -309,22 +304,22 @@ + } + + 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); -+ switchInt(move _25) -> [0: bb7, 1: bb6, otherwise: bb5]; ++ _23 = discriminant(_18); ++ switchInt(move _23) -> [0: bb7, 1: bb6, 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 8b027e988b8e8..4ca2318b0ff31 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 @@ -32,15 +32,15 @@ + let mut _20: &mut std::future::Ready<()>; + let mut _21: &mut std::future::Ready<()>; + let mut _22: &mut std::task::Context<'_>; -+ let mut _23: &mut std::task::Context<'_>; -+ let mut _24: &mut std::task::Context<'_>; -+ let mut _25: isize; -+ let mut _27: !; ++ let mut _23: isize; ++ let mut _25: !; ++ let mut _26: unsafe<'a, 'b> &'a mut std::task::Context<'b>; ++ let mut _27: (); + 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 _30: unsafe<'a, 'b> &'a mut std::task::Context<'b>; ++ 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,24 +50,23 @@ + 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 { -+ let _26: (); ++ let _24: (); + scope 9 { + } + scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { + } + scope 13 (inlined 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 > 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::>) { + 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 as IntoFuture>::into_future) { + } @@ -135,8 +134,10 @@ + StorageLive(_11); + StorageLive(_15); + StorageLive(_16); ++ StorageLive(_23); + StorageLive(_25); -+ StorageLive(_27); ++ StorageLive(_28); ++ StorageLive(_29); + StorageLive(_30); + StorageLive(_31); + StorageLive(_32); @@ -149,10 +150,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 +170,6 @@ + } + + bb4: { -+ StorageDead(_42); + StorageDead(_41); + StorageDead(_40); + StorageDead(_39); @@ -183,8 +182,10 @@ + StorageDead(_32); + StorageDead(_31); + StorageDead(_30); -+ StorageDead(_27); ++ StorageDead(_29); ++ StorageDead(_28); + StorageDead(_25); ++ StorageDead(_23); + StorageDead(_16); + StorageDead(_15); + StorageDead(_11); @@ -203,23 +204,23 @@ - StorageDead(_2); - return; + bb5: { -+ _31 = move _9; ++ _30 = wrap_binder!(move _9; unsafe<'a, 'b> &'a mut std::task::Context<'b>); ++ _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 +232,35 @@ + 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; -+ _23 = move _24; -+ _22 = &mut (*_23); -+ StorageDead(_24); ++ _28 = deref_copy unwrap_binder!(_30; &mut Context<'_>); ++ _22 = &mut (*_28); ++ 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): { @@ -274,69 +271,66 @@ + + bb8: { + _17 = const (); -+ StorageDead(_23); + StorageDead(_21); + StorageDead(_18); + StorageDead(_17); -+ StorageLive(_28); -+ StorageLive(_29); -+ _29 = (); ++ StorageLive(_26); ++ StorageLive(_27); ++ _27 = (); + _7 = Poll::<()>::Pending; + StorageDead(_12); -+ StorageDead(_28); -+ StorageDead(_29); -+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_38)) = 3; ++ StorageDead(_26); ++ StorageDead(_27); ++ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_37)) = 3; + goto -> bb4; + } + + bb9: { -+ StorageLive(_26); -+ _26 = copy ((_18 as Ready).0: ()); -+ _30 = copy _26; -+ StorageDead(_26); -+ StorageDead(_23); ++ StorageLive(_24); ++ _24 = copy ((_18 as Ready).0: ()); ++ _29 = copy _24; ++ StorageDead(_24); + StorageDead(_21); + 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; ++ _7 = Poll::<()>::Ready(move _29); ++ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_39)) = 1; + goto -> bb4; + } + + bb11 (cleanup): { + StorageDead(_22); + StorageDead(_19); -+ StorageDead(_23); + StorageDead(_21); + 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; + } + + bb13: { + StorageLive(_12); -+ StorageLive(_28); -+ StorageLive(_29); -+ _28 = move _9; -+ StorageDead(_29); -+ _31 = move _28; -+ StorageDead(_28); ++ StorageLive(_26); ++ StorageLive(_27); ++ _26 = wrap_binder!(move _9; unsafe<'a, 'b> &'a mut std::task::Context<'b>); ++ StorageDead(_27); ++ _30 = move _26; ++ StorageDead(_26); + _16 = const (); + goto -> bb6; + } @@ -350,22 +344,22 @@ + } + + 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); -+ switchInt(move _25) -> [0: bb9, 1: bb8, otherwise: bb7]; ++ _23 = discriminant(_18); ++ switchInt(move _23) -> [0: bb9, 1: bb8, otherwise: bb7]; + } + } + diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr index a507fa697604f..9da145c8e2a6d 100644 --- a/tests/ui/async-await/async-closures/def-path.stderr +++ b/tests/ui/async-await/async-closures/def-path.stderr @@ -5,11 +5,11 @@ LL | let x = async || {}; | -- the expected `async` closure body LL | LL | let () = x(); - | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}` + | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=unsafe &'^0.Named(DefId(2:15634 ~ core[1112]::future::ResumeTy::'a)) mut Context<'^1.Named(DefId(2:15635 ~ core[1112]::future::ResumeTy::'b))> yield_ty=() return_ty=()}` | | | expected `async` closure body, found `()` | - = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}` + = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=unsafe &'^0.Named(DefId(2:15634 ~ core[1112]::future::ResumeTy::'a)) mut Context<'^1.Named(DefId(2:15635 ~ core[1112]::future::ResumeTy::'b))> yield_ty=() return_ty=()}` found unit type `()` error: aborting due to 1 previous error