Skip to content

Commit 24a24ec

Browse files
committed
Add simple async drop glue generation
Explainer: https://zetanumbers.github.io/book/async-drop-design.html #121801
1 parent 1dea922 commit 24a24ec

File tree

40 files changed

+1921
-20
lines changed

40 files changed

+1921
-20
lines changed

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,24 @@ fn exported_symbols_provider_local(
363363
},
364364
));
365365
}
366+
MonoItem::Fn(Instance {
367+
def: InstanceDef::AsyncDropGlueCtorShim(def_id, 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+
}
366384
_ => {
367385
// Any other symbols don't qualify for sharing
368386
}
@@ -385,6 +403,7 @@ fn upstream_monomorphizations_provider(
385403
let mut instances: DefIdMap<UnordMap<_, _>> = Default::default();
386404

387405
let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn();
406+
let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn();
388407

389408
for &cnum in cnums.iter() {
390409
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
@@ -399,6 +418,18 @@ fn upstream_monomorphizations_provider(
399418
continue;
400419
}
401420
}
421+
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
422+
if let Some(async_drop_in_place_fn_def_id) = async_drop_in_place_fn_def_id {
423+
(
424+
async_drop_in_place_fn_def_id,
425+
tcx.mk_args(&[tcx.lifetimes.re_erased.into(), ty.into()]),
426+
)
427+
} else {
428+
// `drop_in_place` in place does not exist, don't try
429+
// to use it.
430+
continue;
431+
}
432+
}
402433
ExportedSymbol::NonGeneric(..)
403434
| ExportedSymbol::ThreadLocalShim(..)
404435
| ExportedSymbol::NoDefId(..) => {
@@ -534,6 +565,13 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
534565
Instance::resolve_drop_in_place(tcx, ty),
535566
instantiating_crate,
536567
),
568+
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
569+
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
570+
tcx,
571+
Instance::resolve_async_drop_in_place(tcx, ty),
572+
instantiating_crate,
573+
)
574+
}
537575
ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(),
538576
}
539577
}
@@ -582,6 +620,9 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
582620
// DropGlue always use the Rust calling convention and thus follow the target's default
583621
// symbol decoration scheme.
584622
ExportedSymbol::DropGlue(..) => None,
623+
// AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
624+
// target's default symbol decoration scheme.
625+
ExportedSymbol::AsyncDropGlueCtorShim(..) => None,
585626
// NoDefId always follow the target's default symbol decoration scheme.
586627
ExportedSymbol::NoDefId(..) => None,
587628
// ThreadLocalShim always follow the target's default symbol decoration scheme.

compiler/rustc_const_eval/src/interpret/terminator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
558558
| ty::InstanceDef::CloneShim(..)
559559
| ty::InstanceDef::FnPtrAddrShim(..)
560560
| ty::InstanceDef::ThreadLocalShim(..)
561+
| ty::InstanceDef::AsyncDropGlueCtorShim(..)
561562
| ty::InstanceDef::Item(_) => {
562563
// We need MIR for this fn
563564
let Some((body, instance)) = M::find_mir_or_eval_fn(

compiler/rustc_hir/src/lang_items.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ language_item_table! {
162162
Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None;
163163
Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None;
164164

165+
AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::Exact(0);
166+
AsyncDestruct, sym::async_destruct, async_destruct_trait, Target::Trait, GenericRequirement::Exact(0);
167+
AsyncDropInPlace, sym::async_drop_in_place, async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
168+
SurfaceAsyncDropInPlace, sym::surface_async_drop_in_place, surface_async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
169+
AsyncDropSurfaceDropInPlace, sym::async_drop_surface_drop_in_place, async_drop_surface_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
170+
AsyncDropSlice, sym::async_drop_slice, async_drop_slice_fn, Target::Fn, GenericRequirement::Exact(1);
171+
AsyncDropChain, sym::async_drop_chain, async_drop_chain_fn, Target::Fn, GenericRequirement::Exact(2);
172+
AsyncDropNoop, sym::async_drop_noop, async_drop_noop_fn, Target::Fn, GenericRequirement::Exact(0);
173+
AsyncDropFuse, sym::async_drop_fuse, async_drop_fuse_fn, Target::Fn, GenericRequirement::Exact(1);
174+
AsyncDropDefer, sym::async_drop_defer, async_drop_defer_fn, Target::Fn, GenericRequirement::Exact(1);
175+
AsyncDropEither, sym::async_drop_either, async_drop_either_fn, Target::Fn, GenericRequirement::Exact(3);
176+
165177
CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1);
166178
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1);
167179

@@ -281,6 +293,7 @@ language_item_table! {
281293

282294
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
283295
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
296+
FallbackSurfaceDrop, sym::fallback_surface_drop, fallback_surface_drop_fn, Target::Fn, GenericRequirement::None;
284297
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
285298

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

compiler/rustc_hir_typeck/src/callee.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ pub fn check_legal_trait_for_method_call(
3838
receiver: Option<Span>,
3939
expr_span: Span,
4040
trait_id: DefId,
41+
body_id: DefId,
4142
) -> Result<(), ErrorGuaranteed> {
42-
if tcx.lang_items().drop_trait() == Some(trait_id) {
43+
if tcx.lang_items().drop_trait() == Some(trait_id)
44+
&& tcx.lang_items().fallback_surface_drop_fn() != Some(body_id)
45+
{
4346
let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {
4447
errors::ExplicitDestructorCallSugg::Snippet {
4548
lo: expr_span.shrink_to_lo(),

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11181118
None,
11191119
span,
11201120
container_id,
1121+
self.body_id.to_def_id(),
11211122
) {
11221123
self.set_tainted_by_errors(e);
11231124
}

compiler/rustc_hir_typeck/src/method/confirm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
628628
Some(self.self_expr.span),
629629
self.call_expr.span,
630630
trait_def_id,
631+
self.body_id.to_def_id(),
631632
) {
632633
self.set_tainted_by_errors(e);
633634
}

compiler/rustc_middle/src/middle/exported_symbols.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub enum ExportedSymbol<'tcx> {
4343
NonGeneric(DefId),
4444
Generic(DefId, GenericArgsRef<'tcx>),
4545
DropGlue(Ty<'tcx>),
46+
AsyncDropGlueCtorShim(Ty<'tcx>),
4647
ThreadLocalShim(DefId),
4748
NoDefId(ty::SymbolName<'tcx>),
4849
}
@@ -59,6 +60,9 @@ impl<'tcx> ExportedSymbol<'tcx> {
5960
ExportedSymbol::DropGlue(ty) => {
6061
tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
6162
}
63+
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
64+
tcx.symbol_name(ty::Instance::resolve_async_drop_in_place(tcx, ty))
65+
}
6266
ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance {
6367
def: ty::InstanceDef::ThreadLocalShim(def_id),
6468
args: ty::GenericArgs::empty(),

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,8 @@ impl<'tcx> CodegenUnit<'tcx> {
406406
| InstanceDef::DropGlue(..)
407407
| InstanceDef::CloneShim(..)
408408
| InstanceDef::ThreadLocalShim(..)
409-
| InstanceDef::FnPtrAddrShim(..) => None,
409+
| InstanceDef::FnPtrAddrShim(..)
410+
| InstanceDef::AsyncDropGlueCtorShim(..) => None,
410411
}
411412
}
412413
MonoItem::Static(def_id) => def_id.as_local().map(Idx::index),

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,17 @@ fn dump_path<'tcx>(
187187
}));
188188
s
189189
}
190+
ty::InstanceDef::AsyncDropGlueCtorShim(_, ty) => {
191+
// Unfortunately, pretty-printed typed are not very filename-friendly.
192+
// We dome some filtering.
193+
let mut s = ".".to_owned();
194+
s.extend(ty.to_string().chars().filter_map(|c| match c {
195+
' ' => None,
196+
':' | '<' | '>' => Some('_'),
197+
c => Some(c),
198+
}));
199+
s
200+
}
190201
_ => String::new(),
191202
};
192203

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,8 @@ macro_rules! make_mir_visitor {
355355
ty::InstanceDef::FnPtrShim(_def_id, ty) |
356356
ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
357357
ty::InstanceDef::CloneShim(_def_id, ty) |
358-
ty::InstanceDef::FnPtrAddrShim(_def_id, ty) => {
358+
ty::InstanceDef::FnPtrAddrShim(_def_id, ty) |
359+
ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, ty) => {
359360
// FIXME(eddyb) use a better `TyContext` here.
360361
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
361362
}

0 commit comments

Comments
 (0)