diff options
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mono.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/instance.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/util.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs | 54 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_smir/context.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 2 | ||||
| -rw-r--r-- | compiler/stable_mir/src/compiler_interface.rs | 3 | ||||
| -rw-r--r-- | compiler/stable_mir/src/mir/mono.rs | 5 |
9 files changed, 54 insertions, 31 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 24f2c50e882..fad81600576 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -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); diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 5ccc0386c97..9eed7019782 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -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() } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index c7c4225c80e..4002d0da790 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -288,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, }; @@ -357,11 +358,12 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::FnPtrAddrShim(..) | InstanceDef::FnPtrShim(..) | InstanceDef::DropGlue(_, Some(_)) - | InstanceDef::AsyncDropGlueCtorShim(..) => false, + | InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => false, InstanceDef::ClosureOnceShim { .. } | InstanceDef::ConstructCoroutineInClosureShim { .. } | InstanceDef::CoroutineKindShim { .. } | InstanceDef::DropGlue(..) + | InstanceDef::AsyncDropGlueCtorShim(..) | InstanceDef::Item(_) | InstanceDef::Intrinsic(..) | InstanceDef::ReifyShim(..) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index cd9d17cf930..2d83b9f8ef1 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1340,7 +1340,7 @@ impl<'tcx> Ty<'tcx> { /// implementation. Returning `true` means nothing -- could be /// `Drop`, might not be. fn could_have_surface_drop(self) -> bool { - self.is_async_destructor_trivially_noop() + !self.is_async_destructor_trivially_noop() && !matches!( self.kind(), ty::Tuple(_) diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index a423e324781..80eadb9abdc 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -9,7 +9,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{ BasicBlock, BasicBlockData, Body, CallSource, CastKind, Const, ConstOperand, ConstValue, Local, 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::util::Discr; @@ -67,9 +67,12 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { const MAX_STACK_LEN: usize = 2; 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 arg_ty = if let Some(ty) = self_ty { ty } else { tcx.types.unit }; - let sig = tcx.fn_sig(def_id).instantiate(tcx, &[arg_ty.into()]); + let args = if let Some(ty) = self_ty { + tcx.mk_args(&[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 span = tcx.def_span(def_id); @@ -113,7 +116,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { fn build(self) -> Body<'tcx> { 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 = || { @@ -258,8 +261,8 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { self.return_() } - fn build_noop(mut self) -> Body<'tcx> { - self.put_noop(); + fn build_zst_output(mut self) -> Body<'tcx> { + self.put_zst_output(); self.return_() } @@ -288,6 +291,15 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { 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. fn put_self(&mut self) { self.put_operand(Operand::Copy(Self::SELF_PTR.into())) @@ -464,23 +476,15 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { self.stack.len(), ) }; - const RETURN_LOCAL: Local = Local::from_u32(0); - - debug_assert_eq!( - output.ty(&self.locals, self.tcx), - self.self_ty.map(|ty| ty.async_destructor_ty(self.tcx, self.param_env)).unwrap_or_else( - || { - self.tcx - .fn_sig( - self.tcx.require_lang_item(LangItem::AsyncDropNoop, Some(self.span)), - ) - .instantiate_identity() - .output() - .no_bound_vars() - .unwrap() - } - ), - ); + #[cfg(debug_assertions)] + if let Some(ty) = self.self_ty { + debug_assert_eq!( + output.ty(&self.locals, self.tcx), + ty.async_destructor_ty(self.tcx, self.param_env), + "output async destructor types did not match for type: {ty:?}", + ); + } + let dead_storage = match &output { Operand::Move(place) => Some(Statement { source_info, @@ -492,7 +496,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { last_bb.statements.extend( iter::once(Statement { 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), ); diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 61bbedf9eec..fd31c020f89 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -500,6 +500,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> { 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 { let mut tables = self.0.borrow_mut(); let def_id = tables[def_id]; diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 400556a7d6a..c1661fa63a8 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -57,7 +57,7 @@ fn resolve_instance<'tcx>( } else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() { 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() { ty::Closure(..) | ty::CoroutineClosure(..) diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index 94c552199bc..e82d1f4813e 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -158,6 +158,9 @@ pub trait Context { /// Check if this is an empty DropGlue shim. 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. /// This function will panic if the item is generic. fn mono_instance(&self, def_id: DefId) -> Instance; diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs index a032a180fcf..394038926f6 100644 --- a/compiler/stable_mir/src/mir/mono.rs +++ b/compiler/stable_mir/src/mir/mono.rs @@ -157,7 +157,10 @@ impl Instance { /// 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. 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. |
