Make async drop code more consistent with regular drop code
Fixes #126573
This commit is contained in:
parent
f873ae029e
commit
af10880f6b
@ -371,7 +371,7 @@ fn exported_symbols_provider_local(
|
|||||||
}) => {
|
}) => {
|
||||||
// A little sanity-check
|
// A little sanity-check
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
args.non_erasable_generics(tcx, def_id).skip(1).next(),
|
args.non_erasable_generics(tcx, def_id).next(),
|
||||||
Some(GenericArgKind::Type(ty))
|
Some(GenericArgKind::Type(ty))
|
||||||
);
|
);
|
||||||
symbols.push((
|
symbols.push((
|
||||||
@ -422,10 +422,7 @@ fn upstream_monomorphizations_provider(
|
|||||||
}
|
}
|
||||||
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
|
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
|
||||||
if let Some(async_drop_in_place_fn_def_id) = async_drop_in_place_fn_def_id {
|
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(&[ty.into()]))
|
||||||
async_drop_in_place_fn_def_id,
|
|
||||||
tcx.mk_args(&[tcx.lifetimes.re_erased.into(), ty.into()]),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
// `drop_in_place` in place does not exist, don't try
|
// `drop_in_place` in place does not exist, don't try
|
||||||
// to use it.
|
// to use it.
|
||||||
@ -480,6 +477,17 @@ fn upstream_drop_glue_for_provider<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn upstream_async_drop_glue_for_provider<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
args: GenericArgsRef<'tcx>,
|
||||||
|
) -> Option<CrateNum> {
|
||||||
|
if let Some(def_id) = tcx.lang_items().async_drop_in_place_fn() {
|
||||||
|
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&args).cloned())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
||||||
!tcx.reachable_set(()).contains(&def_id)
|
!tcx.reachable_set(()).contains(&def_id)
|
||||||
}
|
}
|
||||||
@ -491,6 +499,7 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
|
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
|
||||||
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
|
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
|
||||||
providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
|
providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
|
||||||
|
providers.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider;
|
||||||
providers.wasm_import_module_map = wasm_import_module_map;
|
providers.wasm_import_module_map = wasm_import_module_map;
|
||||||
providers.extern_queries.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
|
providers.extern_queries.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
|
||||||
providers.extern_queries.upstream_monomorphizations_for =
|
providers.extern_queries.upstream_monomorphizations_for =
|
||||||
|
@ -1554,12 +1554,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The entire set of monomorphizations the local crate can safely link
|
/// The entire set of monomorphizations the local crate can safely
|
||||||
/// to because they are exported from upstream crates. Do not depend on
|
/// link to because they are exported from upstream crates. Do
|
||||||
/// this directly, as its value changes anytime a monomorphization gets
|
/// not depend on this directly, as its value changes anytime
|
||||||
/// added or removed in any upstream crate. Instead use the narrower
|
/// a monomorphization gets added or removed in any upstream
|
||||||
/// `upstream_monomorphizations_for`, `upstream_drop_glue_for`, or, even
|
/// crate. Instead use the narrower `upstream_monomorphizations_for`,
|
||||||
/// better, `Instance::upstream_monomorphization()`.
|
/// `upstream_drop_glue_for`, `upstream_async_drop_glue_for`, or,
|
||||||
|
/// even better, `Instance::upstream_monomorphization()`.
|
||||||
query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<UnordMap<GenericArgsRef<'tcx>, CrateNum>> {
|
query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<UnordMap<GenericArgsRef<'tcx>, CrateNum>> {
|
||||||
arena_cache
|
arena_cache
|
||||||
desc { "collecting available upstream monomorphizations" }
|
desc { "collecting available upstream monomorphizations" }
|
||||||
@ -1601,6 +1602,26 @@
|
|||||||
desc { "available upstream drop-glue for `{:?}`", args }
|
desc { "available upstream drop-glue for `{:?}`", args }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the upstream crate that exports async-drop-glue for
|
||||||
|
/// the given type (`args` is expected to be a single-item list
|
||||||
|
/// containing the type one wants async-drop-glue for).
|
||||||
|
///
|
||||||
|
/// This is a subset of `upstream_monomorphizations_for` in order
|
||||||
|
/// to increase dep-tracking granularity. Otherwise adding or
|
||||||
|
/// removing any type with async-drop-glue in any upstream crate
|
||||||
|
/// would invalidate all functions calling async-drop-glue of an
|
||||||
|
/// upstream type.
|
||||||
|
///
|
||||||
|
/// You likely want to call `Instance::upstream_monomorphization()`
|
||||||
|
/// instead of invoking this query directly.
|
||||||
|
///
|
||||||
|
/// NOTE: This query could easily be extended to also support other
|
||||||
|
/// common functions that have are large set of monomorphizations
|
||||||
|
/// (like `Clone::clone` for example).
|
||||||
|
query upstream_async_drop_glue_for(args: GenericArgsRef<'tcx>) -> Option<CrateNum> {
|
||||||
|
desc { "available upstream async-drop-glue for `{:?}`", args }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a list of all `extern` blocks of a crate.
|
/// Returns a list of all `extern` blocks of a crate.
|
||||||
query foreign_modules(_: CrateNum) -> &'tcx FxIndexMap<DefId, ForeignModule> {
|
query foreign_modules(_: CrateNum) -> &'tcx FxIndexMap<DefId, ForeignModule> {
|
||||||
arena_cache
|
arena_cache
|
||||||
|
@ -219,8 +219,9 @@ pub fn upstream_monomorphization(&self, tcx: TyCtxt<'tcx>) -> Option<CrateNum> {
|
|||||||
InstanceKind::Item(def) => tcx
|
InstanceKind::Item(def) => tcx
|
||||||
.upstream_monomorphizations_for(def)
|
.upstream_monomorphizations_for(def)
|
||||||
.and_then(|monos| monos.get(&self.args).cloned()),
|
.and_then(|monos| monos.get(&self.args).cloned()),
|
||||||
InstanceKind::DropGlue(_, Some(_)) | InstanceKind::AsyncDropGlueCtorShim(_, _) => {
|
InstanceKind::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.args),
|
||||||
tcx.upstream_drop_glue_for(self.args)
|
InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => {
|
||||||
|
tcx.upstream_async_drop_glue_for(self.args)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -256,7 +257,7 @@ pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
|
|||||||
match self {
|
match self {
|
||||||
ty::InstanceKind::Item(def) => Some(def),
|
ty::InstanceKind::Item(def) => Some(def),
|
||||||
ty::InstanceKind::DropGlue(def_id, Some(_))
|
ty::InstanceKind::DropGlue(def_id, Some(_))
|
||||||
| InstanceKind::AsyncDropGlueCtorShim(def_id, _)
|
| InstanceKind::AsyncDropGlueCtorShim(def_id, Some(_))
|
||||||
| InstanceKind::ThreadLocalShim(def_id) => Some(def_id),
|
| InstanceKind::ThreadLocalShim(def_id) => Some(def_id),
|
||||||
InstanceKind::VTableShim(..)
|
InstanceKind::VTableShim(..)
|
||||||
| InstanceKind::ReifyShim(..)
|
| InstanceKind::ReifyShim(..)
|
||||||
@ -267,6 +268,7 @@ pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
|
|||||||
| ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
|
| ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
|
||||||
| ty::InstanceKind::CoroutineKindShim { .. }
|
| ty::InstanceKind::CoroutineKindShim { .. }
|
||||||
| InstanceKind::DropGlue(..)
|
| InstanceKind::DropGlue(..)
|
||||||
|
| InstanceKind::AsyncDropGlueCtorShim(..)
|
||||||
| InstanceKind::CloneShim(..)
|
| InstanceKind::CloneShim(..)
|
||||||
| InstanceKind::FnPtrAddrShim(..) => None,
|
| InstanceKind::FnPtrAddrShim(..) => None,
|
||||||
}
|
}
|
||||||
@ -332,6 +334,26 @@ pub fn generates_cgu_internal_copy(&self, tcx: TyCtxt<'tcx>) -> bool {
|
|||||||
.map_or_else(|| adt_def.is_enum(), |dtor| tcx.cross_crate_inlinable(dtor.did))
|
.map_or_else(|| adt_def.is_enum(), |dtor| tcx.cross_crate_inlinable(dtor.did))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if let ty::InstanceKind::AsyncDropGlueCtorShim(.., Some(ty)) = *self {
|
||||||
|
// Async drop glue generally wants to be instantiated at
|
||||||
|
// every codegen unit, but without an #[inline] hint. We
|
||||||
|
// should make this available to normal end-users.
|
||||||
|
if tcx.sess.opts.incremental.is_none() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// When compiling with incremental, we can generate a *lot* of
|
||||||
|
// codegen units. Including drop glue into all of them has a
|
||||||
|
// considerable compile time cost.
|
||||||
|
//
|
||||||
|
// We include enums without destructors to allow, say, optimizing
|
||||||
|
// drops of `Option::None` before LTO. We also respect the intent of
|
||||||
|
// `#[inline]` on `Drop::drop` implementations.
|
||||||
|
return ty.ty_adt_def().map_or(true, |adt_def| {
|
||||||
|
adt_def
|
||||||
|
.async_destructor(tcx)
|
||||||
|
.map_or_else(|| adt_def.is_enum(), |dtor| tcx.cross_crate_inlinable(dtor.ctor))
|
||||||
|
});
|
||||||
|
}
|
||||||
if let ty::InstanceKind::ThreadLocalShim(..) = *self {
|
if let ty::InstanceKind::ThreadLocalShim(..) = *self {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -288,6 +288,7 @@ pub fn transform_instance<'tcx>(
|
|||||||
mut instance: Instance<'tcx>,
|
mut instance: Instance<'tcx>,
|
||||||
options: TransformTyOptions,
|
options: TransformTyOptions,
|
||||||
) -> Instance<'tcx> {
|
) -> Instance<'tcx> {
|
||||||
|
// FIXME: account for async-drop-glue
|
||||||
if (matches!(instance.def, ty::InstanceKind::Virtual(..))
|
if (matches!(instance.def, ty::InstanceKind::Virtual(..))
|
||||||
&& tcx.is_lang_item(instance.def_id(), LangItem::DropInPlace))
|
&& tcx.is_lang_item(instance.def_id(), LangItem::DropInPlace))
|
||||||
|| matches!(instance.def, ty::InstanceKind::DropGlue(..))
|
|| matches!(instance.def, ty::InstanceKind::DropGlue(..))
|
||||||
|
Loading…
Reference in New Issue
Block a user