Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2b693c0

Browse files
committedFeb 9, 2025·
Prereq4 for async drop - needs_async_drop query fixes and some cleanup from previous async drop glue implementation
1 parent c561fb9 commit 2b693c0

File tree

30 files changed

+146
-1774
lines changed

30 files changed

+146
-1774
lines changed
 

‎compiler/rustc_codegen_cranelift/src/abi/mod.rs

Lines changed: 5 additions & 4 deletions
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

Lines changed: 3 additions & 4 deletions
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

Lines changed: 1 addition & 13 deletions
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

Lines changed: 2 additions & 4 deletions
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

Lines changed: 12 additions & 0 deletions
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

Lines changed: 0 additions & 1 deletion
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

Lines changed: 1 addition & 125 deletions
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(

‎compiler/rustc_middle/src/ty/util.rs

Lines changed: 68 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -436,25 +436,6 @@ impl<'tcx> TyCtxt<'tcx> {
436436
Some(ty::AsyncDestructor { future, ctor })
437437
}
438438

439-
/// Returns async drop glue morphology for a definition. To get async drop
440-
/// glue morphology for a type see [`Ty::async_drop_glue_morphology`].
441-
//
442-
// FIXME: consider making this a query
443-
pub fn async_drop_glue_morphology(self, did: DefId) -> AsyncDropGlueMorphology {
444-
let ty: Ty<'tcx> = self.type_of(did).instantiate_identity();
445-
446-
// Async drop glue morphology is an internal detail, so
447-
// using `TypingMode::PostAnalysis` probably should be fine.
448-
let typing_env = ty::TypingEnv::fully_monomorphized();
449-
if ty.needs_async_drop(self, typing_env) {
450-
AsyncDropGlueMorphology::Custom
451-
} else if ty.needs_drop(self, typing_env) {
452-
AsyncDropGlueMorphology::DeferredDropInPlace
453-
} else {
454-
AsyncDropGlueMorphology::Noop
455-
}
456-
}
457-
458439
/// Returns the set of types that are required to be alive in
459440
/// order to run the destructor of `def` (see RFCs 769 and
460441
/// 1238).
@@ -1095,18 +1076,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for WeakAliasTypeExpander<'tcx> {
10951076
}
10961077
}
10971078

1098-
/// Indicates the form of `AsyncDestruct::Destructor`. Used to simplify async
1099-
/// drop glue for types not using async drop.
1100-
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
1101-
pub enum AsyncDropGlueMorphology {
1102-
/// Async destructor simply does nothing
1103-
Noop,
1104-
/// Async destructor simply runs `drop_in_place`
1105-
DeferredDropInPlace,
1106-
/// Async destructor has custom logic
1107-
Custom,
1108-
}
1109-
11101079
impl<'tcx> Ty<'tcx> {
11111080
/// Returns the `Size` for primitive types (bool, uint, int, char, float).
11121081
pub fn primitive_size(self, tcx: TyCtxt<'tcx>) -> Size {
@@ -1276,16 +1245,17 @@ impl<'tcx> Ty<'tcx> {
12761245
}
12771246
}
12781247

1279-
/// Get morphology of the async drop glue, needed for types which do not
1280-
/// use async drop. To get async drop glue morphology for a definition see
1281-
/// [`TyCtxt::async_drop_glue_morphology`]. Used for `AsyncDestruct::Destructor`
1282-
/// type construction.
1283-
//
1284-
// FIXME: implement optimization to not instantiate a certain morphology of
1285-
// async drop glue too soon to allow per type optimizations, see array case
1286-
// for more info. Perhaps then remove this method and use `needs_(async_)drop`
1287-
// instead.
1288-
pub fn async_drop_glue_morphology(self, tcx: TyCtxt<'tcx>) -> AsyncDropGlueMorphology {
1248+
/// Checks whether values of this type `T` implement the `AsyncDrop` trait.
1249+
pub fn is_async_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool {
1250+
!self.is_trivially_not_async_drop()
1251+
&& tcx.is_async_drop_raw(typing_env.as_query_input(self))
1252+
}
1253+
1254+
/// Fast path helper for testing if a type is `AsyncDrop`.
1255+
///
1256+
/// Returning true means the type is known to be `!AsyncDrop`. Returning
1257+
/// `false` means nothing -- could be `AsyncDrop`, might not be.
1258+
fn is_trivially_not_async_drop(self) -> bool {
12891259
match self.kind() {
12901260
ty::Int(_)
12911261
| ty::Uint(_)
@@ -1297,46 +1267,26 @@ impl<'tcx> Ty<'tcx> {
12971267
| ty::Ref(..)
12981268
| ty::RawPtr(..)
12991269
| ty::FnDef(..)
1300-
| ty::FnPtr(..)
1301-
| ty::Infer(ty::FreshIntTy(_))
1302-
| ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop,
1303-
1270+
| ty::Error(_)
1271+
| ty::FnPtr(..) => true,
13041272
// FIXME(unsafe_binders):
13051273
ty::UnsafeBinder(_) => todo!(),
1306-
1307-
ty::Tuple(tys) if tys.is_empty() => AsyncDropGlueMorphology::Noop,
1308-
ty::Adt(adt_def, _) if adt_def.is_manually_drop() => AsyncDropGlueMorphology::Noop,
1309-
1310-
// Foreign types can never have destructors.
1311-
ty::Foreign(_) => AsyncDropGlueMorphology::Noop,
1312-
1313-
// FIXME: implement dynamic types async drops
1314-
ty::Error(_) | ty::Dynamic(..) => AsyncDropGlueMorphology::DeferredDropInPlace,
1315-
1316-
ty::Tuple(_) | ty::Array(_, _) | ty::Slice(_) => {
1317-
// Assume worst-case scenario, because we can instantiate async
1318-
// destructors in different orders:
1319-
//
1320-
// 1. Instantiate [T; N] with T = String and N = 0
1321-
// 2. Instantiate <[String; 0] as AsyncDestruct>::Destructor
1322-
//
1323-
// And viceversa, thus we cannot rely on String not using async
1324-
// drop or array having zero (0) elements
1325-
AsyncDropGlueMorphology::Custom
1326-
}
1327-
ty::Pat(ty, _) => ty.async_drop_glue_morphology(tcx),
1328-
1329-
ty::Adt(adt_def, _) => tcx.async_drop_glue_morphology(adt_def.did()),
1330-
1331-
ty::Closure(did, _)
1332-
| ty::CoroutineClosure(did, _)
1333-
| ty::Coroutine(did, _)
1334-
| ty::CoroutineWitness(did, _) => tcx.async_drop_glue_morphology(*did),
1335-
1336-
ty::Alias(..) | ty::Param(_) | ty::Bound(..) | ty::Placeholder(..) | ty::Infer(_) => {
1337-
// No specifics, but would usually mean forwarding async drop glue
1338-
AsyncDropGlueMorphology::Custom
1274+
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_not_async_drop),
1275+
ty::Pat(elem_ty, _) | ty::Slice(elem_ty) | ty::Array(elem_ty, _) => {
1276+
elem_ty.is_trivially_not_async_drop()
13391277
}
1278+
ty::Adt(..)
1279+
| ty::Bound(..)
1280+
| ty::Closure(..)
1281+
| ty::CoroutineClosure(..)
1282+
| ty::Dynamic(..)
1283+
| ty::Foreign(_)
1284+
| ty::Coroutine(..)
1285+
| ty::CoroutineWitness(..)
1286+
| ty::Infer(_)
1287+
| ty::Alias(..)
1288+
| ty::Param(_)
1289+
| ty::Placeholder(_) => false,
13401290
}
13411291
}
13421292

@@ -1382,9 +1332,6 @@ impl<'tcx> Ty<'tcx> {
13821332
/// (Note that this implies that if `ty` has an async destructor attached,
13831333
/// then `needs_async_drop` will definitely return `true` for `ty`.)
13841334
///
1385-
/// When constructing `AsyncDestruct::Destructor` type, use
1386-
/// [`Ty::async_drop_glue_morphology`] instead.
1387-
//
13881335
// FIXME(zetanumbers): Note that this method is used to check eligible types
13891336
// in unions.
13901337
#[inline]
@@ -1668,6 +1615,46 @@ pub fn needs_drop_components_with_async<'tcx>(
16681615
}
16691616
}
16701617

1618+
pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
1619+
match *ty.kind() {
1620+
ty::Bool
1621+
| ty::Char
1622+
| ty::Int(_)
1623+
| ty::Uint(_)
1624+
| ty::Float(_)
1625+
| ty::Infer(ty::IntVar(_))
1626+
| ty::Infer(ty::FloatVar(_))
1627+
| ty::Str
1628+
| ty::RawPtr(_, _)
1629+
| ty::Ref(..)
1630+
| ty::FnDef(..)
1631+
| ty::FnPtr(..)
1632+
| ty::Never
1633+
| ty::Foreign(_) => true,
1634+
1635+
ty::Alias(..)
1636+
| ty::Dynamic(..)
1637+
| ty::Error(_)
1638+
| ty::Bound(..)
1639+
| ty::Param(_)
1640+
| ty::Placeholder(_)
1641+
| ty::Infer(_)
1642+
| ty::UnsafeBinder(_) => false,
1643+
1644+
// Not trivial because they have components, and instead of looking inside,
1645+
// we'll just perform trait selection.
1646+
ty::Closure(..)
1647+
| ty::CoroutineClosure(..)
1648+
| ty::Coroutine(..)
1649+
| ty::CoroutineWitness(..)
1650+
| ty::Adt(..) => false,
1651+
1652+
ty::Array(ty, _) | ty::Slice(ty) | ty::Pat(ty, _) => is_trivially_const_drop(ty),
1653+
1654+
ty::Tuple(tys) => tys.iter().all(|ty| is_trivially_const_drop(ty)),
1655+
}
1656+
}
1657+
16711658
/// Does the equivalent of
16721659
/// ```ignore (illustrative)
16731660
/// let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();

‎compiler/rustc_mir_transform/src/shim.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ use crate::{
2424
instsimplify, mentioned_items, pass_manager as pm, remove_noop_landing_pads, simplify,
2525
};
2626

27-
mod async_destructor_ctor;
28-
2927
pub(super) fn provide(providers: &mut Providers) {
3028
providers.mir_shims = make_shim;
3129
}
@@ -130,8 +128,8 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
130128
ty::InstanceKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance),
131129
ty::InstanceKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty),
132130
ty::InstanceKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty),
133-
ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) => {
134-
async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty)
131+
ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, _ty) => {
132+
bug!("AsyncDropGlueCtorShim in re-working ({:?})", instance)
135133
}
136134
ty::InstanceKind::Virtual(..) => {
137135
bug!("InstanceKind::Virtual ({:?}) is for direct calls only", instance)

‎compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs

Lines changed: 0 additions & 639 deletions
This file was deleted.

‎compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,6 @@ where
252252
goal: Goal<I, Self>,
253253
) -> Result<Candidate<I>, NoSolution>;
254254

255-
fn consider_builtin_async_destruct_candidate(
256-
ecx: &mut EvalCtxt<'_, D>,
257-
goal: Goal<I, Self>,
258-
) -> Result<Candidate<I>, NoSolution>;
259-
260255
fn consider_builtin_destruct_candidate(
261256
ecx: &mut EvalCtxt<'_, D>,
262257
goal: Goal<I, Self>,
@@ -469,9 +464,6 @@ where
469464
Some(TraitSolverLangItem::DiscriminantKind) => {
470465
G::consider_builtin_discriminant_kind_candidate(self, goal)
471466
}
472-
Some(TraitSolverLangItem::AsyncDestruct) => {
473-
G::consider_builtin_async_destruct_candidate(self, goal)
474-
}
475467
Some(TraitSolverLangItem::Destruct) => {
476468
G::consider_builtin_destruct_candidate(self, goal)
477469
}

‎compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,13 +335,6 @@ where
335335
unreachable!("DiscriminantKind is not const")
336336
}
337337

338-
fn consider_builtin_async_destruct_candidate(
339-
_ecx: &mut EvalCtxt<'_, D>,
340-
_goal: Goal<I, Self>,
341-
) -> Result<Candidate<I>, NoSolution> {
342-
unreachable!("AsyncDestruct is not const")
343-
}
344-
345338
fn consider_builtin_destruct_candidate(
346339
ecx: &mut EvalCtxt<'_, D>,
347340
goal: Goal<I, Self>,

‎compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -859,64 +859,6 @@ where
859859
})
860860
}
861861

862-
fn consider_builtin_async_destruct_candidate(
863-
ecx: &mut EvalCtxt<'_, D>,
864-
goal: Goal<I, Self>,
865-
) -> Result<Candidate<I>, NoSolution> {
866-
let self_ty = goal.predicate.self_ty();
867-
let async_destructor_ty = match self_ty.kind() {
868-
ty::Bool
869-
| ty::Char
870-
| ty::Int(..)
871-
| ty::Uint(..)
872-
| ty::Float(..)
873-
| ty::Array(..)
874-
| ty::RawPtr(..)
875-
| ty::Ref(..)
876-
| ty::FnDef(..)
877-
| ty::FnPtr(..)
878-
| ty::Closure(..)
879-
| ty::CoroutineClosure(..)
880-
| ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
881-
| ty::Never
882-
| ty::Adt(_, _)
883-
| ty::Str
884-
| ty::Slice(_)
885-
| ty::Tuple(_)
886-
| ty::Error(_) => self_ty.async_destructor_ty(ecx.cx()),
887-
888-
ty::UnsafeBinder(_) => {
889-
// FIXME(unsafe_binders): Instantiate the binder with placeholders I guess.
890-
todo!()
891-
}
892-
893-
// We do not call `Ty::async_destructor_ty` on alias, param, or placeholder
894-
// types, which return `<self_ty as AsyncDestruct>::AsyncDestructor`
895-
// (or ICE in the case of placeholders). Projecting a type to itself
896-
// is never really productive.
897-
ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => {
898-
return Err(NoSolution);
899-
}
900-
901-
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
902-
| ty::Foreign(..)
903-
| ty::Bound(..) => panic!(
904-
"unexpected self ty `{:?}` when normalizing `<T as AsyncDestruct>::AsyncDestructor`",
905-
goal.predicate.self_ty()
906-
),
907-
908-
ty::Pat(..) | ty::Dynamic(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) => panic!(
909-
"`consider_builtin_async_destruct_candidate` is not yet implemented for type: {self_ty:?}"
910-
),
911-
};
912-
913-
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
914-
ecx.eq(goal.param_env, goal.predicate.term, async_destructor_ty.into())
915-
.expect("expected goal term to be fully unconstrained");
916-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
917-
})
918-
}
919-
920862
fn consider_builtin_destruct_candidate(
921863
_ecx: &mut EvalCtxt<'_, D>,
922864
goal: Goal<I, Self>,

‎compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -566,19 +566,6 @@ where
566566
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
567567
}
568568

569-
fn consider_builtin_async_destruct_candidate(
570-
ecx: &mut EvalCtxt<'_, D>,
571-
goal: Goal<I, Self>,
572-
) -> Result<Candidate<I>, NoSolution> {
573-
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
574-
return Err(NoSolution);
575-
}
576-
577-
// `AsyncDestruct` is automatically implemented for every type.
578-
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
579-
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
580-
}
581-
582569
fn consider_builtin_destruct_candidate(
583570
ecx: &mut EvalCtxt<'_, D>,
584571
goal: Goal<I, Self>,

‎compiler/rustc_span/src/symbol.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -469,18 +469,9 @@ symbols! {
469469
async_call_mut,
470470
async_call_once,
471471
async_closure,
472-
async_destruct,
473472
async_drop,
474-
async_drop_chain,
475-
async_drop_defer,
476-
async_drop_deferred_drop_in_place,
477-
async_drop_either,
478-
async_drop_fuse,
479473
async_drop_in_place,
480474
async_drop_in_place_poll,
481-
async_drop_noop,
482-
async_drop_slice,
483-
async_drop_surface_drop_in_place,
484475
async_fn,
485476
async_fn_in_dyn_trait,
486477
async_fn_in_trait,
@@ -929,7 +920,6 @@ symbols! {
929920
fadd_fast,
930921
fake_variadic,
931922
fallback,
932-
fallback_surface_drop,
933923
fdiv_algebraic,
934924
fdiv_fast,
935925
feature,
@@ -1996,7 +1986,6 @@ symbols! {
19961986
sub_assign,
19971987
sub_with_overflow,
19981988
suggestion,
1999-
surface_async_drop_in_place,
20001989
sym,
20011990
sync,
20021991
synthetic,

‎compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,43 +1065,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
10651065
| ty::Infer(..)
10661066
| ty::Error(_) => false,
10671067
}
1068-
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::AsyncDestruct) {
1069-
match self_ty.kind() {
1070-
ty::Bool
1071-
| ty::Char
1072-
| ty::Int(_)
1073-
| ty::Uint(_)
1074-
| ty::Float(_)
1075-
| ty::Adt(..)
1076-
| ty::Str
1077-
| ty::Array(..)
1078-
| ty::Slice(_)
1079-
| ty::RawPtr(..)
1080-
| ty::Ref(..)
1081-
| ty::FnDef(..)
1082-
| ty::FnPtr(..)
1083-
| ty::UnsafeBinder(_)
1084-
| ty::Dynamic(..)
1085-
| ty::Closure(..)
1086-
| ty::CoroutineClosure(..)
1087-
| ty::Coroutine(..)
1088-
| ty::CoroutineWitness(..)
1089-
| ty::Pat(..)
1090-
| ty::Never
1091-
| ty::Tuple(..)
1092-
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
1093-
1094-
// type parameters, opaques, and unnormalized projections don't have
1095-
// a known async destructor and may need to be normalized further or rely
1096-
// on param env for async destructor projections
1097-
ty::Param(_)
1098-
| ty::Foreign(_)
1099-
| ty::Alias(..)
1100-
| ty::Bound(..)
1101-
| ty::Placeholder(..)
1102-
| ty::Infer(_)
1103-
| ty::Error(_) => false,
1104-
}
11051068
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::PointeeTrait) {
11061069
let tail = selcx.tcx().struct_tail_raw(
11071070
self_ty,
@@ -1559,11 +1522,6 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
15591522
assert_eq!(discriminant_def_id, item_def_id);
15601523

15611524
(self_ty.discriminant_ty(tcx).into(), PredicateObligations::new())
1562-
} else if tcx.is_lang_item(trait_def_id, LangItem::AsyncDestruct) {
1563-
let destructor_def_id = tcx.associated_item_def_ids(trait_def_id)[0];
1564-
assert_eq!(destructor_def_id, item_def_id);
1565-
1566-
(self_ty.async_destructor_ty(tcx).into(), PredicateObligations::new())
15671525
} else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) {
15681526
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
15691527
assert_eq!(metadata_def_id, item_def_id);

‎compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
7979
} else if tcx.is_lang_item(def_id, LangItem::DiscriminantKind) {
8080
// `DiscriminantKind` is automatically implemented for every type.
8181
candidates.vec.push(BuiltinCandidate { has_nested: false });
82-
} else if tcx.is_lang_item(def_id, LangItem::AsyncDestruct) {
83-
// `AsyncDestruct` is automatically implemented for every type.
84-
candidates.vec.push(BuiltinCandidate { has_nested: false });
8582
} else if tcx.is_lang_item(def_id, LangItem::PointeeTrait) {
8683
// `Pointee` is automatically implemented for every type.
8784
candidates.vec.push(BuiltinCandidate { has_nested: false });

‎compiler/rustc_ty_utils/src/common_traits.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ fn is_unpin_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, T
2222
is_item_raw(tcx, query, LangItem::Unpin)
2323
}
2424

25+
fn is_async_drop_raw<'tcx>(
26+
tcx: TyCtxt<'tcx>,
27+
query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
28+
) -> bool {
29+
is_item_raw(tcx, query, LangItem::AsyncDrop)
30+
}
31+
2532
fn is_item_raw<'tcx>(
2633
tcx: TyCtxt<'tcx>,
2734
query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
@@ -33,5 +40,12 @@ fn is_item_raw<'tcx>(
3340
}
3441

3542
pub(crate) fn provide(providers: &mut Providers) {
36-
*providers = Providers { is_copy_raw, is_sized_raw, is_freeze_raw, is_unpin_raw, ..*providers };
43+
*providers = Providers {
44+
is_copy_raw,
45+
is_sized_raw,
46+
is_freeze_raw,
47+
is_unpin_raw,
48+
is_async_drop_raw,
49+
..*providers
50+
};
3751
}

‎compiler/rustc_ty_utils/src/instance.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use rustc_infer::infer::TyCtxtInferExt;
55
use rustc_middle::bug;
66
use rustc_middle::query::Providers;
77
use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError};
8-
use rustc_middle::ty::util::AsyncDropGlueMorphology;
98
use rustc_middle::ty::{
109
self, GenericArgsRef, Instance, PseudoCanonicalInput, TyCtxt, TypeVisitableExt,
1110
};
@@ -63,7 +62,7 @@ fn resolve_instance_raw<'tcx>(
6362
} else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) {
6463
let ty = args.type_at(0);
6564

66-
if ty.async_drop_glue_morphology(tcx) != AsyncDropGlueMorphology::Noop {
65+
if ty.needs_async_drop(tcx, typing_env) {
6766
match *ty.kind() {
6867
ty::Closure(..)
6968
| ty::CoroutineClosure(..)

‎compiler/rustc_ty_utils/src/needs_drop.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ fn needs_async_drop_raw<'tcx>(
4242
let adt_has_async_dtor =
4343
|adt_def: ty::AdtDef<'tcx>| adt_def.async_destructor(tcx).map(|_| DtorType::Significant);
4444
let res = drop_tys_helper(tcx, query.value, query.typing_env, adt_has_async_dtor, false, false)
45-
.filter(filter_array_elements(tcx, query.typing_env))
45+
.filter(filter_array_elements_async(tcx, query.typing_env))
4646
.next()
4747
.is_some();
4848

49-
debug!("needs_drop_raw({:?}) = {:?}", query, res);
49+
debug!("needs_async_drop_raw({:?}) = {:?}", query, res);
5050
res
5151
}
5252

@@ -66,6 +66,18 @@ fn filter_array_elements<'tcx>(
6666
Err(AlwaysRequiresDrop) => true,
6767
}
6868
}
69+
fn filter_array_elements_async<'tcx>(
70+
tcx: TyCtxt<'tcx>,
71+
typing_env: ty::TypingEnv<'tcx>,
72+
) -> impl Fn(&Result<Ty<'tcx>, AlwaysRequiresDrop>) -> bool {
73+
move |ty| match ty {
74+
Ok(ty) => match *ty.kind() {
75+
ty::Array(elem, _) => tcx.needs_async_drop_raw(typing_env.as_query_input(elem)),
76+
_ => true,
77+
},
78+
Err(AlwaysRequiresDrop) => true,
79+
}
80+
}
6981

7082
fn has_significant_drop_raw<'tcx>(
7183
tcx: TyCtxt<'tcx>,
@@ -414,6 +426,27 @@ fn adt_drop_tys<'tcx>(
414426
.collect::<Result<Vec<_>, _>>()
415427
.map(|components| tcx.mk_type_list(&components))
416428
}
429+
430+
fn adt_async_drop_tys<'tcx>(
431+
tcx: TyCtxt<'tcx>,
432+
def_id: DefId,
433+
) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
434+
// This is for the "adt_async_drop_tys" query, that considers all `AsyncDrop` impls.
435+
let adt_has_dtor =
436+
|adt_def: ty::AdtDef<'tcx>| adt_def.async_destructor(tcx).map(|_| DtorType::Significant);
437+
// `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_args)`
438+
drop_tys_helper(
439+
tcx,
440+
tcx.type_of(def_id).instantiate_identity(),
441+
ty::TypingEnv::non_body_analysis(tcx, def_id),
442+
adt_has_dtor,
443+
false,
444+
false,
445+
)
446+
.collect::<Result<Vec<_>, _>>()
447+
.map(|components| tcx.mk_type_list(&components))
448+
}
449+
417450
// If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed
418451
// a `tcx.make_ty(def, identity_args)` and as such it is legal to instantiate the generic parameters
419452
// of the ADT into the outputted `ty`s.
@@ -458,6 +491,7 @@ pub(crate) fn provide(providers: &mut Providers) {
458491
needs_async_drop_raw,
459492
has_significant_drop_raw,
460493
adt_drop_tys,
494+
adt_async_drop_tys,
461495
adt_significant_drop_tys,
462496
list_significant_drop_tys,
463497
..*providers

‎compiler/rustc_type_ir/src/inherent.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,6 @@ pub trait Ty<I: Interner<Ty = Self>>:
163163

164164
fn discriminant_ty(self, interner: I) -> I::Ty;
165165

166-
fn async_destructor_ty(self, interner: I) -> I::Ty;
167-
168166
/// Returns `true` when the outermost type cannot be further normalized,
169167
/// resolved, or instantiated. This includes all primitive types, but also
170168
/// things like ADTs and trait objects, since even if their arguments or

‎compiler/rustc_type_ir/src/lang_items.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
/// representation of `LangItem`s used in the underlying compiler implementation.
33
pub enum TraitSolverLangItem {
44
// tidy-alphabetical-start
5-
AsyncDestruct,
65
AsyncFn,
76
AsyncFnKindHelper,
87
AsyncFnKindUpvars,

‎library/core/src/future/async_drop.rs

Lines changed: 0 additions & 284 deletions
This file was deleted.

‎library/core/src/future/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,13 @@
1212
use crate::ptr::NonNull;
1313
use crate::task::Context;
1414

15-
mod async_drop;
1615
mod future;
1716
mod into_future;
1817
mod join;
1918
mod pending;
2019
mod poll_fn;
2120
mod ready;
2221

23-
#[unstable(feature = "async_drop", issue = "126482")]
24-
pub use async_drop::{AsyncDrop, AsyncDropInPlace, async_drop, async_drop_in_place};
2522
#[stable(feature = "into_future", since = "1.64.0")]
2623
pub use into_future::IntoFuture;
2724
#[stable(feature = "future_readiness_fns", since = "1.48.0")]

‎library/core/src/ops/drop.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,3 @@ pub trait Drop {
240240
#[stable(feature = "rust1", since = "1.0.0")]
241241
fn drop(&mut self);
242242
}
243-
244-
/// Fallback function to call surface level `Drop::drop` function
245-
#[allow(drop_bounds)]
246-
#[lang = "fallback_surface_drop"]
247-
pub(crate) fn fallback_surface_drop<T: Drop + ?Sized>(x: &mut T) {
248-
<T as Drop>::drop(x)
249-
}

‎library/core/src/ops/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ pub use self::deref::Receiver;
176176
pub use self::deref::{Deref, DerefMut};
177177
#[stable(feature = "rust1", since = "1.0.0")]
178178
pub use self::drop::Drop;
179-
pub(crate) use self::drop::fallback_surface_drop;
180179
#[stable(feature = "rust1", since = "1.0.0")]
181180
pub use self::function::{Fn, FnMut, FnOnce};
182181
#[stable(feature = "rust1", since = "1.0.0")]

‎src/tools/miri/tests/pass/async-drop.rs

Lines changed: 0 additions & 199 deletions
This file was deleted.

‎tests/crashes/128695.rs

Lines changed: 0 additions & 11 deletions
This file was deleted.

‎tests/ui/async-await/async-drop.rs

Lines changed: 0 additions & 222 deletions
This file was deleted.

‎tests/ui/async-await/async-drop.run.stdout

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.