Skip to content

Commit 4efe2f2

Browse files
committed
Prereq4 for async drop - needs_async_drop query fixes and some cleanup from previous async drop glue implementation
1 parent 3534899 commit 4efe2f2

File tree

32 files changed

+158
-1777
lines changed

32 files changed

+158
-1777
lines changed

compiler/rustc_codegen_cranelift/src/abi/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,9 @@ pub(crate) fn codegen_terminator_call<'tcx>(
441441
Err(instance) => Some(instance),
442442
}
443443
}
444-
InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) => {
444+
// We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
445+
// it is `func returning noop future`
446+
InstanceKind::DropGlue(_, None) => {
445447
// empty drop glue - a nop.
446448
let dest = target.expect("Non terminating drop_in_place_real???");
447449
let ret_block = fx.get_block(dest);
@@ -707,9 +709,8 @@ pub(crate) fn codegen_drop<'tcx>(
707709
let ty = drop_place.layout().ty;
708710
let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty);
709711

710-
if let ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) =
711-
drop_instance.def
712-
{
712+
// AsyncDropGlueCtorShim can't be here
713+
if let ty::InstanceKind::DropGlue(_, None) = drop_instance.def {
713714
// we don't actually need to drop anything
714715
} else {
715716
match ty.kind() {

compiler/rustc_codegen_ssa/src/mir/block.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -867,10 +867,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
867867

868868
let def = instance.map(|i| i.def);
869869

870-
if let Some(
871-
ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None),
872-
) = def
873-
{
870+
// We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
871+
// it is `func returning noop future`
872+
if let Some(ty::InstanceKind::DropGlue(_, None)) = def {
874873
// Empty drop glue; a no-op.
875874
let target = target.unwrap();
876875
return helper.funclet_br(self, bx, target, mergeable_succ);

compiler/rustc_hir/src/lang_items.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -187,20 +187,9 @@ language_item_table! {
187187

188188
Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None;
189189
Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None;
190-
191-
AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::Exact(0);
192-
AsyncDestruct, sym::async_destruct, async_destruct_trait, Target::Trait, GenericRequirement::Exact(0);
190+
AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::None;
193191
AsyncDropInPlace, sym::async_drop_in_place, async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
194192
AsyncDropInPlacePoll, sym::async_drop_in_place_poll, async_drop_in_place_poll_fn, Target::Closure, GenericRequirement::Exact(1);
195-
SurfaceAsyncDropInPlace, sym::surface_async_drop_in_place, surface_async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
196-
AsyncDropSurfaceDropInPlace, sym::async_drop_surface_drop_in_place, async_drop_surface_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
197-
AsyncDropSlice, sym::async_drop_slice, async_drop_slice_fn, Target::Fn, GenericRequirement::Exact(1);
198-
AsyncDropChain, sym::async_drop_chain, async_drop_chain_fn, Target::Fn, GenericRequirement::Exact(2);
199-
AsyncDropNoop, sym::async_drop_noop, async_drop_noop_fn, Target::Fn, GenericRequirement::Exact(0);
200-
AsyncDropDeferredDropInPlace, sym::async_drop_deferred_drop_in_place, async_drop_deferred_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
201-
AsyncDropFuse, sym::async_drop_fuse, async_drop_fuse_fn, Target::Fn, GenericRequirement::Exact(1);
202-
AsyncDropDefer, sym::async_drop_defer, async_drop_defer_fn, Target::Fn, GenericRequirement::Exact(1);
203-
AsyncDropEither, sym::async_drop_either, async_drop_either_fn, Target::Fn, GenericRequirement::Exact(3);
204193

205194
CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1);
206195
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1);
@@ -335,7 +324,6 @@ language_item_table! {
335324

336325
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
337326
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
338-
FallbackSurfaceDrop, sym::fallback_surface_drop, fallback_surface_drop_fn, Target::Fn, GenericRequirement::None;
339327
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
340328

341329
/// For all binary crates without `#![no_main]`, Rust will generate a "main" function.

compiler/rustc_hir_typeck/src/callee.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@ pub(crate) fn check_legal_trait_for_method_call(
3434
receiver: Option<Span>,
3535
expr_span: Span,
3636
trait_id: DefId,
37-
body_id: DefId,
37+
_body_id: DefId,
3838
) -> Result<(), ErrorGuaranteed> {
39-
if tcx.is_lang_item(trait_id, LangItem::Drop)
40-
&& tcx.lang_items().fallback_surface_drop_fn() != Some(body_id)
41-
{
39+
if tcx.is_lang_item(trait_id, LangItem::Drop) {
4240
let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {
4341
errors::ExplicitDestructorCallSugg::Snippet {
4442
lo: expr_span.shrink_to_lo(),

compiler/rustc_middle/src/query/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,10 @@ rustc_queries! {
15241524
query is_unpin_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
15251525
desc { "computing whether `{}` is `Unpin`", env.value }
15261526
}
1527+
/// Query backing `Ty::is_async_drop`.
1528+
query is_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
1529+
desc { "computing whether `{}` is `AsyncDrop`", env.value }
1530+
}
15271531
/// Query backing `Ty::needs_drop`.
15281532
query needs_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
15291533
desc { "computing whether `{}` needs drop", env.value }
@@ -1556,6 +1560,14 @@ rustc_queries! {
15561560
cache_on_disk_if { true }
15571561
}
15581562

1563+
/// A list of types where the ADT requires async drop if and only if any of
1564+
/// those types require async drop. If the ADT is known to always need async drop
1565+
/// then `Err(AlwaysRequiresDrop)` is returned.
1566+
query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
1567+
desc { |tcx| "computing when `{}` needs async drop", tcx.def_path_str(def_id) }
1568+
cache_on_disk_if { true }
1569+
}
1570+
15591571
/// A list of types where the ADT requires drop if and only if any of those types
15601572
/// has significant drop. A type marked with the attribute `rustc_insignificant_dtor`
15611573
/// is considered to not be significant. A drop is significant if it is implemented

compiler/rustc_middle/src/ty/context.rs

-1
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,6 @@ macro_rules! bidirectional_lang_item_map {
682682

683683
bidirectional_lang_item_map! {
684684
// tidy-alphabetical-start
685-
AsyncDestruct,
686685
AsyncFn,
687686
AsyncFnKindHelper,
688687
AsyncFnKindUpvars,

compiler/rustc_middle/src/ty/sty.rs

+1-125
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use std::assert_matches::debug_assert_matches;
66
use std::borrow::Cow;
7-
use std::iter;
87
use std::ops::{ControlFlow, Range};
98

109
use hir::def::{CtorKind, DefKind};
@@ -20,7 +19,7 @@ use rustc_type_ir::TyKind::*;
2019
use rustc_type_ir::visit::TypeVisitableExt;
2120
use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind};
2221
use tracing::instrument;
23-
use ty::util::{AsyncDropGlueMorphology, IntTypeExt};
22+
use ty::util::IntTypeExt;
2423

2524
use super::GenericParamDefKind;
2625
use crate::infer::canonical::Canonical;
@@ -1018,10 +1017,6 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
10181017
self.discriminant_ty(interner)
10191018
}
10201019

1021-
fn async_destructor_ty(self, interner: TyCtxt<'tcx>) -> Ty<'tcx> {
1022-
self.async_destructor_ty(interner)
1023-
}
1024-
10251020
fn has_unsafe_fields(self) -> bool {
10261021
Ty::has_unsafe_fields(self)
10271022
}
@@ -1548,125 +1543,6 @@ impl<'tcx> Ty<'tcx> {
15481543
}
15491544
}
15501545

1551-
/// Returns the type of the async destructor of this type.
1552-
pub fn async_destructor_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
1553-
match self.async_drop_glue_morphology(tcx) {
1554-
AsyncDropGlueMorphology::Noop => {
1555-
return Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop)
1556-
.instantiate_identity();
1557-
}
1558-
AsyncDropGlueMorphology::DeferredDropInPlace => {
1559-
let drop_in_place =
1560-
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropDeferredDropInPlace)
1561-
.instantiate(tcx, &[self.into()]);
1562-
return Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse)
1563-
.instantiate(tcx, &[drop_in_place.into()]);
1564-
}
1565-
AsyncDropGlueMorphology::Custom => (),
1566-
}
1567-
1568-
match *self.kind() {
1569-
ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {
1570-
let assoc_items = tcx
1571-
.associated_item_def_ids(tcx.require_lang_item(LangItem::AsyncDestruct, None));
1572-
Ty::new_projection(tcx, assoc_items[0], [self])
1573-
}
1574-
1575-
ty::Array(elem_ty, _) | ty::Slice(elem_ty) => {
1576-
let dtor = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropSlice)
1577-
.instantiate(tcx, &[elem_ty.into()]);
1578-
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse)
1579-
.instantiate(tcx, &[dtor.into()])
1580-
}
1581-
1582-
ty::Adt(adt_def, args) if adt_def.is_enum() || adt_def.is_struct() => self
1583-
.adt_async_destructor_ty(
1584-
tcx,
1585-
adt_def.variants().iter().map(|v| v.fields.iter().map(|f| f.ty(tcx, args))),
1586-
),
1587-
ty::Tuple(tys) => self.adt_async_destructor_ty(tcx, iter::once(tys)),
1588-
ty::Closure(_, args) => {
1589-
self.adt_async_destructor_ty(tcx, iter::once(args.as_closure().upvar_tys()))
1590-
}
1591-
ty::CoroutineClosure(_, args) => self
1592-
.adt_async_destructor_ty(tcx, iter::once(args.as_coroutine_closure().upvar_tys())),
1593-
1594-
ty::Adt(adt_def, _) => {
1595-
assert!(adt_def.is_union());
1596-
1597-
let surface_drop = self.surface_async_dropper_ty(tcx).unwrap();
1598-
1599-
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse)
1600-
.instantiate(tcx, &[surface_drop.into()])
1601-
}
1602-
1603-
ty::Bound(..)
1604-
| ty::Foreign(_)
1605-
| ty::Placeholder(_)
1606-
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1607-
bug!("`async_destructor_ty` applied to unexpected type: {self:?}")
1608-
}
1609-
1610-
_ => bug!("`async_destructor_ty` is not yet implemented for type: {self:?}"),
1611-
}
1612-
}
1613-
1614-
fn adt_async_destructor_ty<I>(self, tcx: TyCtxt<'tcx>, variants: I) -> Ty<'tcx>
1615-
where
1616-
I: Iterator + ExactSizeIterator,
1617-
I::Item: IntoIterator<Item = Ty<'tcx>>,
1618-
{
1619-
debug_assert_eq!(self.async_drop_glue_morphology(tcx), AsyncDropGlueMorphology::Custom);
1620-
1621-
let defer = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropDefer);
1622-
let chain = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain);
1623-
1624-
let noop =
1625-
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop).instantiate_identity();
1626-
let either = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropEither);
1627-
1628-
let variants_dtor = variants
1629-
.into_iter()
1630-
.map(|variant| {
1631-
variant
1632-
.into_iter()
1633-
.map(|ty| defer.instantiate(tcx, &[ty.into()]))
1634-
.reduce(|acc, next| chain.instantiate(tcx, &[acc.into(), next.into()]))
1635-
.unwrap_or(noop)
1636-
})
1637-
.reduce(|other, matched| {
1638-
either.instantiate(tcx, &[other.into(), matched.into(), self.into()])
1639-
})
1640-
.unwrap();
1641-
1642-
let dtor = if let Some(dropper_ty) = self.surface_async_dropper_ty(tcx) {
1643-
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain)
1644-
.instantiate(tcx, &[dropper_ty.into(), variants_dtor.into()])
1645-
} else {
1646-
variants_dtor
1647-
};
1648-
1649-
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse)
1650-
.instantiate(tcx, &[dtor.into()])
1651-
}
1652-
1653-
fn surface_async_dropper_ty(self, tcx: TyCtxt<'tcx>) -> Option<Ty<'tcx>> {
1654-
let adt_def = self.ty_adt_def()?;
1655-
let dropper = adt_def
1656-
.async_destructor(tcx)
1657-
.map(|_| LangItem::SurfaceAsyncDropInPlace)
1658-
.or_else(|| adt_def.destructor(tcx).map(|_| LangItem::AsyncDropSurfaceDropInPlace))?;
1659-
Some(Ty::async_destructor_combinator(tcx, dropper).instantiate(tcx, &[self.into()]))
1660-
}
1661-
1662-
fn async_destructor_combinator(
1663-
tcx: TyCtxt<'tcx>,
1664-
lang_item: LangItem,
1665-
) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
1666-
tcx.fn_sig(tcx.require_lang_item(lang_item, None))
1667-
.map_bound(|fn_sig| fn_sig.output().no_bound_vars().unwrap())
1668-
}
1669-
16701546
/// Returns the type of metadata for (potentially wide) pointers to this type,
16711547
/// or the struct tail if the metadata type cannot be determined.
16721548
pub fn ptr_metadata_ty_or_tail(

0 commit comments

Comments
 (0)