Skip to content

Commit e239e73

Browse files
committed
Fix disabling the export of noop async_drop_in_place_raw
1 parent 80c0b7e commit e239e73

File tree

9 files changed

+54
-31
lines changed

9 files changed

+54
-31
lines changed

Diff for: compiler/rustc_codegen_ssa/src/mir/block.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
835835

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

838-
if let Some(ty::InstanceDef::DropGlue(_, None)) = def {
838+
if let Some(
839+
ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None),
840+
) = def
841+
{
839842
// Empty drop glue; a no-op.
840843
let target = target.unwrap();
841844
return helper.funclet_br(self, bx, target, mergeable_succ);

Diff for: compiler/rustc_middle/src/mir/mono.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ impl<'tcx> MonoItem<'tcx> {
6565
match instance.def {
6666
// "Normal" functions size estimate: the number of
6767
// statements, plus one for the terminator.
68-
InstanceDef::Item(..) | InstanceDef::DropGlue(..) => {
68+
InstanceDef::Item(..)
69+
| InstanceDef::DropGlue(..)
70+
| InstanceDef::AsyncDropGlueCtorShim(..) => {
6971
let mir = tcx.instance_mir(instance.def);
7072
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
7173
}

Diff for: compiler/rustc_middle/src/ty/instance.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ impl<'tcx> InstanceDef<'tcx> {
288288
let def_id = match *self {
289289
ty::InstanceDef::Item(def) => def,
290290
ty::InstanceDef::DropGlue(_, Some(_)) => return false,
291+
ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => return false,
291292
ty::InstanceDef::ThreadLocalShim(_) => return false,
292293
_ => return true,
293294
};
@@ -357,11 +358,12 @@ impl<'tcx> InstanceDef<'tcx> {
357358
| InstanceDef::FnPtrAddrShim(..)
358359
| InstanceDef::FnPtrShim(..)
359360
| InstanceDef::DropGlue(_, Some(_))
360-
| InstanceDef::AsyncDropGlueCtorShim(..) => false,
361+
| InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => false,
361362
InstanceDef::ClosureOnceShim { .. }
362363
| InstanceDef::ConstructCoroutineInClosureShim { .. }
363364
| InstanceDef::CoroutineKindShim { .. }
364365
| InstanceDef::DropGlue(..)
366+
| InstanceDef::AsyncDropGlueCtorShim(..)
365367
| InstanceDef::Item(_)
366368
| InstanceDef::Intrinsic(..)
367369
| InstanceDef::ReifyShim(..)

Diff for: compiler/rustc_middle/src/ty/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ impl<'tcx> Ty<'tcx> {
13401340
/// implementation. Returning `true` means nothing -- could be
13411341
/// `Drop`, might not be.
13421342
fn could_have_surface_drop(self) -> bool {
1343-
self.is_async_destructor_trivially_noop()
1343+
!self.is_async_destructor_trivially_noop()
13441344
&& !matches!(
13451345
self.kind(),
13461346
ty::Tuple(_)

Diff for: compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs

+29-25
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_index::{Idx, IndexVec};
99
use rustc_middle::mir::{
1010
BasicBlock, BasicBlockData, Body, CallSource, CastKind, Const, ConstOperand, ConstValue, Local,
1111
LocalDecl, MirSource, Operand, Place, PlaceElem, Rvalue, SourceInfo, Statement, StatementKind,
12-
Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason,
12+
Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason, RETURN_PLACE,
1313
};
1414
use rustc_middle::ty::adjustment::PointerCoercion;
1515
use rustc_middle::ty::util::Discr;
@@ -67,9 +67,12 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
6767
const MAX_STACK_LEN: usize = 2;
6868

6969
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Option<Ty<'tcx>>) -> Self {
70-
// Assuming `async_drop_in_place::<()>` is the same as for any type with noop async destructor
71-
let arg_ty = if let Some(ty) = self_ty { ty } else { tcx.types.unit };
72-
let sig = tcx.fn_sig(def_id).instantiate(tcx, &[arg_ty.into()]);
70+
let args = if let Some(ty) = self_ty {
71+
tcx.mk_args(&[ty.into()])
72+
} else {
73+
ty::GenericArgs::identity_for_item(tcx, def_id)
74+
};
75+
let sig = tcx.fn_sig(def_id).instantiate(tcx, args);
7376
let sig = tcx.instantiate_bound_regions_with_erased(sig);
7477
let span = tcx.def_span(def_id);
7578

@@ -113,7 +116,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
113116

114117
fn build(self) -> Body<'tcx> {
115118
let (tcx, def_id, Some(self_ty)) = (self.tcx, self.def_id, self.self_ty) else {
116-
return self.build_noop();
119+
return self.build_zst_output();
117120
};
118121

119122
let surface_drop_kind = || {
@@ -258,8 +261,8 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
258261
self.return_()
259262
}
260263

261-
fn build_noop(mut self) -> Body<'tcx> {
262-
self.put_noop();
264+
fn build_zst_output(mut self) -> Body<'tcx> {
265+
self.put_zst_output();
263266
self.return_()
264267
}
265268

@@ -288,6 +291,15 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
288291
self.return_()
289292
}
290293

294+
fn put_zst_output(&mut self) {
295+
let return_ty = self.locals[RETURN_PLACE].ty;
296+
self.put_operand(Operand::Constant(Box::new(ConstOperand {
297+
span: self.span,
298+
user_ty: None,
299+
const_: Const::zero_sized(return_ty),
300+
})));
301+
}
302+
291303
/// Puts `to_drop: *mut Self` on top of the stack.
292304
fn put_self(&mut self) {
293305
self.put_operand(Operand::Copy(Self::SELF_PTR.into()))
@@ -464,23 +476,15 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
464476
self.stack.len(),
465477
)
466478
};
467-
const RETURN_LOCAL: Local = Local::from_u32(0);
468-
469-
debug_assert_eq!(
470-
output.ty(&self.locals, self.tcx),
471-
self.self_ty.map(|ty| ty.async_destructor_ty(self.tcx, self.param_env)).unwrap_or_else(
472-
|| {
473-
self.tcx
474-
.fn_sig(
475-
self.tcx.require_lang_item(LangItem::AsyncDropNoop, Some(self.span)),
476-
)
477-
.instantiate_identity()
478-
.output()
479-
.no_bound_vars()
480-
.unwrap()
481-
}
482-
),
483-
);
479+
#[cfg(debug_assertions)]
480+
if let Some(ty) = self.self_ty {
481+
debug_assert_eq!(
482+
output.ty(&self.locals, self.tcx),
483+
ty.async_destructor_ty(self.tcx, self.param_env),
484+
"output async destructor types did not match for type: {ty:?}",
485+
);
486+
}
487+
484488
let dead_storage = match &output {
485489
Operand::Move(place) => Some(Statement {
486490
source_info,
@@ -492,7 +496,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
492496
last_bb.statements.extend(
493497
iter::once(Statement {
494498
source_info,
495-
kind: StatementKind::Assign(Box::new((RETURN_LOCAL.into(), Rvalue::Use(output)))),
499+
kind: StatementKind::Assign(Box::new((RETURN_PLACE.into(), Rvalue::Use(output)))),
496500
})
497501
.chain(dead_storage),
498502
);

Diff for: compiler/rustc_smir/src/rustc_smir/context.rs

+6
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
500500
matches!(instance.def, ty::InstanceDef::DropGlue(_, None))
501501
}
502502

503+
fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool {
504+
let tables = self.0.borrow_mut();
505+
let instance = tables.instances[def];
506+
matches!(instance.def, ty::InstanceDef::AsyncDropGlueCtorShim(_, None))
507+
}
508+
503509
fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance {
504510
let mut tables = self.0.borrow_mut();
505511
let def_id = tables[def_id];

Diff for: compiler/rustc_ty_utils/src/instance.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fn resolve_instance<'tcx>(
5757
} else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() {
5858
let ty = args.type_at(0);
5959

60-
if ty.is_async_destructor_noop(tcx, param_env) {
60+
if !ty.is_async_destructor_noop(tcx, param_env) {
6161
match *ty.kind() {
6262
ty::Closure(..)
6363
| ty::CoroutineClosure(..)

Diff for: compiler/stable_mir/src/compiler_interface.rs

+3
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ pub trait Context {
158158
/// Check if this is an empty DropGlue shim.
159159
fn is_empty_drop_shim(&self, def: InstanceDef) -> bool;
160160

161+
/// Check if this is an empty AsyncDropGlueCtor shim.
162+
fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool;
163+
161164
/// Convert a non-generic crate item into an instance.
162165
/// This function will panic if the item is generic.
163166
fn mono_instance(&self, def_id: DefId) -> Instance;

Diff for: compiler/stable_mir/src/mir/mono.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,10 @@ impl Instance {
157157
/// When generating code for a Drop terminator, users can ignore an empty drop glue.
158158
/// These shims are only needed to generate a valid Drop call done via VTable.
159159
pub fn is_empty_shim(&self) -> bool {
160-
self.kind == InstanceKind::Shim && with(|cx| cx.is_empty_drop_shim(self.def))
160+
self.kind == InstanceKind::Shim
161+
&& with(|cx| {
162+
cx.is_empty_drop_shim(self.def) || cx.is_empty_async_drop_ctor_shim(self.def)
163+
})
161164
}
162165

163166
/// Try to constant evaluate the instance into a constant with the given type.

0 commit comments

Comments
 (0)