Skip to content

Commit 043bac9

Browse files
frank-king王俊吉
authored andcommitted
Emit either mono item of Drop::drop or Drop::pin_drop depending on which was implemented
1 parent b40ce8b commit 043bac9

10 files changed

Lines changed: 90 additions & 21 deletions

File tree

compiler/rustc_mir_transform/src/elaborate_drop.rs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_middle::ty::adjustment::PointerCoercion;
99
use rustc_middle::ty::util::IntTypeExt;
1010
use rustc_middle::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt};
1111
use rustc_middle::{bug, span_bug, traits};
12+
use rustc_span::symbol::sym;
1213
use rustc_span::{DUMMY_SP, Spanned, dummy_spanned};
1314
use tracing::{debug, instrument};
1415

@@ -973,26 +974,55 @@ where
973974
fn destructor_call_block_sync(&mut self, succ: BasicBlock, unwind: Unwind) -> BasicBlock {
974975
let tcx = self.tcx();
975976
let drop_trait = tcx.require_lang_item(LangItem::Drop, DUMMY_SP);
976-
let drop_fn = tcx.associated_item_def_ids(drop_trait)[0];
977+
let mut drop_fn = tcx.associated_item_def_ids(drop_trait)[0];
977978
let ty = self.place_ty(self.place);
978979

979980
let ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty);
980981
let ref_place = self.new_temp(ref_ty);
981982
let unit_temp = Place::from(self.new_temp(tcx.types.unit));
982983

984+
let mut arg_place = ref_place;
985+
986+
let mut stmts = vec![self.assign(
987+
Place::from(ref_place),
988+
Rvalue::Ref(
989+
tcx.lifetimes.re_erased,
990+
BorrowKind::Mut { kind: MutBorrowKind::Default },
991+
self.place,
992+
),
993+
)];
994+
995+
// When the type implements `Drop::pin_drop`, we call it directly instead of `Drop::drop`.
996+
if let Some(adt) = ty.ty_adt_def()
997+
&& let Some(dtor) = adt.destructor(tcx)
998+
&& tcx.item_name(dtor.did) == sym::pin_drop
999+
{
1000+
debug!("call `pin_drop` for {adt:?}");
1001+
let pin_ref_ty = Ty::new_pinned_ref(tcx, tcx.lifetimes.re_erased, ty, Mutability::Mut);
1002+
let pin_ref_place = self.new_temp(pin_ref_ty);
1003+
stmts.push(self.assign(
1004+
Place::from(pin_ref_place),
1005+
Rvalue::Aggregate(
1006+
Box::new(AggregateKind::Adt(
1007+
tcx.require_lang_item(LangItem::Pin, DUMMY_SP),
1008+
VariantIdx::ZERO,
1009+
tcx.mk_args(&[ref_ty.into()]),
1010+
None,
1011+
None,
1012+
)),
1013+
[Operand::Move(Place::from(ref_place))].into(),
1014+
),
1015+
));
1016+
drop_fn = tcx.associated_item_def_ids(drop_trait)[1];
1017+
arg_place = pin_ref_place;
1018+
}
1019+
9831020
self.new_block_with_statements(
9841021
unwind,
985-
vec![self.assign(
986-
Place::from(ref_place),
987-
Rvalue::Ref(
988-
tcx.lifetimes.re_erased,
989-
BorrowKind::Mut { kind: MutBorrowKind::Default },
990-
self.place,
991-
),
992-
)],
1022+
stmts,
9931023
TerminatorKind::Call {
9941024
func: Operand::function_handle(tcx, drop_fn, [ty.into()], self.source_info.span),
995-
args: [Spanned { node: Operand::Move(Place::from(ref_place)), span: DUMMY_SP }]
1025+
args: [Spanned { node: Operand::Move(Place::from(arg_place)), span: DUMMY_SP }]
9961026
.into(),
9971027
destination: unit_temp,
9981028
target: Some(succ),

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,15 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) ->
10621062
tcx.dcx().delayed_bug("attempt to codegen `#[rustc_force_inline]` item");
10631063
}
10641064

1065+
// It is not possible to manually call `Drop::drop` and `Drop::pin_drop`, so we can
1066+
// skip codegen for mentioned associated items of the `Drop` trait, and only codegen
1067+
// `drop` or `pin_drop` depending on which was implemented.
1068+
if let Some(trait_id) = tcx.trait_of_assoc(def_id)
1069+
&& tcx.is_lang_item(trait_id, LangItem::Drop)
1070+
{
1071+
return false;
1072+
}
1073+
10651074
if def_id.is_local() {
10661075
// Local items cannot be referred to locally without monomorphizing them locally.
10671076
return true;

tests/codegen-units/item-collection/drop-glue-eager.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ struct StructWithDrop {
1010

1111
impl Drop for StructWithDrop {
1212
//~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop
13-
//~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::pin_drop
1413
fn drop(&mut self) {}
1514
}
1615

@@ -25,7 +24,6 @@ enum EnumWithDrop {
2524

2625
impl Drop for EnumWithDrop {
2726
//~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::drop
28-
//~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::pin_drop
2927
fn drop(&mut self) {}
3028
}
3129

@@ -36,7 +34,6 @@ enum EnumNoDrop {
3634
// We should be able to monomorphize drops for struct with lifetimes.
3735
impl<'a> Drop for StructWithDropAndLt<'a> {
3836
//~ MONO_ITEM fn <StructWithDropAndLt<'_> as std::ops::Drop>::drop
39-
//~ MONO_ITEM fn <StructWithDropAndLt<'_> as std::ops::Drop>::pin_drop
4037
fn drop(&mut self) {}
4138
}
4239

@@ -55,6 +52,5 @@ struct StructWithLtAndPredicate<'a: 'a> {
5552
// We should be able to monomorphize drops for struct with lifetimes.
5653
impl<'a> Drop for StructWithLtAndPredicate<'a> {
5754
//~ MONO_ITEM fn <StructWithLtAndPredicate<'_> as std::ops::Drop>::drop
58-
//~ MONO_ITEM fn <StructWithLtAndPredicate<'_> as std::ops::Drop>::pin_drop
5955
fn drop(&mut self) {}
6056
}

tests/codegen-units/item-collection/drop_in_place_intrinsic.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ struct StructWithDtor(u32);
99

1010
impl Drop for StructWithDtor {
1111
//~ MONO_ITEM fn <StructWithDtor as std::ops::Drop>::drop
12-
//~ MONO_ITEM fn <StructWithDtor as std::ops::Drop>::pin_drop
1312
fn drop(&mut self) {}
1413
}
1514
//~ MONO_ITEM fn start

tests/codegen-units/item-collection/generic-drop-glue.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ struct NonGenericWithDrop(#[allow(dead_code)] i32);
3939

4040
impl Drop for NonGenericWithDrop {
4141
//~ MONO_ITEM fn <NonGenericWithDrop as std::ops::Drop>::drop
42-
//~ MONO_ITEM fn <NonGenericWithDrop as std::ops::Drop>::pin_drop
4342
fn drop(&mut self) {}
4443
}
4544

tests/codegen-units/item-collection/non-generic-closures.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,5 @@ struct PresentDrop;
7474

7575
impl Drop for PresentDrop {
7676
//~ MONO_ITEM fn <PresentDrop as std::ops::Drop>::drop @@ non_generic_closures-cgu.0[External]
77-
//~ MONO_ITEM fn <PresentDrop as std::ops::Drop>::pin_drop @@ non_generic_closures-cgu.0[External]
7877
fn drop(&mut self) {}
7978
}

tests/codegen-units/item-collection/non-generic-drop-glue.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ struct StructWithDrop {
1111

1212
impl Drop for StructWithDrop {
1313
//~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop
14-
//~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::pin_drop
1514
fn drop(&mut self) {}
1615
}
1716

@@ -26,7 +25,6 @@ enum EnumWithDrop {
2625

2726
impl Drop for EnumWithDrop {
2827
//~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::drop
29-
//~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::pin_drop
3028
fn drop(&mut self) {}
3129
}
3230

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#![feature(pin_ergonomics)]
2+
// Ensure that we emit either `Drop::drop` or `Drop::pin_drop` for types that implement `Drop`.
3+
4+
//@ compile-flags:-Clink-dead-code
5+
//@ compile-flags:--crate-type=lib
6+
//@ rustc-env:MONO_TEST=1
7+
8+
//~ MONO_ITEM fn std::ptr::drop_glue::<StructWithDrop> - shim(Some(StructWithDrop))
9+
struct StructWithDrop {
10+
x: i32,
11+
}
12+
13+
impl Drop for StructWithDrop {
14+
//~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop
15+
fn drop(&mut self) {}
16+
}
17+
18+
struct StructNoDrop {
19+
x: i32,
20+
}
21+
22+
//~ MONO_ITEM fn std::ptr::drop_glue::<StructWithPinDrop> - shim(Some(StructWithPinDrop))
23+
struct StructWithPinDrop {
24+
x: i32,
25+
}
26+
27+
impl Drop for StructWithPinDrop {
28+
//~ MONO_ITEM fn <StructWithPinDrop as std::ops::Drop>::pin_drop
29+
fn pin_drop(&pin mut self) {}
30+
}
31+
32+
//~ MONO_ITEM fn std::ptr::drop_glue::<StructPinV2WithPinDrop> - shim(Some(StructPinV2WithPinDrop))
33+
#[pin_v2]
34+
struct StructPinV2WithPinDrop {
35+
x: i32,
36+
}
37+
38+
impl Drop for StructPinV2WithPinDrop {
39+
//~ MONO_ITEM fn <StructPinV2WithPinDrop as std::ops::Drop>::pin_drop
40+
fn pin_drop(&pin mut self) {}
41+
}

tests/codegen-units/item-collection/transitive-drop-glue.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ struct Leaf;
1313

1414
impl Drop for Leaf {
1515
//~ MONO_ITEM fn <Leaf as std::ops::Drop>::drop
16-
//~ MONO_ITEM fn <Leaf as std::ops::Drop>::pin_drop
1716
fn drop(&mut self) {}
1817
}
1918

tests/codegen-units/item-collection/tuple-drop-glue.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ struct Dropped;
99

1010
impl Drop for Dropped {
1111
//~ MONO_ITEM fn <Dropped as std::ops::Drop>::drop
12-
//~ MONO_ITEM fn <Dropped as std::ops::Drop>::pin_drop
1312
fn drop(&mut self) {}
1413
}
1514

0 commit comments

Comments
 (0)