From 05116c5c30dea6895fb65fe31b6f2dd0f1198b51 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 13 Feb 2024 15:29:50 +0000 Subject: [PATCH] Only split by-ref/by-move futures for async closures --- .../src/type_check/input_output.rs | 2 +- compiler/rustc_hir_typeck/src/callee.rs | 14 ++- compiler/rustc_hir_typeck/src/closure.rs | 6 +- compiler/rustc_hir_typeck/src/upvar.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 12 --- compiler/rustc_middle/src/mir/visit.rs | 6 +- compiler/rustc_middle/src/ty/instance.rs | 18 +--- compiler/rustc_middle/src/ty/sty.rs | 17 +++- .../src/coroutine/by_move_body.rs | 35 ------- .../rustc_mir_transform/src/pass_manager.rs | 3 - compiler/rustc_mir_transform/src/shim.rs | 98 +++---------------- compiler/rustc_span/src/symbol.rs | 3 +- compiler/rustc_symbol_mangling/src/legacy.rs | 14 +-- compiler/rustc_symbol_mangling/src/v0.rs | 8 +- .../src/solve/normalizes_to/mod.rs | 2 +- .../src/traits/project.rs | 12 +-- compiler/rustc_ty_utils/src/abi.rs | 18 ++-- compiler/rustc_ty_utils/src/instance.rs | 33 +++---- library/alloc/src/boxed.rs | 8 +- library/core/src/ops/async_function.rs | 30 +++--- .../src/library-features/async-fn-traits.md | 2 +- ...ure#0}.coroutine_by_move.0.panic-abort.mir | 2 +- ...re#0}.coroutine_by_move.0.panic-unwind.mir | 2 +- ...sure#0}.coroutine_by_mut.0.panic-abort.mir | 47 --------- ...ure#0}.coroutine_by_mut.0.panic-unwind.mir | 47 --------- ...oroutine_closure_by_move.0.panic-abort.mir | 6 +- ...routine_closure_by_move.0.panic-unwind.mir | 6 +- ...coroutine_closure_by_mut.0.panic-abort.mir | 16 --- ...oroutine_closure_by_mut.0.panic-unwind.mir | 16 --- tests/mir-opt/async_closure_shims.rs | 2 - .../async-closures/def-path.stderr | 4 +- tests/ui/async-await/async-fn/dyn-pos.rs | 3 - tests/ui/async-await/async-fn/dyn-pos.stderr | 57 +---------- 33 files changed, 119 insertions(+), 432 deletions(-) delete mode 100644 tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-abort.mir delete mode 100644 tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-unwind.mir delete mode 100644 tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-abort.mir delete mode 100644 tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-unwind.mir diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 575aab47ac7..a4c1066ee8e 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -87,7 +87,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.tcx(), ty::CoroutineArgsParts { parent_args: args.parent_args(), - kind_ty: Ty::from_closure_kind(self.tcx(), args.kind()), + kind_ty: Ty::from_coroutine_closure_kind(self.tcx(), args.kind()), return_ty: user_provided_sig.output(), tupled_upvars_ty, // For async closures, none of these can be annotated, so just fill diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 9a500fa712b..0e75a47683d 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -184,16 +184,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind: TypeVariableOriginKind::TypeInference, span: callee_expr.span, }); + // We may actually receive a coroutine back whose kind is different + // from the closure that this dispatched from. This is because when + // we have no captures, we automatically implement `FnOnce`. This + // impl forces the closure kind to `FnOnce` i.e. `u8`. + let kind_ty = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span: callee_expr.span, + }); let call_sig = self.tcx.mk_fn_sig( [coroutine_closure_sig.tupled_inputs_ty], coroutine_closure_sig.to_coroutine( self.tcx, closure_args.parent_args(), - // Inherit the kind ty of the closure, since we're calling this - // coroutine with the most relaxed `AsyncFn*` trait that we can. - // We don't necessarily need to do this here, but it saves us - // computing one more infer var that will get constrained later. - closure_args.kind_ty(), + kind_ty, self.tcx.coroutine_for_closure(def_id), tupled_upvars_ty, ), diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 4bea4bb3e82..6e30cb02245 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -262,6 +262,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, ); + let coroutine_kind_ty = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::ClosureSynthetic, + span: expr_span, + }); let coroutine_upvars_ty = self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::ClosureSynthetic, span: expr_span, @@ -279,7 +283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sig.to_coroutine( tcx, parent_args, - closure_kind_ty, + coroutine_kind_ty, tcx.coroutine_for_closure(expr_def_id), coroutine_upvars_ty, ) diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index be14f5bf0d8..b71e88a1579 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -410,7 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.demand_eqtype( span, coroutine_args.as_coroutine().kind_ty(), - Ty::from_closure_kind(self.tcx, closure_kind), + Ty::from_coroutine_closure_kind(self.tcx, closure_kind), ); } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index d57ffc0f8b5..984d4687ef8 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -278,13 +278,6 @@ pub struct CoroutineInfo<'tcx> { /// using `run_passes`. pub by_move_body: Option>, - /// The body of the coroutine, modified to take its upvars by mutable ref rather than by - /// immutable ref. - /// - /// FIXME(async_closures): This is literally the same body as the parent body. Find a better - /// way to represent the by-mut signature (or cap the closure-kind of the coroutine). - pub by_mut_body: Option>, - /// The layout of a coroutine. This field is populated after the state transform pass. pub coroutine_layout: Option>, @@ -305,7 +298,6 @@ impl<'tcx> CoroutineInfo<'tcx> { yield_ty: Some(yield_ty), resume_ty: Some(resume_ty), by_move_body: None, - by_mut_body: None, coroutine_drop: None, coroutine_layout: None, } @@ -628,10 +620,6 @@ impl<'tcx> Body<'tcx> { self.coroutine.as_ref()?.by_move_body.as_ref() } - pub fn coroutine_by_mut_body(&self) -> Option<&Body<'tcx>> { - self.coroutine.as_ref()?.by_mut_body.as_ref() - } - #[inline] pub fn coroutine_kind(&self) -> Option { self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 845b1717550..562aed5a643 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -345,8 +345,10 @@ macro_rules! make_mir_visitor { ty::InstanceDef::Virtual(_def_id, _) | ty::InstanceDef::ThreadLocalShim(_def_id) | ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } | - ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id, target_kind: _ } | - ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id, target_kind: _ } | + ty::InstanceDef::ConstructCoroutineInClosureShim { + coroutine_closure_def_id: _def_id, + } | + ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id } | ty::InstanceDef::DropGlue(_def_id, None) => {} ty::InstanceDef::FnPtrShim(_def_id, ty) | diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 814c3629b08..bbe0915baa2 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -90,16 +90,12 @@ pub enum InstanceDef<'tcx> { /// and dispatch to the `FnMut::call_mut` instance for the closure. ClosureOnceShim { call_once: DefId, track_caller: bool }, - /// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once` or - /// `<[Fn coroutine-closure] as FnMut>::call_mut`. + /// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once` /// /// The body generated here differs significantly from the `ClosureOnceShim`, /// since we need to generate a distinct coroutine type that will move the /// closure's upvars *out* of the closure. - ConstructCoroutineInClosureShim { - coroutine_closure_def_id: DefId, - target_kind: ty::ClosureKind, - }, + ConstructCoroutineInClosureShim { coroutine_closure_def_id: DefId }, /// `<[coroutine] as Future>::poll`, but for coroutines produced when `AsyncFnOnce` /// is called on a coroutine-closure whose closure kind greater than `FnOnce`, or @@ -107,7 +103,7 @@ pub enum InstanceDef<'tcx> { /// /// This will select the body that is produced by the `ByMoveBody` transform, and thus /// take and use all of its upvars by-move rather than by-ref. - CoroutineKindShim { coroutine_def_id: DefId, target_kind: ty::ClosureKind }, + CoroutineKindShim { coroutine_def_id: DefId }, /// Compiler-generated accessor for thread locals which returns a reference to the thread local /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking @@ -192,9 +188,8 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } | ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id: def_id, - target_kind: _, } - | ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id, target_kind: _ } + | ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id } | InstanceDef::DropGlue(def_id, _) | InstanceDef::CloneShim(def_id, _) | InstanceDef::FnPtrAddrShim(def_id, _) => def_id, @@ -651,10 +646,7 @@ impl<'tcx> Instance<'tcx> { Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args }) } else { Some(Instance { - def: ty::InstanceDef::CoroutineKindShim { - coroutine_def_id, - target_kind: args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(), - }, + def: ty::InstanceDef::CoroutineKindShim { coroutine_def_id }, args, }) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 540936d7d8a..67908013041 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -483,7 +483,7 @@ impl<'tcx> CoroutineClosureSignature<'tcx> { self.to_coroutine( tcx, parent_args, - Ty::from_closure_kind(tcx, goal_kind), + Ty::from_coroutine_closure_kind(tcx, goal_kind), coroutine_def_id, tupled_upvars_ty, ) @@ -2456,6 +2456,21 @@ impl<'tcx> Ty<'tcx> { } } + /// Like [`Ty::to_opt_closure_kind`], but it caps the "maximum" closure kind + /// to `FnMut`. This is because although we have three capability states, + /// `AsyncFn`/`AsyncFnMut`/`AsyncFnOnce`, we only need to distinguish two coroutine + /// bodies: by-ref and by-value. + /// + /// This method should be used when constructing a `Coroutine` out of a + /// `CoroutineClosure`, when the `Coroutine`'s `kind` field is being populated + /// directly from the `CoroutineClosure`'s `kind`. + pub fn from_coroutine_closure_kind(tcx: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Ty<'tcx> { + match kind { + ty::ClosureKind::Fn | ty::ClosureKind::FnMut => tcx.types.i16, + ty::ClosureKind::FnOnce => tcx.types.i32, + } + } + /// Fast path helper for testing if a type is `Sized`. /// /// Returning true means the type is known to be sized. Returning diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index e40f4520671..000b96ee801 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -67,45 +67,10 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { by_move_body.source = mir::MirSource { instance: InstanceDef::CoroutineKindShim { coroutine_def_id: coroutine_def_id.to_def_id(), - target_kind: ty::ClosureKind::FnOnce, }, promoted: None, }; body.coroutine.as_mut().unwrap().by_move_body = Some(by_move_body); - - // If this is coming from an `AsyncFn` coroutine-closure, we must also create a by-mut body. - // This is actually just a copy of the by-ref body, but with a different self type. - // FIXME(async_closures): We could probably unify this with the by-ref body somehow. - if coroutine_kind == ty::ClosureKind::Fn { - let by_mut_coroutine_ty = Ty::new_coroutine( - tcx, - coroutine_def_id.to_def_id(), - ty::CoroutineArgs::new( - tcx, - ty::CoroutineArgsParts { - parent_args: args.as_coroutine().parent_args(), - kind_ty: Ty::from_closure_kind(tcx, ty::ClosureKind::FnMut), - resume_ty: args.as_coroutine().resume_ty(), - yield_ty: args.as_coroutine().yield_ty(), - return_ty: args.as_coroutine().return_ty(), - witness: args.as_coroutine().witness(), - tupled_upvars_ty: args.as_coroutine().tupled_upvars_ty(), - }, - ) - .args, - ); - let mut by_mut_body = body.clone(); - by_mut_body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty = by_mut_coroutine_ty; - dump_mir(tcx, false, "coroutine_by_mut", &0, &by_mut_body, |_, _| Ok(())); - by_mut_body.source = mir::MirSource { - instance: InstanceDef::CoroutineKindShim { - coroutine_def_id: coroutine_def_id.to_def_id(), - target_kind: ty::ClosureKind::FnMut, - }, - promoted: None, - }; - body.coroutine.as_mut().unwrap().by_mut_body = Some(by_mut_body); - } } } diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index 77478cc741d..17a1c3c7157 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -186,9 +186,6 @@ fn run_passes_inner<'tcx>( if let Some(by_move_body) = coroutine.by_move_body.as_mut() { run_passes_inner(tcx, by_move_body, passes, phase_change, validate_each); } - if let Some(by_mut_body) = coroutine.by_mut_body.as_mut() { - run_passes_inner(tcx, by_mut_body, passes, phase_change, validate_each); - } } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 733e2f93b25..3efaa69a7e7 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -3,8 +3,8 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_middle::mir::*; use rustc_middle::query::Providers; +use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, CoroutineArgs, EarlyBinder, Ty, TyCtxt}; -use rustc_middle::ty::{GenericArgs, CAPTURE_STRUCT_LOCAL}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_index::{Idx, IndexVec}; @@ -70,39 +70,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' build_call_shim(tcx, instance, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) } - ty::InstanceDef::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - target_kind, - } => match target_kind { - ty::ClosureKind::Fn => unreachable!("shouldn't be building shim for Fn"), - ty::ClosureKind::FnMut => { - // No need to optimize the body, it has already been optimized - // since we steal it from the `AsyncFn::call` body and just fix - // the return type. - return build_construct_coroutine_by_mut_shim(tcx, coroutine_closure_def_id); - } - ty::ClosureKind::FnOnce => { - build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id) - } - }, + ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id } => { + build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id) + } - ty::InstanceDef::CoroutineKindShim { coroutine_def_id, target_kind } => match target_kind { - ty::ClosureKind::Fn => unreachable!(), - ty::ClosureKind::FnMut => { - return tcx - .optimized_mir(coroutine_def_id) - .coroutine_by_mut_body() - .unwrap() - .clone(); - } - ty::ClosureKind::FnOnce => { - return tcx - .optimized_mir(coroutine_def_id) - .coroutine_by_move_body() - .unwrap() - .clone(); - } - }, + ty::InstanceDef::CoroutineKindShim { coroutine_def_id } => { + return tcx.optimized_mir(coroutine_def_id).coroutine_by_move_body().unwrap().clone(); + } ty::InstanceDef::DropGlue(def_id, ty) => { // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end @@ -123,21 +97,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' let body = if id_args.as_coroutine().kind_ty() == args.as_coroutine().kind_ty() { coroutine_body.coroutine_drop().unwrap() } else { - match args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap() { - ty::ClosureKind::Fn => { - unreachable!() - } - ty::ClosureKind::FnMut => coroutine_body - .coroutine_by_mut_body() - .unwrap() - .coroutine_drop() - .unwrap(), - ty::ClosureKind::FnOnce => coroutine_body - .coroutine_by_move_body() - .unwrap() - .coroutine_drop() - .unwrap(), - } + assert_eq!( + args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(), + ty::ClosureKind::FnOnce + ); + coroutine_body.coroutine_by_move_body().unwrap().coroutine_drop().unwrap() }; let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args); @@ -1112,7 +1076,6 @@ fn build_construct_coroutine_by_move_shim<'tcx>( let source = MirSource::from_instance(ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id, - target_kind: ty::ClosureKind::FnOnce, }); let body = @@ -1121,40 +1084,3 @@ fn build_construct_coroutine_by_move_shim<'tcx>( body } - -fn build_construct_coroutine_by_mut_shim<'tcx>( - tcx: TyCtxt<'tcx>, - coroutine_closure_def_id: DefId, -) -> Body<'tcx> { - let mut body = tcx.optimized_mir(coroutine_closure_def_id).clone(); - let coroutine_closure_ty = tcx.type_of(coroutine_closure_def_id).instantiate_identity(); - let ty::CoroutineClosure(_, args) = *coroutine_closure_ty.kind() else { - bug!(); - }; - let args = args.as_coroutine_closure(); - - body.local_decls[RETURN_PLACE].ty = - tcx.instantiate_bound_regions_with_erased(args.coroutine_closure_sig().map_bound(|sig| { - sig.to_coroutine_given_kind_and_upvars( - tcx, - args.parent_args(), - tcx.coroutine_for_closure(coroutine_closure_def_id), - ty::ClosureKind::FnMut, - tcx.lifetimes.re_erased, - args.tupled_upvars_ty(), - args.coroutine_captures_by_ref_ty(), - ) - })); - body.local_decls[CAPTURE_STRUCT_LOCAL].ty = - Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, coroutine_closure_ty); - - body.source = MirSource::from_instance(ty::InstanceDef::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - target_kind: ty::ClosureKind::FnMut, - }); - - body.pass_count = 0; - dump_mir(tcx, false, "coroutine_closure_by_mut", &0, &body, |_, _| Ok(())); - - body -} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 63b950a2803..8b911a41a11 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -166,9 +166,8 @@ symbols! { Break, C, CStr, - CallFuture, - CallMutFuture, CallOnceFuture, + CallRefFuture, Capture, Center, Cleanup, diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 83e920e2f8e..1c62ce2d214 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -76,16 +76,10 @@ pub(super) fn mangle<'tcx>( } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceDef::ConstructCoroutineInClosureShim { target_kind, .. } - | ty::InstanceDef::CoroutineKindShim { target_kind, .. } => match target_kind { - ty::ClosureKind::Fn => unreachable!(), - ty::ClosureKind::FnMut => { - printer.write_str("{{fn-mut-shim}}").unwrap(); - } - ty::ClosureKind::FnOnce => { - printer.write_str("{{fn-once-shim}}").unwrap(); - } - }, + ty::InstanceDef::ConstructCoroutineInClosureShim { .. } + | ty::InstanceDef::CoroutineKindShim { .. } => { + printer.write_str("{{fn-once-shim}}").unwrap(); + } _ => {} } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index f1b1b4ed2bb..6bc375512ac 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -46,12 +46,8 @@ pub(super) fn mangle<'tcx>( ty::InstanceDef::VTableShim(_) => Some("vtable"), ty::InstanceDef::ReifyShim(_) => Some("reify"), - ty::InstanceDef::ConstructCoroutineInClosureShim { target_kind, .. } - | ty::InstanceDef::CoroutineKindShim { target_kind, .. } => match target_kind { - ty::ClosureKind::Fn => unreachable!(), - ty::ClosureKind::FnMut => Some("fn_mut"), - ty::ClosureKind::FnOnce => Some("fn_once"), - }, + ty::InstanceDef::ConstructCoroutineInClosureShim { .. } + | ty::InstanceDef::CoroutineKindShim { .. } => Some("fn_once"), _ => None, }; diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index d24bec5a766..85bb6338daf 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -414,7 +414,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ), output_coroutine_ty.into(), ), - sym::CallMutFuture | sym::CallFuture => ( + sym::CallRefFuture => ( ty::AliasTy::new( tcx, goal.predicate.def_id(), diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 6756b5dec23..12371155303 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1726,7 +1726,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let sig = args.coroutine_closure_sig().skip_binder(); let term = match item_name { - sym::CallOnceFuture | sym::CallMutFuture | sym::CallFuture => { + sym::CallOnceFuture | sym::CallRefFuture => { if let Some(closure_kind) = kind_ty.to_opt_closure_kind() { if !closure_kind.extends(goal_kind) { bug!("we should not be confirming if the closure kind is not met"); @@ -1787,7 +1787,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( obligation.predicate.def_id, [self_ty, sig.tupled_inputs_ty], ), - sym::CallMutFuture | sym::CallFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTy::new( tcx, obligation.predicate.def_id, [ty::GenericArg::from(self_ty), sig.tupled_inputs_ty.into(), env_region.into()], @@ -1803,7 +1803,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let sig = bound_sig.skip_binder(); let term = match item_name { - sym::CallOnceFuture | sym::CallMutFuture | sym::CallFuture => sig.output(), + sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); let future_output_def_id = tcx @@ -1822,7 +1822,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( obligation.predicate.def_id, [self_ty, Ty::new_tup(tcx, sig.inputs())], ), - sym::CallMutFuture | sym::CallFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTy::new( tcx, obligation.predicate.def_id, [ @@ -1842,7 +1842,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let sig = bound_sig.skip_binder(); let term = match item_name { - sym::CallOnceFuture | sym::CallMutFuture | sym::CallFuture => sig.output(), + sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); let future_output_def_id = tcx @@ -1859,7 +1859,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( sym::CallOnceFuture | sym::Output => { ty::AliasTy::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]]) } - sym::CallMutFuture | sym::CallFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTy::new( tcx, obligation.predicate.def_id, [ty::GenericArg::from(self_ty), sig.inputs()[0].into(), env_region.into()], diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index a5328baadb5..7d54083fbd5 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -102,6 +102,7 @@ fn fn_sig_for_fn_abi<'tcx>( ) } ty::CoroutineClosure(def_id, args) => { + let coroutine_ty = Ty::new_coroutine_closure(tcx, def_id, args); let sig = args.as_coroutine_closure().coroutine_closure_sig(); let bound_vars = tcx.mk_bound_variable_kinds_from_iter( sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), @@ -111,18 +112,17 @@ fn fn_sig_for_fn_abi<'tcx>( kind: ty::BoundRegionKind::BrEnv, }; let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br); - // When this `CoroutineClosure` comes from a `ConstructCoroutineInClosureShim`, // make sure we respect the `target_kind` in that shim. // FIXME(async_closures): This shouldn't be needed, and we should be populating // a separate def-id for these bodies. - let mut kind = args.as_coroutine_closure().kind(); - if let InstanceDef::ConstructCoroutineInClosureShim { target_kind, .. } = instance.def { - kind = target_kind; + let mut coroutine_kind = args.as_coroutine_closure().kind(); + + if let InstanceDef::ConstructCoroutineInClosureShim { .. } = instance.def { + coroutine_kind = ty::ClosureKind::FnOnce; } - let env_ty = - tcx.closure_env_ty(Ty::new_coroutine_closure(tcx, def_id, args), kind, env_region); + let env_ty = tcx.closure_env_ty(coroutine_ty, coroutine_kind, env_region); let sig = sig.skip_binder(); ty::Binder::bind_with_vars( @@ -132,7 +132,7 @@ fn fn_sig_for_fn_abi<'tcx>( tcx, args.as_coroutine_closure().parent_args(), tcx.coroutine_for_closure(def_id), - kind, + coroutine_kind, env_region, args.as_coroutine_closure().tupled_upvars_ty(), args.as_coroutine_closure().coroutine_captures_by_ref_ty(), @@ -161,7 +161,7 @@ fn fn_sig_for_fn_abi<'tcx>( // make sure we respect the `target_kind` in that shim. // FIXME(async_closures): This shouldn't be needed, and we should be populating // a separate def-id for these bodies. - if let InstanceDef::CoroutineKindShim { target_kind, .. } = instance.def { + if let InstanceDef::CoroutineKindShim { .. } = instance.def { // Grab the parent coroutine-closure. It has the same args for the purposes // of instantiation, so this will be okay to do. let ty::CoroutineClosure(_, coroutine_closure_args) = *tcx @@ -181,7 +181,7 @@ fn fn_sig_for_fn_abi<'tcx>( tcx, coroutine_closure_args.parent_args(), did, - target_kind, + ty::ClosureKind::FnOnce, tcx.lifetimes.re_erased, coroutine_closure_args.tupled_upvars_ty(), coroutine_closure_args.coroutine_captures_by_ref_ty(), diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 2816bcc888b..c2ea89f4c29 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -282,7 +282,6 @@ fn resolve_associated_item<'tcx>( Some(Instance { def: ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id, - target_kind: ty::ClosureKind::FnOnce, }, args, }) @@ -297,25 +296,19 @@ fn resolve_associated_item<'tcx>( { match *rcvr_args.type_at(0).kind() { ty::CoroutineClosure(coroutine_closure_def_id, args) => { - match (target_kind, args.as_coroutine_closure().kind()) { - (ClosureKind::FnOnce | ClosureKind::FnMut, ClosureKind::Fn) - | (ClosureKind::FnOnce, ClosureKind::FnMut) => { - // If we're computing `AsyncFnOnce`/`AsyncFnMut` for a by-ref closure, - // or `AsyncFnOnce` for a by-mut closure, then construct a new body that - // has the right return types. - // - // Specifically, `AsyncFnMut` for a by-ref coroutine-closure just needs - // to have its input and output types fixed (`&mut self` and returning - // `i16` coroutine kind). - Some(Instance { - def: ty::InstanceDef::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - target_kind, - }, - args, - }) - } - _ => Some(Instance::new(coroutine_closure_def_id, args)), + if target_kind == ClosureKind::FnOnce + && args.as_coroutine_closure().kind() != ClosureKind::FnOnce + { + // If we're computing `AsyncFnOnce` for a by-ref closure then + // construct a new body that has the right return types. + Some(Instance { + def: ty::InstanceDef::ConstructCoroutineInClosureShim { + coroutine_closure_def_id, + }, + args, + }) + } else { + Some(Instance::new(coroutine_closure_def_id, args)) } } ty::Closure(closure_def_id, args) => { diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index f47fe560b07..cfaf533088a 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2042,18 +2042,16 @@ impl + ?Sized, A: Allocator> AsyncFnOnce #[unstable(feature = "async_fn_traits", issue = "none")] impl + ?Sized, A: Allocator> AsyncFnMut for Box { - type CallMutFuture<'a> = F::CallMutFuture<'a> where Self: 'a; + type CallRefFuture<'a> = F::CallRefFuture<'a> where Self: 'a; - extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallMutFuture<'_> { + extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallRefFuture<'_> { F::async_call_mut(self, args) } } #[unstable(feature = "async_fn_traits", issue = "none")] impl + ?Sized, A: Allocator> AsyncFn for Box { - type CallFuture<'a> = F::CallFuture<'a> where Self: 'a; - - extern "rust-call" fn async_call(&self, args: Args) -> Self::CallFuture<'_> { + extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> { F::async_call(self, args) } } diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs index d6b06ffb7fc..6c8a0daf6f3 100644 --- a/library/core/src/ops/async_function.rs +++ b/library/core/src/ops/async_function.rs @@ -10,15 +10,9 @@ use crate::marker::Tuple; #[must_use = "async closures are lazy and do nothing unless called"] #[lang = "async_fn"] pub trait AsyncFn: AsyncFnMut { - /// Future returned by [`AsyncFn::async_call`]. - #[unstable(feature = "async_fn_traits", issue = "none")] - type CallFuture<'a>: Future - where - Self: 'a; - /// Call the [`AsyncFn`], returning a future which may borrow from the called closure. #[unstable(feature = "async_fn_traits", issue = "none")] - extern "rust-call" fn async_call(&self, args: Args) -> Self::CallFuture<'_>; + extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_>; } /// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait. @@ -30,15 +24,15 @@ pub trait AsyncFn: AsyncFnMut { #[must_use = "async closures are lazy and do nothing unless called"] #[lang = "async_fn_mut"] pub trait AsyncFnMut: AsyncFnOnce { - /// Future returned by [`AsyncFnMut::async_call_mut`]. + /// Future returned by [`AsyncFnMut::async_call_mut`] and [`AsyncFn::async_call`]. #[unstable(feature = "async_fn_traits", issue = "none")] - type CallMutFuture<'a>: Future + type CallRefFuture<'a>: Future where Self: 'a; /// Call the [`AsyncFnMut`], returning a future which may borrow from the called closure. #[unstable(feature = "async_fn_traits", issue = "none")] - extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallMutFuture<'_>; + extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallRefFuture<'_>; } /// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait. @@ -72,9 +66,7 @@ mod impls { where F: AsyncFn, { - type CallFuture<'a> = F::CallFuture<'a> where Self: 'a; - - extern "rust-call" fn async_call(&self, args: A) -> Self::CallFuture<'_> { + extern "rust-call" fn async_call(&self, args: A) -> Self::CallRefFuture<'_> { F::async_call(*self, args) } } @@ -84,9 +76,9 @@ mod impls { where F: AsyncFn, { - type CallMutFuture<'a> = F::CallFuture<'a> where Self: 'a; + type CallRefFuture<'a> = F::CallRefFuture<'a> where Self: 'a; - extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallMutFuture<'_> { + extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallRefFuture<'_> { F::async_call(*self, args) } } @@ -97,7 +89,7 @@ mod impls { F: AsyncFn, { type Output = F::Output; - type CallOnceFuture = F::CallFuture<'a>; + type CallOnceFuture = F::CallRefFuture<'a>; extern "rust-call" fn async_call_once(self, args: A) -> Self::CallOnceFuture { F::async_call(self, args) @@ -109,9 +101,9 @@ mod impls { where F: AsyncFnMut, { - type CallMutFuture<'a> = F::CallMutFuture<'a> where Self: 'a; + type CallRefFuture<'a> = F::CallRefFuture<'a> where Self: 'a; - extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallMutFuture<'_> { + extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallRefFuture<'_> { F::async_call_mut(*self, args) } } @@ -122,7 +114,7 @@ mod impls { F: AsyncFnMut, { type Output = F::Output; - type CallOnceFuture = F::CallMutFuture<'a>; + type CallOnceFuture = F::CallRefFuture<'a>; extern "rust-call" fn async_call_once(self, args: A) -> Self::CallOnceFuture { F::async_call_mut(self, args) diff --git a/src/doc/unstable-book/src/library-features/async-fn-traits.md b/src/doc/unstable-book/src/library-features/async-fn-traits.md index e1c3f067e5b..a0edb3c7dd2 100644 --- a/src/doc/unstable-book/src/library-features/async-fn-traits.md +++ b/src/doc/unstable-book/src/library-features/async-fn-traits.md @@ -10,4 +10,4 @@ for creating custom closure-like types that return futures. [`AsyncFn*`]: ../../std/ops/trait.AsyncFn.html The main difference to the `Fn*` family of traits is that `AsyncFn` can return a future -that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFn::CallFuture` does). +that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFnMut::CallRefFuture` does). diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir index 1fae40c5f40..6ca3dd61005 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_move -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir index 1fae40c5f40..6ca3dd61005 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_move -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-abort.mir deleted file mode 100644 index 9886d6f68a4..00000000000 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-abort.mir +++ /dev/null @@ -1,47 +0,0 @@ -// MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_mut - -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}, _2: ResumeTy) -> () -yields () - { - debug _task_context => _2; - debug a => (_1.0: i32); - debug b => (*(_1.1: &i32)); - let mut _0: (); - let _3: i32; - scope 1 { - debug a => _3; - let _4: &i32; - scope 2 { - debug a => _4; - let _5: &i32; - scope 3 { - debug b => _5; - } - } - } - - bb0: { - StorageLive(_3); - _3 = (_1.0: i32); - FakeRead(ForLet(None), _3); - StorageLive(_4); - _4 = &_3; - FakeRead(ForLet(None), _4); - StorageLive(_5); - _5 = &(*(_1.1: &i32)); - FakeRead(ForLet(None), _5); - _0 = const (); - StorageDead(_5); - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; - } - - bb1: { - return; - } - - bb2 (cleanup): { - resume; - } -} diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-unwind.mir deleted file mode 100644 index 9886d6f68a4..00000000000 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-unwind.mir +++ /dev/null @@ -1,47 +0,0 @@ -// MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_mut - -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}, _2: ResumeTy) -> () -yields () - { - debug _task_context => _2; - debug a => (_1.0: i32); - debug b => (*(_1.1: &i32)); - let mut _0: (); - let _3: i32; - scope 1 { - debug a => _3; - let _4: &i32; - scope 2 { - debug a => _4; - let _5: &i32; - scope 3 { - debug b => _5; - } - } - } - - bb0: { - StorageLive(_3); - _3 = (_1.0: i32); - FakeRead(ForLet(None), _3); - StorageLive(_4); - _4 = &_3; - FakeRead(ForLet(None), _4); - StorageLive(_5); - _5 = &(*(_1.1: &i32)); - FakeRead(ForLet(None), _5); - _0 = const (); - StorageDead(_5); - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; - } - - bb1: { - return; - } - - bb2 (cleanup): { - resume; - } -} diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir index 21a9f6f8721..b5768e14452 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move -fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:39:33: 39:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}; +fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:37:33: 37:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:39:53: 42:10 (#0)} { a: move _2, b: move (_1.0: i32) }; + _0 = {coroutine@$DIR/async_closure_shims.rs:37:53: 40:10 (#0)} { a: move _2, b: move (_1.0: i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir index 21a9f6f8721..b5768e14452 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move -fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:39:33: 39:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}; +fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:37:33: 37:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:39:53: 42:10 (#0)} { a: move _2, b: move (_1.0: i32) }; + _0 = {coroutine@$DIR/async_closure_shims.rs:37:53: 40:10 (#0)} { a: move _2, b: move (_1.0: i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-abort.mir deleted file mode 100644 index 1cfb6c2f3ea..00000000000 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-abort.mir +++ /dev/null @@ -1,16 +0,0 @@ -// MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_mut - -fn main::{closure#0}::{closure#0}(_1: &mut {async closure@$DIR/async_closure_shims.rs:39:33: 39:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10} { - debug a => _2; - debug b => ((*_1).0: i32); - let mut _0: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}; - let mut _3: &i32; - - bb0: { - StorageLive(_3); - _3 = &((*_1).0: i32); - _0 = {coroutine@$DIR/async_closure_shims.rs:39:53: 42:10 (#0)} { a: _2, b: move _3 }; - StorageDead(_3); - return; - } -} diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-unwind.mir deleted file mode 100644 index 1cfb6c2f3ea..00000000000 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-unwind.mir +++ /dev/null @@ -1,16 +0,0 @@ -// MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_mut - -fn main::{closure#0}::{closure#0}(_1: &mut {async closure@$DIR/async_closure_shims.rs:39:33: 39:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10} { - debug a => _2; - debug b => ((*_1).0: i32); - let mut _0: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}; - let mut _3: &i32; - - bb0: { - StorageLive(_3); - _3 = &((*_1).0: i32); - _0 = {coroutine@$DIR/async_closure_shims.rs:39:53: 42:10 (#0)} { a: _2, b: move _3 }; - StorageDead(_3); - return; - } -} diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs index 5e875321400..47c41ed0500 100644 --- a/tests/mir-opt/async_closure_shims.rs +++ b/tests/mir-opt/async_closure_shims.rs @@ -30,8 +30,6 @@ async fn call_once(f: impl AsyncFnOnce(i32)) { } // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir -// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.mir -// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.mir // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.mir pub fn main() { block_on(async { diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr index dae45825f37..0a1e30c1253 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=?15t witness=?6t}` + | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?16t witness=?6t}` | | | expected `async` closure body, found `()` | - = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?15t witness=?6t}` + = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?16t witness=?6t}` found unit type `()` error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-fn/dyn-pos.rs b/tests/ui/async-await/async-fn/dyn-pos.rs index e817a1b518f..772c7d15cfd 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.rs +++ b/tests/ui/async-await/async-fn/dyn-pos.rs @@ -4,9 +4,6 @@ fn foo(x: &dyn async Fn()) {} //~^ ERROR the trait `AsyncFn` cannot be made into an object -//~| ERROR the trait `AsyncFn` cannot be made into an object -//~| ERROR the trait `AsyncFn` cannot be made into an object -//~| ERROR the trait `AsyncFn` cannot be made into an object //~| ERROR the trait `AsyncFnMut` cannot be made into an object //~| ERROR the trait `AsyncFnMut` cannot be made into an object //~| ERROR the trait `AsyncFnMut` cannot be made into an object diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr index 488c5d06938..3bef5a27897 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.stderr +++ b/tests/ui/async-await/async-fn/dyn-pos.stderr @@ -1,17 +1,3 @@ -error[E0038]: the trait `AsyncFn` cannot be made into an object - --> $DIR/dyn-pos.rs:5:16 - | -LL | fn foo(x: &dyn async Fn()) {} - | ^^^^^^^^^^ `AsyncFn` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL - | - = note: the trait cannot be made into an object because it contains the generic associated type `CallFuture` - = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead: - &F - std::boxed::Box - error[E0038]: the trait `AsyncFnMut` cannot be made into an object --> $DIR/dyn-pos.rs:5:16 | @@ -21,27 +7,12 @@ LL | fn foo(x: &dyn async Fn()) {} note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL | - = note: the trait cannot be made into an object because it contains the generic associated type `CallMutFuture` + = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture` = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead: &F &mut F std::boxed::Box -error[E0038]: the trait `AsyncFn` cannot be made into an object - --> $DIR/dyn-pos.rs:5:16 - | -LL | fn foo(x: &dyn async Fn()) {} - | ^^^^^^^^^^ `AsyncFn` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL - | - = note: the trait cannot be made into an object because it contains the generic associated type `CallFuture` - = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead: - &F - std::boxed::Box - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0038]: the trait `AsyncFnMut` cannot be made into an object --> $DIR/dyn-pos.rs:5:16 | @@ -51,28 +22,13 @@ LL | fn foo(x: &dyn async Fn()) {} note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL | - = note: the trait cannot be made into an object because it contains the generic associated type `CallMutFuture` + = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture` = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead: &F &mut F std::boxed::Box = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0038]: the trait `AsyncFn` cannot be made into an object - --> $DIR/dyn-pos.rs:5:16 - | -LL | fn foo(x: &dyn async Fn()) {} - | ^^^^^^^^^^ `AsyncFn` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL - | - = note: the trait cannot be made into an object because it contains the generic associated type `CallFuture` - = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead: - &F - std::boxed::Box - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0038]: the trait `AsyncFnMut` cannot be made into an object --> $DIR/dyn-pos.rs:5:16 | @@ -82,7 +38,7 @@ LL | fn foo(x: &dyn async Fn()) {} note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL | - = note: the trait cannot be made into an object because it contains the generic associated type `CallMutFuture` + = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture` = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead: &F &mut F @@ -98,14 +54,11 @@ LL | fn foo(x: &dyn async Fn()) {} note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL | - = note: the trait cannot be made into an object because it contains the generic associated type `CallFuture` - ::: $SRC_DIR/core/src/ops/async_function.rs:LL:COL - | - = note: the trait cannot be made into an object because it contains the generic associated type `CallMutFuture` + = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture` = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead: &F std::boxed::Box -error: aborting due to 7 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0038`.