Skip to content
41 changes: 41 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,24 @@ fn exported_symbols_provider_local(
},
));
}
MonoItem::Fn(Instance {
def: InstanceDef::AsyncDropGlueCtorShim(def_id, Some(ty)),
args,
}) => {
// A little sanity-check
debug_assert_eq!(
args.non_erasable_generics(tcx, def_id).skip(1).next(),
Some(GenericArgKind::Type(ty))
);
symbols.push((
ExportedSymbol::AsyncDropGlueCtorShim(ty),
SymbolExportInfo {
level: SymbolExportLevel::Rust,
kind: SymbolExportKind::Text,
used: false,
},
));
}
_ => {
// Any other symbols don't qualify for sharing
}
Expand All @@ -385,6 +403,7 @@ fn upstream_monomorphizations_provider(
let mut instances: DefIdMap<UnordMap<_, _>> = Default::default();

let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn();
let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn();

for &cnum in cnums.iter() {
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
Expand All @@ -399,6 +418,18 @@ fn upstream_monomorphizations_provider(
continue;
}
}
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
if let Some(async_drop_in_place_fn_def_id) = async_drop_in_place_fn_def_id {
(
async_drop_in_place_fn_def_id,
tcx.mk_args(&[tcx.lifetimes.re_erased.into(), ty.into()]),
)
} else {
// `drop_in_place` in place does not exist, don't try
// to use it.
continue;
}
}
ExportedSymbol::NonGeneric(..)
| ExportedSymbol::ThreadLocalShim(..)
| ExportedSymbol::NoDefId(..) => {
Expand Down Expand Up @@ -534,6 +565,13 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
Instance::resolve_drop_in_place(tcx, ty),
instantiating_crate,
),
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
tcx,
Instance::resolve_async_drop_in_place(tcx, ty),
instantiating_crate,
)
}
ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(),
}
}
Expand Down Expand Up @@ -582,6 +620,9 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
// DropGlue always use the Rust calling convention and thus follow the target's default
// symbol decoration scheme.
ExportedSymbol::DropGlue(..) => None,
// AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
// target's default symbol decoration scheme.
ExportedSymbol::AsyncDropGlueCtorShim(..) => None,
// NoDefId always follow the target's default symbol decoration scheme.
ExportedSymbol::NoDefId(..) => None,
// ThreadLocalShim always follow the target's default symbol decoration scheme.
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

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

if let Some(ty::InstanceDef::DropGlue(_, None)) = def {
if let Some(
ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None),
) = def
{
// Empty drop glue; a no-op.
let target = target.unwrap();
return helper.funclet_br(self, bx, target, mergeable_succ);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
| ty::InstanceDef::CloneShim(..)
| ty::InstanceDef::FnPtrAddrShim(..)
| ty::InstanceDef::ThreadLocalShim(..)
| ty::InstanceDef::AsyncDropGlueCtorShim(..)
| ty::InstanceDef::Item(_) => {
// We need MIR for this fn
let Some((body, instance)) = M::find_mir_or_eval_fn(
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,18 @@ language_item_table! {
Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None;
Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None;

AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::Exact(0);
AsyncDestruct, sym::async_destruct, async_destruct_trait, Target::Trait, GenericRequirement::Exact(0);
AsyncDropInPlace, sym::async_drop_in_place, async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
SurfaceAsyncDropInPlace, sym::surface_async_drop_in_place, surface_async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
AsyncDropSurfaceDropInPlace, sym::async_drop_surface_drop_in_place, async_drop_surface_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);
AsyncDropSlice, sym::async_drop_slice, async_drop_slice_fn, Target::Fn, GenericRequirement::Exact(1);
AsyncDropChain, sym::async_drop_chain, async_drop_chain_fn, Target::Fn, GenericRequirement::Exact(2);
AsyncDropNoop, sym::async_drop_noop, async_drop_noop_fn, Target::Fn, GenericRequirement::Exact(0);
AsyncDropFuse, sym::async_drop_fuse, async_drop_fuse_fn, Target::Fn, GenericRequirement::Exact(1);
AsyncDropDefer, sym::async_drop_defer, async_drop_defer_fn, Target::Fn, GenericRequirement::Exact(1);
AsyncDropEither, sym::async_drop_either, async_drop_either_fn, Target::Fn, GenericRequirement::Exact(3);

CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1);
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1);

Expand Down Expand Up @@ -281,6 +293,7 @@ language_item_table! {

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

Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ pub fn check_legal_trait_for_method_call(
receiver: Option<Span>,
expr_span: Span,
trait_id: DefId,
body_id: DefId,
) -> Result<(), ErrorGuaranteed> {
if tcx.lang_items().drop_trait() == Some(trait_id) {
if tcx.lang_items().drop_trait() == Some(trait_id)
&& tcx.lang_items().fallback_surface_drop_fn() != Some(body_id)
{
let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {
errors::ExplicitDestructorCallSugg::Snippet {
lo: expr_span.shrink_to_lo(),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None,
span,
container_id,
self.body_id.to_def_id(),
) {
self.set_tainted_by_errors(e);
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
Some(self.self_expr.span),
self.call_expr.span,
trait_def_id,
self.body_id.to_def_id(),
) {
self.set_tainted_by_errors(e);
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/middle/exported_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub enum ExportedSymbol<'tcx> {
NonGeneric(DefId),
Generic(DefId, GenericArgsRef<'tcx>),
DropGlue(Ty<'tcx>),
AsyncDropGlueCtorShim(Ty<'tcx>),
ThreadLocalShim(DefId),
NoDefId(ty::SymbolName<'tcx>),
}
Expand All @@ -59,6 +60,9 @@ impl<'tcx> ExportedSymbol<'tcx> {
ExportedSymbol::DropGlue(ty) => {
tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
}
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
tcx.symbol_name(ty::Instance::resolve_async_drop_in_place(tcx, ty))
}
ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance {
def: ty::InstanceDef::ThreadLocalShim(def_id),
args: ty::GenericArgs::empty(),
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_middle/src/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ impl<'tcx> MonoItem<'tcx> {
match instance.def {
// "Normal" functions size estimate: the number of
// statements, plus one for the terminator.
InstanceDef::Item(..) | InstanceDef::DropGlue(..) => {
InstanceDef::Item(..)
| InstanceDef::DropGlue(..)
| InstanceDef::AsyncDropGlueCtorShim(..) => {
let mir = tcx.instance_mir(instance.def);
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
}
Expand Down Expand Up @@ -406,7 +408,8 @@ impl<'tcx> CodegenUnit<'tcx> {
| InstanceDef::DropGlue(..)
| InstanceDef::CloneShim(..)
| InstanceDef::ThreadLocalShim(..)
| InstanceDef::FnPtrAddrShim(..) => None,
| InstanceDef::FnPtrAddrShim(..)
| InstanceDef::AsyncDropGlueCtorShim(..) => None,
}
}
MonoItem::Static(def_id) => def_id.as_local().map(Idx::index),
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,17 @@ fn dump_path<'tcx>(
}));
s
}
ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) => {
// Unfortunately, pretty-printed typed are not very filename-friendly.
// We dome some filtering.
let mut s = ".".to_owned();
s.extend(ty.to_string().chars().filter_map(|c| match c {
' ' => None,
':' | '<' | '>' => Some('_'),
c => Some(c),
}));
s
}
_ => String::new(),
};

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_middle/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,14 @@ macro_rules! make_mir_visitor {
receiver_by_ref: _,
} |
ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id } |
ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, None) |
ty::InstanceDef::DropGlue(_def_id, None) => {}

ty::InstanceDef::FnPtrShim(_def_id, ty) |
ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
ty::InstanceDef::CloneShim(_def_id, ty) |
ty::InstanceDef::FnPtrAddrShim(_def_id, ty) => {
ty::InstanceDef::FnPtrAddrShim(_def_id, ty) |
ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, Some(ty)) => {
// FIXME(eddyb) use a better `TyContext` here.
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,14 @@ rustc_queries! {
query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Unpin`", env.value }
}
/// Query backing `Ty::has_surface_async_drop`.
query has_surface_async_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` has `AsyncDrop` implementation", env.value }
}
/// Query backing `Ty::has_surface_drop`.
query has_surface_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` has `Drop` implementation", env.value }
}
/// Query backing `Ty::needs_drop`.
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` needs drop", env.value }
Expand Down
32 changes: 26 additions & 6 deletions compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ pub enum InstanceDef<'tcx> {
///
/// The `DefId` is for `FnPtr::addr`, the `Ty` is the type `T`.
FnPtrAddrShim(DefId, Ty<'tcx>),

/// `core::future::async_drop::async_drop_in_place::<'_, T>`.
///
/// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty`
/// is the type `T`.
AsyncDropGlueCtorShim(DefId, Option<Ty<'tcx>>),
}

impl<'tcx> Instance<'tcx> {
Expand Down Expand Up @@ -210,7 +216,9 @@ impl<'tcx> Instance<'tcx> {
InstanceDef::Item(def) => tcx
.upstream_monomorphizations_for(def)
.and_then(|monos| monos.get(&self.args).cloned()),
InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.args),
InstanceDef::DropGlue(_, Some(_)) | InstanceDef::AsyncDropGlueCtorShim(_, _) => {
tcx.upstream_drop_glue_for(self.args)
}
_ => None,
}
}
Expand All @@ -235,17 +243,18 @@ impl<'tcx> InstanceDef<'tcx> {
| ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id }
| InstanceDef::DropGlue(def_id, _)
| InstanceDef::CloneShim(def_id, _)
| InstanceDef::FnPtrAddrShim(def_id, _) => def_id,
| InstanceDef::FnPtrAddrShim(def_id, _)
| InstanceDef::AsyncDropGlueCtorShim(def_id, _) => def_id,
}
}

/// Returns the `DefId` of instances which might not require codegen locally.
pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
match self {
ty::InstanceDef::Item(def) => Some(def),
ty::InstanceDef::DropGlue(def_id, Some(_)) | InstanceDef::ThreadLocalShim(def_id) => {
Some(def_id)
}
ty::InstanceDef::DropGlue(def_id, Some(_))
| InstanceDef::AsyncDropGlueCtorShim(def_id, _)
| InstanceDef::ThreadLocalShim(def_id) => Some(def_id),
InstanceDef::VTableShim(..)
| InstanceDef::ReifyShim(..)
| InstanceDef::FnPtrShim(..)
Expand Down Expand Up @@ -279,6 +288,7 @@ impl<'tcx> InstanceDef<'tcx> {
let def_id = match *self {
ty::InstanceDef::Item(def) => def,
ty::InstanceDef::DropGlue(_, Some(_)) => return false,
ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => return false,
ty::InstanceDef::ThreadLocalShim(_) => return false,
_ => return true,
};
Expand Down Expand Up @@ -347,11 +357,13 @@ impl<'tcx> InstanceDef<'tcx> {
| InstanceDef::ThreadLocalShim(..)
| InstanceDef::FnPtrAddrShim(..)
| InstanceDef::FnPtrShim(..)
| InstanceDef::DropGlue(_, Some(_)) => false,
| InstanceDef::DropGlue(_, Some(_))
| InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => false,
InstanceDef::ClosureOnceShim { .. }
| InstanceDef::ConstructCoroutineInClosureShim { .. }
| InstanceDef::CoroutineKindShim { .. }
| InstanceDef::DropGlue(..)
| InstanceDef::AsyncDropGlueCtorShim(..)
| InstanceDef::Item(_)
| InstanceDef::Intrinsic(..)
| InstanceDef::ReifyShim(..)
Expand Down Expand Up @@ -396,6 +408,8 @@ fn fmt_instance(
InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({ty})"),
InstanceDef::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"),
InstanceDef::AsyncDropGlueCtorShim(_, None) => write!(f, " - shim(None)"),
InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
}
}

Expand Down Expand Up @@ -638,6 +652,12 @@ impl<'tcx> Instance<'tcx> {
Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args)
}

pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, None);
let args = tcx.mk_args(&[ty.into()]);
Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args)
}

#[instrument(level = "debug", skip(tcx), ret)]
pub fn fn_once_adapter_instance(
tcx: TyCtxt<'tcx>,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1797,7 +1797,8 @@ impl<'tcx> TyCtxt<'tcx> {
| ty::InstanceDef::DropGlue(..)
| ty::InstanceDef::CloneShim(..)
| ty::InstanceDef::ThreadLocalShim(..)
| ty::InstanceDef::FnPtrAddrShim(..) => self.mir_shims(instance),
| ty::InstanceDef::FnPtrAddrShim(..)
| ty::InstanceDef::AsyncDropGlueCtorShim(..) => self.mir_shims(instance),
}
}

Expand Down
Loading