Auto merge of #124662 - zetanumbers:needs_async_drop, r=oli-obk
Implement `needs_async_drop` in rustc and optimize async drop glue
This PR expands on #121801 and implements `Ty::needs_async_drop` which works almost exactly the same as `Ty::needs_drop`, which is needed for #123948.
Also made compiler's async drop code to look more like compiler's regular drop code, which enabled me to write an optimization where types which do not use `AsyncDrop` can simply forward async drop glue to `drop_in_place`. This made size of the async block from the [async_drop test](67980dd6fb/tests/ui/async-await/async-drop.rs
) to decrease by 12%.
This commit is contained in:
commit
99cb42c296
19 changed files with 382 additions and 194 deletions
|
@ -12,7 +12,7 @@ use rustc_middle::mir::{
|
|||
Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason, RETURN_PLACE,
|
||||
};
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::util::Discr;
|
||||
use rustc_middle::ty::util::{AsyncDropGlueMorphology, Discr};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::source_map::respan;
|
||||
|
@ -116,15 +116,25 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
|||
}
|
||||
|
||||
fn build(self) -> Body<'tcx> {
|
||||
let (tcx, def_id, Some(self_ty)) = (self.tcx, self.def_id, self.self_ty) else {
|
||||
let (tcx, Some(self_ty)) = (self.tcx, self.self_ty) else {
|
||||
return self.build_zst_output();
|
||||
};
|
||||
match self_ty.async_drop_glue_morphology(tcx) {
|
||||
AsyncDropGlueMorphology::Noop => span_bug!(
|
||||
self.span,
|
||||
"async drop glue shim generator encountered type with noop async drop glue morphology"
|
||||
),
|
||||
AsyncDropGlueMorphology::DeferredDropInPlace => {
|
||||
return self.build_deferred_drop_in_place();
|
||||
}
|
||||
AsyncDropGlueMorphology::Custom => (),
|
||||
}
|
||||
|
||||
let surface_drop_kind = || {
|
||||
let param_env = tcx.param_env_reveal_all_normalized(def_id);
|
||||
if self_ty.has_surface_async_drop(tcx, param_env) {
|
||||
let adt_def = self_ty.ty_adt_def()?;
|
||||
if adt_def.async_destructor(tcx).is_some() {
|
||||
Some(SurfaceDropKind::Async)
|
||||
} else if self_ty.has_surface_drop(tcx, param_env) {
|
||||
} else if adt_def.destructor(tcx).is_some() {
|
||||
Some(SurfaceDropKind::Sync)
|
||||
} else {
|
||||
None
|
||||
|
@ -267,6 +277,13 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
|||
self.return_()
|
||||
}
|
||||
|
||||
fn build_deferred_drop_in_place(mut self) -> Body<'tcx> {
|
||||
self.put_self();
|
||||
let deferred = self.combine_deferred_drop_in_place();
|
||||
self.combine_fuse(deferred);
|
||||
self.return_()
|
||||
}
|
||||
|
||||
fn build_fused_async_surface(mut self) -> Body<'tcx> {
|
||||
self.put_self();
|
||||
let surface = self.combine_async_surface();
|
||||
|
@ -441,6 +458,14 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
fn combine_deferred_drop_in_place(&mut self) -> Ty<'tcx> {
|
||||
self.apply_combinator(
|
||||
1,
|
||||
LangItem::AsyncDropDeferredDropInPlace,
|
||||
&[self.self_ty.unwrap().into()],
|
||||
)
|
||||
}
|
||||
|
||||
fn combine_fuse(&mut self, inner_future_ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.apply_combinator(1, LangItem::AsyncDropFuse, &[inner_future_ty.into()])
|
||||
}
|
||||
|
@ -481,7 +506,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
|||
if let Some(ty) = self.self_ty {
|
||||
debug_assert_eq!(
|
||||
output.ty(&self.locals, self.tcx),
|
||||
ty.async_destructor_ty(self.tcx, self.param_env),
|
||||
ty.async_destructor_ty(self.tcx),
|
||||
"output async destructor types did not match for type: {ty:?}",
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue