Fix disabling the export of noop async_drop_in_place_raw
This commit is contained in:
parent
80c0b7e90f
commit
e239e73a77
9 changed files with 53 additions and 30 deletions
|
@ -835,7 +835,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
|
|
||||||
let def = instance.map(|i| i.def);
|
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.
|
// Empty drop glue; a no-op.
|
||||||
let target = target.unwrap();
|
let target = target.unwrap();
|
||||||
return helper.funclet_br(self, bx, target, mergeable_succ);
|
return helper.funclet_br(self, bx, target, mergeable_succ);
|
||||||
|
|
|
@ -65,7 +65,9 @@ impl<'tcx> MonoItem<'tcx> {
|
||||||
match instance.def {
|
match instance.def {
|
||||||
// "Normal" functions size estimate: the number of
|
// "Normal" functions size estimate: the number of
|
||||||
// statements, plus one for the terminator.
|
// statements, plus one for the terminator.
|
||||||
InstanceDef::Item(..) | InstanceDef::DropGlue(..) => {
|
InstanceDef::Item(..)
|
||||||
|
| InstanceDef::DropGlue(..)
|
||||||
|
| InstanceDef::AsyncDropGlueCtorShim(..) => {
|
||||||
let mir = tcx.instance_mir(instance.def);
|
let mir = tcx.instance_mir(instance.def);
|
||||||
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
|
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,6 +288,7 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||||
let def_id = match *self {
|
let def_id = match *self {
|
||||||
ty::InstanceDef::Item(def) => def,
|
ty::InstanceDef::Item(def) => def,
|
||||||
ty::InstanceDef::DropGlue(_, Some(_)) => return false,
|
ty::InstanceDef::DropGlue(_, Some(_)) => return false,
|
||||||
|
ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => return false,
|
||||||
ty::InstanceDef::ThreadLocalShim(_) => return false,
|
ty::InstanceDef::ThreadLocalShim(_) => return false,
|
||||||
_ => return true,
|
_ => return true,
|
||||||
};
|
};
|
||||||
|
@ -357,11 +358,12 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||||
| InstanceDef::FnPtrAddrShim(..)
|
| InstanceDef::FnPtrAddrShim(..)
|
||||||
| InstanceDef::FnPtrShim(..)
|
| InstanceDef::FnPtrShim(..)
|
||||||
| InstanceDef::DropGlue(_, Some(_))
|
| InstanceDef::DropGlue(_, Some(_))
|
||||||
| InstanceDef::AsyncDropGlueCtorShim(..) => false,
|
| InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => false,
|
||||||
InstanceDef::ClosureOnceShim { .. }
|
InstanceDef::ClosureOnceShim { .. }
|
||||||
| InstanceDef::ConstructCoroutineInClosureShim { .. }
|
| InstanceDef::ConstructCoroutineInClosureShim { .. }
|
||||||
| InstanceDef::CoroutineKindShim { .. }
|
| InstanceDef::CoroutineKindShim { .. }
|
||||||
| InstanceDef::DropGlue(..)
|
| InstanceDef::DropGlue(..)
|
||||||
|
| InstanceDef::AsyncDropGlueCtorShim(..)
|
||||||
| InstanceDef::Item(_)
|
| InstanceDef::Item(_)
|
||||||
| InstanceDef::Intrinsic(..)
|
| InstanceDef::Intrinsic(..)
|
||||||
| InstanceDef::ReifyShim(..)
|
| InstanceDef::ReifyShim(..)
|
||||||
|
|
|
@ -1340,7 +1340,7 @@ impl<'tcx> Ty<'tcx> {
|
||||||
/// implementation. Returning `true` means nothing -- could be
|
/// implementation. Returning `true` means nothing -- could be
|
||||||
/// `Drop`, might not be.
|
/// `Drop`, might not be.
|
||||||
fn could_have_surface_drop(self) -> bool {
|
fn could_have_surface_drop(self) -> bool {
|
||||||
self.is_async_destructor_trivially_noop()
|
!self.is_async_destructor_trivially_noop()
|
||||||
&& !matches!(
|
&& !matches!(
|
||||||
self.kind(),
|
self.kind(),
|
||||||
ty::Tuple(_)
|
ty::Tuple(_)
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_index::{Idx, IndexVec};
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
BasicBlock, BasicBlockData, Body, CallSource, CastKind, Const, ConstOperand, ConstValue, Local,
|
BasicBlock, BasicBlockData, Body, CallSource, CastKind, Const, ConstOperand, ConstValue, Local,
|
||||||
LocalDecl, MirSource, Operand, Place, PlaceElem, Rvalue, SourceInfo, Statement, StatementKind,
|
LocalDecl, MirSource, Operand, Place, PlaceElem, Rvalue, SourceInfo, Statement, StatementKind,
|
||||||
Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason,
|
Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason, RETURN_PLACE,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::util::Discr;
|
use rustc_middle::ty::util::Discr;
|
||||||
|
@ -67,9 +67,12 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
||||||
const MAX_STACK_LEN: usize = 2;
|
const MAX_STACK_LEN: usize = 2;
|
||||||
|
|
||||||
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Option<Ty<'tcx>>) -> Self {
|
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Option<Ty<'tcx>>) -> Self {
|
||||||
// Assuming `async_drop_in_place::<()>` is the same as for any type with noop async destructor
|
let args = if let Some(ty) = self_ty {
|
||||||
let arg_ty = if let Some(ty) = self_ty { ty } else { tcx.types.unit };
|
tcx.mk_args(&[ty.into()])
|
||||||
let sig = tcx.fn_sig(def_id).instantiate(tcx, &[arg_ty.into()]);
|
} else {
|
||||||
|
ty::GenericArgs::identity_for_item(tcx, def_id)
|
||||||
|
};
|
||||||
|
let sig = tcx.fn_sig(def_id).instantiate(tcx, args);
|
||||||
let sig = tcx.instantiate_bound_regions_with_erased(sig);
|
let sig = tcx.instantiate_bound_regions_with_erased(sig);
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
|
|
||||||
|
@ -113,7 +116,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
||||||
|
|
||||||
fn build(self) -> Body<'tcx> {
|
fn build(self) -> Body<'tcx> {
|
||||||
let (tcx, def_id, Some(self_ty)) = (self.tcx, self.def_id, self.self_ty) else {
|
let (tcx, def_id, Some(self_ty)) = (self.tcx, self.def_id, self.self_ty) else {
|
||||||
return self.build_noop();
|
return self.build_zst_output();
|
||||||
};
|
};
|
||||||
|
|
||||||
let surface_drop_kind = || {
|
let surface_drop_kind = || {
|
||||||
|
@ -258,8 +261,8 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
||||||
self.return_()
|
self.return_()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_noop(mut self) -> Body<'tcx> {
|
fn build_zst_output(mut self) -> Body<'tcx> {
|
||||||
self.put_noop();
|
self.put_zst_output();
|
||||||
self.return_()
|
self.return_()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +291,15 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
||||||
self.return_()
|
self.return_()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn put_zst_output(&mut self) {
|
||||||
|
let return_ty = self.locals[RETURN_PLACE].ty;
|
||||||
|
self.put_operand(Operand::Constant(Box::new(ConstOperand {
|
||||||
|
span: self.span,
|
||||||
|
user_ty: None,
|
||||||
|
const_: Const::zero_sized(return_ty),
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
/// Puts `to_drop: *mut Self` on top of the stack.
|
/// Puts `to_drop: *mut Self` on top of the stack.
|
||||||
fn put_self(&mut self) {
|
fn put_self(&mut self) {
|
||||||
self.put_operand(Operand::Copy(Self::SELF_PTR.into()))
|
self.put_operand(Operand::Copy(Self::SELF_PTR.into()))
|
||||||
|
@ -464,23 +476,15 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
||||||
self.stack.len(),
|
self.stack.len(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
const RETURN_LOCAL: Local = Local::from_u32(0);
|
#[cfg(debug_assertions)]
|
||||||
|
if let Some(ty) = self.self_ty {
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
output.ty(&self.locals, self.tcx),
|
output.ty(&self.locals, self.tcx),
|
||||||
self.self_ty.map(|ty| ty.async_destructor_ty(self.tcx, self.param_env)).unwrap_or_else(
|
ty.async_destructor_ty(self.tcx, self.param_env),
|
||||||
|| {
|
"output async destructor types did not match for type: {ty:?}",
|
||||||
self.tcx
|
|
||||||
.fn_sig(
|
|
||||||
self.tcx.require_lang_item(LangItem::AsyncDropNoop, Some(self.span)),
|
|
||||||
)
|
|
||||||
.instantiate_identity()
|
|
||||||
.output()
|
|
||||||
.no_bound_vars()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let dead_storage = match &output {
|
let dead_storage = match &output {
|
||||||
Operand::Move(place) => Some(Statement {
|
Operand::Move(place) => Some(Statement {
|
||||||
source_info,
|
source_info,
|
||||||
|
@ -492,7 +496,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
||||||
last_bb.statements.extend(
|
last_bb.statements.extend(
|
||||||
iter::once(Statement {
|
iter::once(Statement {
|
||||||
source_info,
|
source_info,
|
||||||
kind: StatementKind::Assign(Box::new((RETURN_LOCAL.into(), Rvalue::Use(output)))),
|
kind: StatementKind::Assign(Box::new((RETURN_PLACE.into(), Rvalue::Use(output)))),
|
||||||
})
|
})
|
||||||
.chain(dead_storage),
|
.chain(dead_storage),
|
||||||
);
|
);
|
||||||
|
|
|
@ -500,6 +500,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||||
matches!(instance.def, ty::InstanceDef::DropGlue(_, None))
|
matches!(instance.def, ty::InstanceDef::DropGlue(_, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool {
|
||||||
|
let tables = self.0.borrow_mut();
|
||||||
|
let instance = tables.instances[def];
|
||||||
|
matches!(instance.def, ty::InstanceDef::AsyncDropGlueCtorShim(_, None))
|
||||||
|
}
|
||||||
|
|
||||||
fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance {
|
fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance {
|
||||||
let mut tables = self.0.borrow_mut();
|
let mut tables = self.0.borrow_mut();
|
||||||
let def_id = tables[def_id];
|
let def_id = tables[def_id];
|
||||||
|
|
|
@ -57,7 +57,7 @@ fn resolve_instance<'tcx>(
|
||||||
} else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() {
|
} else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() {
|
||||||
let ty = args.type_at(0);
|
let ty = args.type_at(0);
|
||||||
|
|
||||||
if ty.is_async_destructor_noop(tcx, param_env) {
|
if !ty.is_async_destructor_noop(tcx, param_env) {
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Closure(..)
|
ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
|
|
|
@ -158,6 +158,9 @@ pub trait Context {
|
||||||
/// Check if this is an empty DropGlue shim.
|
/// Check if this is an empty DropGlue shim.
|
||||||
fn is_empty_drop_shim(&self, def: InstanceDef) -> bool;
|
fn is_empty_drop_shim(&self, def: InstanceDef) -> bool;
|
||||||
|
|
||||||
|
/// Check if this is an empty AsyncDropGlueCtor shim.
|
||||||
|
fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool;
|
||||||
|
|
||||||
/// Convert a non-generic crate item into an instance.
|
/// Convert a non-generic crate item into an instance.
|
||||||
/// This function will panic if the item is generic.
|
/// This function will panic if the item is generic.
|
||||||
fn mono_instance(&self, def_id: DefId) -> Instance;
|
fn mono_instance(&self, def_id: DefId) -> Instance;
|
||||||
|
|
|
@ -157,7 +157,10 @@ impl Instance {
|
||||||
/// When generating code for a Drop terminator, users can ignore an empty drop glue.
|
/// When generating code for a Drop terminator, users can ignore an empty drop glue.
|
||||||
/// These shims are only needed to generate a valid Drop call done via VTable.
|
/// These shims are only needed to generate a valid Drop call done via VTable.
|
||||||
pub fn is_empty_shim(&self) -> bool {
|
pub fn is_empty_shim(&self) -> bool {
|
||||||
self.kind == InstanceKind::Shim && with(|cx| cx.is_empty_drop_shim(self.def))
|
self.kind == InstanceKind::Shim
|
||||||
|
&& with(|cx| {
|
||||||
|
cx.is_empty_drop_shim(self.def) || cx.is_empty_async_drop_ctor_shim(self.def)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to constant evaluate the instance into a constant with the given type.
|
/// Try to constant evaluate the instance into a constant with the given type.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue