Only split by-ref/by-move futures for async closures
This commit is contained in:
parent
e760daa6a7
commit
05116c5c30
33 changed files with 119 additions and 432 deletions
|
@ -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)
|
||||
|
|
|
@ -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) |
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue