diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/type_check/input_output.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/callee.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/closure.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/upvar.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/visit.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/instance.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/coroutine/by_move_body.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/pass_manager.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/shim.rs | 98 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/legacy.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/v0.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/abi.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 33 |
18 files changed, 89 insertions, 214 deletions
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<Body<'tcx>>, - /// 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<Body<'tcx>>, - /// The layout of a coroutine. This field is populated after the state transform pass. pub coroutine_layout: Option<CoroutineLayout<'tcx>>, @@ -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<CoroutineKind> { 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) => { |
