Skip to content

Commit c9aacfe

Browse files
committed
Async drop glue integration in progress
1 parent cdf91ab commit c9aacfe

File tree

38 files changed

+1079
-89
lines changed

38 files changed

+1079
-89
lines changed

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+76
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,42 @@ fn exported_symbols_provider_local(
363363
},
364364
));
365365
}
366+
MonoItem::Fn(Instance {
367+
def: InstanceDef::AsyncDropGlueCtorShim(def_id, Some(ty)),
368+
args,
369+
}) => {
370+
// A little sanity-check
371+
debug_assert_eq!(
372+
args.non_erasable_generics(tcx, def_id).skip(1).next(),
373+
Some(GenericArgKind::Type(ty))
374+
);
375+
symbols.push((
376+
ExportedSymbol::AsyncDropGlueCtorShim(ty),
377+
SymbolExportInfo {
378+
level: SymbolExportLevel::Rust,
379+
kind: SymbolExportKind::Text,
380+
used: false,
381+
},
382+
));
383+
}
384+
MonoItem::Fn(Instance {
385+
def: InstanceDef::AsyncDropGlue(def_id, Some(ty)),
386+
args,
387+
}) => {
388+
// A little sanity-check
389+
debug_assert_eq!(
390+
args.non_erasable_generics(tcx, def_id).skip(1).next(),
391+
Some(GenericArgKind::Type(ty))
392+
);
393+
symbols.push((
394+
ExportedSymbol::AsyncDropGlue(ty),
395+
SymbolExportInfo {
396+
level: SymbolExportLevel::Rust,
397+
kind: SymbolExportKind::Text,
398+
used: false,
399+
},
400+
));
401+
}
366402
_ => {
367403
// Any other symbols don't qualify for sharing
368404
}
@@ -385,6 +421,8 @@ fn upstream_monomorphizations_provider(
385421
let mut instances: DefIdMap<UnordMap<_, _>> = Default::default();
386422

387423
let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn();
424+
let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn();
425+
let async_drop_in_place_poll_fn_def_id = tcx.lang_items().async_drop_in_place_poll_fn();
388426

389427
for &cnum in cnums.iter() {
390428
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
@@ -399,6 +437,26 @@ fn upstream_monomorphizations_provider(
399437
continue;
400438
}
401439
}
440+
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
441+
if let Some(async_drop_in_place_fn_def_id) = async_drop_in_place_fn_def_id {
442+
(
443+
async_drop_in_place_fn_def_id,
444+
tcx.mk_args(&[tcx.lifetimes.re_erased.into(), ty.into()]),
445+
)
446+
} else {
447+
continue;
448+
}
449+
}
450+
ExportedSymbol::AsyncDropGlue(ty) => {
451+
if let Some(poll_fn_def_id) = async_drop_in_place_poll_fn_def_id {
452+
(
453+
poll_fn_def_id,
454+
tcx.mk_args(&[tcx.lifetimes.re_erased.into(), ty.into()]),
455+
)
456+
} else {
457+
continue;
458+
}
459+
}
402460
ExportedSymbol::NonGeneric(..)
403461
| ExportedSymbol::ThreadLocalShim(..)
404462
| ExportedSymbol::NoDefId(..) => {
@@ -534,6 +592,20 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
534592
Instance::resolve_drop_in_place(tcx, ty),
535593
instantiating_crate,
536594
),
595+
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
596+
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
597+
tcx,
598+
Instance::resolve_async_drop_in_place(tcx, ty),
599+
instantiating_crate,
600+
)
601+
}
602+
ExportedSymbol::AsyncDropGlue(ty) => {
603+
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
604+
tcx,
605+
Instance::resolve_async_drop_in_place_poll(tcx, ty),
606+
instantiating_crate,
607+
)
608+
}
537609
ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(),
538610
}
539611
}
@@ -581,6 +653,10 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
581653
// DropGlue always use the Rust calling convention and thus follow the target's default
582654
// symbol decoration scheme.
583655
ExportedSymbol::DropGlue(..) => None,
656+
// AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
657+
// target's default symbol decoration scheme.
658+
ExportedSymbol::AsyncDropGlueCtorShim(..) => None,
659+
ExportedSymbol::AsyncDropGlue(..) => None,
584660
// NoDefId always follow the target's default symbol decoration scheme.
585661
ExportedSymbol::NoDefId(..) => None,
586662
// ThreadLocalShim always follow the target's default symbol decoration scheme.

compiler/rustc_codegen_ssa/src/mir/block.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
773773
};
774774
let def = instance.map(|i| i.def);
775775

776-
if let Some(ty::InstanceDef::DropGlue(_, None)) = def {
776+
if let Some(
777+
ty::InstanceDef::DropGlue(_, None)
778+
| ty::InstanceDef::AsyncDropGlueCtorShim(_, None)
779+
| ty::InstanceDef::AsyncDropGlue(_, None),
780+
) = def {
777781
// Empty drop glue; a no-op.
778782
let target = target.unwrap();
779783
return helper.funclet_br(self, bx, target, mergeable_succ);

compiler/rustc_const_eval/src/interpret/terminator.rs

+2
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
547547
| ty::InstanceDef::CloneShim(..)
548548
| ty::InstanceDef::FnPtrAddrShim(..)
549549
| ty::InstanceDef::ThreadLocalShim(..)
550+
| ty::InstanceDef::AsyncDropGlueCtorShim(..)
551+
| ty::InstanceDef::AsyncDropGlue(..)
550552
| ty::InstanceDef::Item(_) => {
551553
// We need MIR for this fn
552554
let Some((body, instance)) = M::find_mir_or_eval_fn(

compiler/rustc_hir/src/lang_items.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ language_item_table! {
165165
Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None;
166166
AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::None;
167167
AsyncDropInPlace, sym::async_drop_in_place, async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
168+
AsyncDropInPlacePoll, sym::async_drop_in_place_poll, async_drop_in_place_poll_fn, Target::Closure, GenericRequirement::Exact(1);
168169
FutureDropPoll, sym::future_drop_poll, future_drop_poll_fn, Target::Fn, GenericRequirement::Exact(1);
169170

170171
CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1);
@@ -263,7 +264,7 @@ language_item_table! {
263264

264265
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
265266
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
266-
DropInPlaceFuture, sym::drop_in_place_future,drop_in_place_future_fn, Target::Fn, GenericRequirement::Minimum(1);
267+
DropInPlaceFuture, sym::drop_in_place_future,drop_in_place_future_fn, Target::Fn, GenericRequirement::Exact(1);
267268
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
268269

269270
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);

compiler/rustc_hir_analysis/src/check/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ pub fn provide(providers: &mut Providers) {
110110
wfcheck::provide(providers);
111111
*providers = Providers {
112112
adt_destructor,
113+
adt_async_destructor,
113114
region_scope_tree,
114115
collect_return_position_impl_trait_in_trait_tys,
115116
compare_impl_const: compare_impl_item::compare_impl_const_raw,
@@ -122,6 +123,10 @@ fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Destructor>
122123
tcx.calculate_dtor(def_id.to_def_id(), dropck::check_drop_impl)
123124
}
124125

126+
fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::AsyncDestructor> {
127+
tcx.calculate_async_dtor(def_id.to_def_id(), dropck::check_drop_impl)
128+
}
129+
125130
/// Given a `DefId` for an opaque type in return position, find its parent item's return
126131
/// expressions.
127132
fn get_owner_return_paths(

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+4
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,10 @@ provide! { tcx, def_id, other, cdata,
286286
let _ = cdata;
287287
tcx.calculate_dtor(def_id, |_,_| Ok(()))
288288
}
289+
adt_async_destructor => {
290+
let _ = cdata;
291+
tcx.calculate_async_dtor(def_id, |_,_| Ok(()))
292+
}
289293
associated_item_def_ids => {
290294
tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index))
291295
}

compiler/rustc_middle/src/middle/exported_symbols.rs

+8
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub enum ExportedSymbol<'tcx> {
4343
NonGeneric(DefId),
4444
Generic(DefId, GenericArgsRef<'tcx>),
4545
DropGlue(Ty<'tcx>),
46+
AsyncDropGlueCtorShim(Ty<'tcx>),
47+
AsyncDropGlue(Ty<'tcx>),
4648
ThreadLocalShim(DefId),
4749
NoDefId(ty::SymbolName<'tcx>),
4850
}
@@ -59,6 +61,12 @@ impl<'tcx> ExportedSymbol<'tcx> {
5961
ExportedSymbol::DropGlue(ty) => {
6062
tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
6163
}
64+
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
65+
tcx.symbol_name(ty::Instance::resolve_async_drop_in_place(tcx, ty))
66+
}
67+
ExportedSymbol::AsyncDropGlue(ty) => {
68+
tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, ty))
69+
}
6270
ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance {
6371
def: ty::InstanceDef::ThreadLocalShim(def_id),
6472
args: ty::GenericArgs::empty(),

compiler/rustc_middle/src/mir/mod.rs

+17
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ pub struct CoroutineInfo<'tcx> {
258258
/// Coroutine async drop glue.
259259
pub coroutine_drop_async: Option<Body<'tcx>>,
260260

261+
/// When coroutine has sync drop, this is async proxy calling `coroutine_drop` sync impl.
262+
pub coroutine_drop_proxy_async: Option<Body<'tcx>>,
263+
261264
/// The layout of a coroutine. Produced by the state transformation.
262265
pub coroutine_layout: Option<CoroutineLayout<'tcx>>,
263266

@@ -279,6 +282,7 @@ impl<'tcx> CoroutineInfo<'tcx> {
279282
resume_ty: Some(resume_ty),
280283
coroutine_drop: None,
281284
coroutine_drop_async: None,
285+
coroutine_drop_proxy_async: None,
282286
coroutine_layout: None,
283287
}
284288
}
@@ -587,6 +591,19 @@ impl<'tcx> Body<'tcx> {
587591
self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_drop_async.as_ref())
588592
}
589593

594+
#[inline]
595+
pub fn coroutine_requires_async_drop(&self) -> bool {
596+
self.coroutine_drop_async().is_some()
597+
}
598+
599+
#[inline]
600+
pub fn future_drop_poll(&self) -> Option<&Body<'tcx>> {
601+
self.coroutine.as_ref().and_then(
602+
|coroutine|
603+
coroutine.coroutine_drop_async.as_ref().or(
604+
coroutine.coroutine_drop_proxy_async.as_ref()))
605+
}
606+
590607
#[inline]
591608
pub fn coroutine_kind(&self) -> Option<CoroutineKind> {
592609
self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind)

compiler/rustc_middle/src/mir/mono.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ impl<'tcx> MonoItem<'tcx> {
6464
match instance.def {
6565
// "Normal" functions size estimate: the number of
6666
// statements, plus one for the terminator.
67-
InstanceDef::Item(..) | InstanceDef::DropGlue(..) => {
67+
InstanceDef::Item(..)
68+
| InstanceDef::DropGlue(..)
69+
| InstanceDef::AsyncDropGlueCtorShim(..)
70+
| InstanceDef::AsyncDropGlue(..) => {
6871
let mir = tcx.instance_mir(instance.def);
6972
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
7073
}
@@ -404,9 +407,11 @@ impl<'tcx> CodegenUnit<'tcx> {
404407
| InstanceDef::ClosureOnceShim { .. }
405408
| InstanceDef::FutureDropPollShim(..)
406409
| InstanceDef::DropGlue(..)
410+
| InstanceDef::AsyncDropGlue(..)
407411
| InstanceDef::CloneShim(..)
408412
| InstanceDef::ThreadLocalShim(..)
409413
| InstanceDef::FnPtrAddrShim(..) => None,
414+
| InstanceDef::AsyncDropGlueCtorShim(..) => None,
410415
}
411416
}
412417
MonoItem::Static(def_id) => def_id.as_local().map(Idx::index),

compiler/rustc_middle/src/mir/pretty.rs

+11
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ fn dump_path<'tcx>(
185185
}));
186186
s
187187
}
188+
ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) => {
189+
// Unfortunately, pretty-printed typed are not very filename-friendly.
190+
// We dome some filtering.
191+
let mut s = ".".to_owned();
192+
s.extend(ty.to_string().chars().filter_map(|c| match c {
193+
' ' => None,
194+
':' | '<' | '>' => Some('_'),
195+
c => Some(c),
196+
}));
197+
s
198+
}
188199
_ => String::new(),
189200
};
190201

compiler/rustc_middle/src/mir/visit.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,17 @@ macro_rules! make_mir_visitor {
345345
ty::InstanceDef::Virtual(_def_id, _) |
346346
ty::InstanceDef::ThreadLocalShim(_def_id) |
347347
ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
348+
ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, None) |
349+
ty::InstanceDef::AsyncDropGlue(_def_id, None) |
348350
ty::InstanceDef::DropGlue(_def_id, None) => {}
349351

350352
ty::InstanceDef::FnPtrShim(_def_id, ty) |
351353
ty::InstanceDef::FutureDropPollShim(_def_id, ty) |
352354
ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
353355
ty::InstanceDef::CloneShim(_def_id, ty) |
354-
ty::InstanceDef::FnPtrAddrShim(_def_id, ty) => {
356+
ty::InstanceDef::FnPtrAddrShim(_def_id, ty) |
357+
ty::InstanceDef::AsyncDropGlue(_def_id, Some(ty)) |
358+
ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, Some(ty)) => {
355359
// FIXME(eddyb) use a better `TyContext` here.
356360
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
357361
}

compiler/rustc_middle/src/query/erase.rs

+2
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ trivial! {
232232
Option<rustc_hir::CoroutineKind>,
233233
Option<rustc_hir::HirId>,
234234
Option<rustc_middle::middle::stability::DeprecationEntry>,
235+
Option<rustc_middle::ty::AsyncDestructor>,
235236
Option<rustc_middle::ty::Destructor>,
236237
Option<rustc_middle::ty::ImplTraitInTraitData>,
237238
Option<rustc_span::def_id::CrateNum>,
@@ -286,6 +287,7 @@ trivial! {
286287
rustc_middle::ty::AssocItem,
287288
rustc_middle::ty::AssocItemContainer,
288289
rustc_middle::ty::Asyncness,
290+
rustc_middle::ty::AsyncDestructor,
289291
rustc_middle::ty::BoundVariableKind,
290292
rustc_middle::ty::DeducedParamAttrs,
291293
rustc_middle::ty::Destructor,

compiler/rustc_middle/src/query/mod.rs

+17
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,11 @@ rustc_queries! {
711711
cache_on_disk_if { key.is_local() }
712712
separate_provide_extern
713713
}
714+
query adt_async_destructor(key: DefId) -> Option<ty::AsyncDestructor> {
715+
desc { |tcx| "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) }
716+
cache_on_disk_if { key.is_local() }
717+
separate_provide_extern
718+
}
714719

715720
query adt_sized_constraint(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<Ty<'tcx>>> {
716721
desc { |tcx| "computing `Sized` constraints for `{}`", tcx.def_path_str(key) }
@@ -1355,6 +1360,10 @@ rustc_queries! {
13551360
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
13561361
desc { "computing whether `{}` needs drop", env.value }
13571362
}
1363+
/// Query backing `Ty::needs_async_drop`.
1364+
query needs_async_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
1365+
desc { "computing whether `{}` needs async drop", env.value }
1366+
}
13581367
/// Query backing `Ty::has_significant_drop_raw`.
13591368
query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
13601369
desc { "computing whether `{}` has a significant drop", env.value }
@@ -1379,6 +1388,14 @@ rustc_queries! {
13791388
cache_on_disk_if { true }
13801389
}
13811390

1391+
/// A list of types where the ADT requires async drop if and only if any of
1392+
/// those types require async drop. If the ADT is known to always need async drop
1393+
/// then `Err(AlwaysRequiresDrop)` is returned.
1394+
query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
1395+
desc { |tcx| "computing when `{}` needs async drop", tcx.def_path_str(def_id) }
1396+
cache_on_disk_if { true }
1397+
}
1398+
13821399
/// A list of types where the ADT requires drop if and only if any of those types
13831400
/// has significant drop. A type marked with the attribute `rustc_insignificant_dtor`
13841401
/// is considered to not be significant. A drop is significant if it is implemented

compiler/rustc_middle/src/ty/adt.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ use std::hash::{Hash, Hasher};
2222
use std::ops::Range;
2323
use std::str;
2424

25-
use super::{Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, VariantDiscr};
25+
use super::{
26+
AsyncDestructor, Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, VariantDiscr
27+
};
2628

2729
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
2830
pub struct AdtFlags(u16);
@@ -564,6 +566,10 @@ impl<'tcx> AdtDef<'tcx> {
564566
tcx.adt_destructor(self.did())
565567
}
566568

569+
pub fn async_destructor(self, tcx: TyCtxt<'tcx>) -> Option<AsyncDestructor> {
570+
tcx.adt_async_destructor(self.did())
571+
}
572+
567573
/// Returns a list of types such that `Self: Sized` if and only if that
568574
/// type is `Sized`, or `ty::Error` if this type has a recursive layout.
569575
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx ty::List<Ty<'tcx>>> {

0 commit comments

Comments
 (0)