Skip to content

Commit 2e5d870

Browse files
committed
Auto merge of #154327 - WaffleLapkin:drop_in_place_ref, r=RalfJung,scottmcm,saethlin
change the type of the argument of `drop_in_place` lang item to `&mut _` We used to special case `core::ptr::drop_in_place` when computing LLVM argument attributes with this hack: https://github.com/rust-lang/rust/blob/db5e2dc248fe5bb26f70d7baec46a3bca9fa3e1d/compiler/rustc_ty_utils/src/abi.rs#L383-L392 This is because even though `drop_in_place` takes a `*mut T` it is semantically a `&mut T` (remember how `&mut Self` is passed to `Drop::drop`). This is apparently relevant for perf. This PR replaces this hack with a simpler solution -- it makes `drop_in_place` a thin wrapper around newly added `core::ptr::drop_glue`, which is the actual lang item and takes a `&mut T`: https://github.com/rust-lang/rust/blob/d2563d5003bbecff1efc40c1f5673ceec603825b/library/core/src/ptr/mod.rs#L810-L833 ------ The rest of the PR is blessing tests and cleaning up things which are not necessary after this change. One thing that is a bit awkward is that now that `drop_glue` is the actual lang item, a lot of the comments referring to `drop_in_place` are outdated. Should I try fixing that? I've also changed `async_drop_in_place` to take a `&mut T`, and it simplified the code handling it a bit. (since it's unstable we don't need to introduce a wrapper) ------- cc @RalfJung Closes #154274
2 parents cb40c25 + e0ecfbb commit 2e5d870

103 files changed

Lines changed: 778 additions & 798 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_codegen_cranelift/example/mini_core.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -575,14 +575,10 @@ unsafe extern "C" {
575575
fn _Unwind_Resume(exc: *mut ()) -> !;
576576
}
577577

578-
#[lang = "drop_in_place"]
579-
#[allow(unconditional_recursion)]
580-
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
578+
#[lang = "drop_glue"]
579+
pub unsafe fn drop_glue<T: ?Sized>(_to_drop: &mut T) {
581580
// Code here does not matter - this is replaced by the
582581
// real drop glue by the compiler.
583-
unsafe {
584-
drop_in_place(to_drop);
585-
}
586582
}
587583

588584
#[lang = "unpin"]

compiler/rustc_codegen_cranelift/src/abi/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ pub(crate) fn codegen_drop<'tcx>(
701701
unwind: UnwindAction,
702702
) {
703703
let ty = drop_place.layout().ty;
704-
let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty);
704+
let drop_instance = Instance::resolve_drop_glue(fx.tcx, ty);
705705
let ret_block = fx.get_block(target);
706706

707707
// AsyncDropGlueCtorShim can't be here
@@ -734,7 +734,7 @@ pub(crate) fn codegen_drop<'tcx>(
734734
fx.bcx.switch_to_block(continued);
735735

736736
// FIXME(eddyb) perhaps move some of this logic into
737-
// `Instance::resolve_drop_in_place`?
737+
// `Instance::resolve_drop_glue`?
738738
let virtual_drop = Instance {
739739
def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0),
740740
args: drop_instance.args,

compiler/rustc_codegen_gcc/example/mini_core.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -577,12 +577,10 @@ fn eh_personality() -> ! {
577577
loop {}
578578
}
579579

580-
#[lang = "drop_in_place"]
581-
#[allow(unconditional_recursion)]
582-
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
580+
#[lang = "drop_glue"]
581+
pub unsafe fn drop_glue<T: ?Sized>(_to_drop: &mut T) {
583582
// Code here does not matter - this is replaced by the
584583
// real drop glue by the compiler.
585-
drop_in_place(to_drop);
586584
}
587585

588586
#[lang = "unpin"]

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -403,19 +403,18 @@ fn upstream_monomorphizations_provider(
403403

404404
let mut instances: DefIdMap<UnordMap<_, _>> = Default::default();
405405

406-
let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn();
406+
let drop_glue_fn_def_id = tcx.lang_items().drop_glue_fn();
407407
let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn();
408408

409409
for &cnum in cnums.iter() {
410410
for (exported_symbol, _) in tcx.exported_generic_symbols(cnum).iter() {
411411
let (def_id, args) = match *exported_symbol {
412412
ExportedSymbol::Generic(def_id, args) => (def_id, args),
413413
ExportedSymbol::DropGlue(ty) => {
414-
if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
414+
if let Some(drop_in_place_fn_def_id) = drop_glue_fn_def_id {
415415
(drop_in_place_fn_def_id, tcx.mk_args(&[ty.into()]))
416416
} else {
417-
// `drop_in_place` in place does not exist, don't try
418-
// to use it.
417+
// `drop_glue` does not exist, don't try to use it.
419418
continue;
420419
}
421420
}
@@ -465,7 +464,7 @@ fn upstream_drop_glue_for_provider<'tcx>(
465464
tcx: TyCtxt<'tcx>,
466465
args: GenericArgsRef<'tcx>,
467466
) -> Option<CrateNum> {
468-
let def_id = tcx.lang_items().drop_in_place_fn()?;
467+
let def_id = tcx.lang_items().drop_glue_fn()?;
469468
tcx.upstream_monomorphizations_for(def_id)?.get(&args).cloned()
470469
}
471470

@@ -587,7 +586,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
587586
}
588587
ExportedSymbol::DropGlue(ty) => rustc_symbol_mangling::symbol_name_for_instance_in_crate(
589588
tcx,
590-
Instance::resolve_drop_in_place(tcx, ty),
589+
Instance::resolve_drop_glue(tcx, ty),
591590
instantiating_crate,
592591
),
593592
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
603603
) -> MergingSucc {
604604
let ty = location.ty(self.mir, bx.tcx()).ty;
605605
let ty = self.monomorphize(ty);
606-
let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty);
606+
let drop_fn = Instance::resolve_drop_glue(bx.tcx(), ty);
607607

608608
if let ty::InstanceKind::DropGlue(_, None) = drop_fn.def {
609609
// we don't actually need to drop anything.
@@ -621,7 +621,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
621621
};
622622
let (maybe_null, drop_fn, fn_abi, drop_instance) = match ty.kind() {
623623
// FIXME(eddyb) perhaps move some of this logic into
624-
// `Instance::resolve_drop_in_place`?
624+
// `Instance::resolve_drop_glue`?
625625
ty::Dynamic(_, _) => {
626626
// IN THIS ARM, WE HAVE:
627627
// ty = *mut (dyn Trait)

compiler/rustc_const_eval/src/interpret/call.rs

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::borrow::Cow;
77
use either::{Left, Right};
88
use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx};
99
use rustc_hir::def_id::DefId;
10-
use rustc_hir::{LangItem, find_attr};
10+
use rustc_hir::find_attr;
1111
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
1212
use rustc_middle::ty::{self, AdtDef, Instance, Ty, Unnormalized, VariantDef};
1313
use rustc_middle::{bug, mir, span_bug};
@@ -278,7 +278,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
278278
callee_arg: &mir::Place<'tcx>,
279279
callee_ty: Ty<'tcx>,
280280
already_live: bool,
281-
is_drop_in_place: bool,
282281
) -> InterpResult<'tcx>
283282
where
284283
'tcx: 'x,
@@ -323,16 +322,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
323322
self.storage_live_dyn(local, meta)?;
324323
}
325324
// Now we can finally actually evaluate the callee place.
326-
let mut callee_arg = self.eval_place(*callee_arg)?;
327-
// drop_in_place has a signature which says that the first argument is `*mut T`
328-
// but really it's `&mut T`. This is where we handle that terrible hack in
329-
// the MIR semantics.
330-
// FIXME(#154274): remove this hack.
331-
if is_drop_in_place && callee_arg_idx == 0 {
332-
let pointee_ty = callee_arg.layout.ty.builtin_deref(true).unwrap();
333-
let mutref_ty = Ty::new_mut_ref(*self.tcx, self.tcx.lifetimes.re_erased, pointee_ty);
334-
callee_arg = callee_arg.transmute(self.layout_of(mutref_ty)?, self)?;
335-
}
325+
let callee_arg = self.eval_place(*callee_arg)?;
336326
// We allow some transmutes here.
337327
// FIXME: Depending on the PassMode, this should reset some padding to uninitialized. (This
338328
// is true for all `copy_op`, but there are a lot of special cases for argument passing
@@ -464,12 +454,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
464454
// Determine whether there is a special VaList argument. This is always the
465455
// last argument, and since arguments start at index 1 that's `arg_count`.
466456
let va_list_arg = callee_fn_abi.c_variadic.then(|| mir::Local::from_usize(body.arg_count));
467-
// Part of the hack for #154274, see `pass_argument`.
468-
let is_drop_in_place = {
469-
let def_id = body.source.def_id();
470-
self.tcx.is_lang_item(def_id, LangItem::DropInPlace)
471-
|| self.tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace)
472-
};
473457

474458
// During argument passing, we want retagging with protectors.
475459
M::with_retag_mode(self, RetagMode::FnEntry, |ecx| {
@@ -532,7 +516,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
532516
&dest,
533517
field_ty,
534518
/* already_live */ true,
535-
is_drop_in_place,
536519
)?;
537520
}
538521
} else {
@@ -545,7 +528,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
545528
&dest,
546529
ty,
547530
/* already_live */ false,
548-
is_drop_in_place,
549531
)?;
550532
}
551533
}
@@ -913,19 +895,21 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
913895
_ => {
914896
debug_assert_eq!(
915897
instance,
916-
ty::Instance::resolve_drop_in_place(*self.tcx, place.layout.ty)
898+
ty::Instance::resolve_drop_glue(*self.tcx, place.layout.ty)
917899
);
918900
place
919901
}
920902
};
903+
921904
let instance = {
922-
let _trace =
923-
enter_trace_span!(M, resolve::resolve_drop_in_place, ty = ?place.layout.ty);
924-
ty::Instance::resolve_drop_in_place(*self.tcx, place.layout.ty)
905+
let _trace = enter_trace_span!(M, resolve::resolve_drop_glue, ty = ?place.layout.ty);
906+
ty::Instance::resolve_drop_glue(*self.tcx, place.layout.ty)
925907
};
926908
let fn_abi = self.fn_abi_of_instance_no_deduced_attrs(instance, ty::List::empty())?;
927909

928-
let arg = self.mplace_to_imm_ptr(&place, None)?;
910+
let ref_ty = Ty::new_mut_ref(self.tcx.tcx, self.tcx.lifetimes.re_erased, place.layout.ty);
911+
let arg = self.mplace_to_imm_ptr(&place, Some(ref_ty))?;
912+
929913
let ret = MPlaceTy::fake_alloc_zst(self.layout_of(self.tcx.types.unit)?);
930914

931915
self.init_fn_call(

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
593593
let place = self.eval_place(place)?;
594594
let instance = {
595595
let _trace =
596-
enter_trace_span!(M, resolve::resolve_drop_in_place, ty = ?place.layout.ty);
597-
Instance::resolve_drop_in_place(*self.tcx, place.layout.ty)
596+
enter_trace_span!(M, resolve::resolve_drop_glue, ty = ?place.layout.ty);
597+
Instance::resolve_drop_glue(*self.tcx, place.layout.ty)
598598
};
599599
if let ty::InstanceKind::DropGlue(_, None) = instance.def {
600600
// This is the branch we enter if and only if the dropped type has no drop glue

compiler/rustc_hir/src/lang_items.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ language_item_table! {
321321
FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None;
322322
FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None;
323323

324-
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
324+
// Compiler-generated drop glue function, aka `core::ptr::drop_glue`
325+
DropGlue, sym::drop_glue, drop_glue_fn, Target::Fn, GenericRequirement::Exact(1);
325326
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
326327

327328
/// For all binary crates without `#![no_main]`, Rust will generate a "main" function.

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,8 @@ impl<'tcx> TyCtxt<'tcx> {
300300
Node::Expr(parent_expr) => {
301301
match parent_expr.kind {
302302
// Addr-of, field projections, and LHS of assignment don't constitute reads.
303-
// Assignment does call `drop_in_place`, though, but its safety
304-
// requirements are not the same.
303+
// Assignment does call `drop_glue`, though, but its safety requirements are
304+
// not the same.
305305
ExprKind::AddrOf(..) | ExprKind::Field(..) => false,
306306

307307
// Place-preserving expressions only constitute reads if their

compiler/rustc_middle/src/middle/exported_symbols.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
6666
tcx.symbol_name(ty::Instance::new_raw(def_id, args))
6767
}
6868
ExportedSymbol::DropGlue(ty) => {
69-
tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
69+
tcx.symbol_name(ty::Instance::resolve_drop_glue(tcx, ty))
7070
}
7171
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
7272
tcx.symbol_name(ty::Instance::resolve_async_drop_in_place(tcx, ty))

0 commit comments

Comments
 (0)