@@ -52,7 +52,8 @@ pub enum InstanceDef<'tcx> {
52
52
/// `<[mut closure] as FnOnce>::call_once`
53
53
ClosureOnceShim { call_once : DefId } ,
54
54
55
- /// `drop_in_place::<T>; None` for empty drop glue.
55
+ /// `real_drop_in_place::<T>`; `None` for empty drop glue. The `DefId` is
56
+ /// for `real_drop_in_place`.
56
57
DropGlue ( DefId , Option < Ty < ' tcx > > ) ,
57
58
58
59
///`<T as Clone>::clone` shim.
@@ -108,11 +109,28 @@ impl<'tcx> InstanceDef<'tcx> {
108
109
if self . is_inline ( tcx) {
109
110
return true
110
111
}
111
- if let ty:: InstanceDef :: DropGlue ( ..) = * self {
112
- // Drop glue wants to be instantiated at every codegen
112
+ if let ty:: InstanceDef :: DropGlue ( .., Some ( ty ) ) = * self {
113
+ // Drop glue generally wants to be instantiated at every codegen
113
114
// unit, but without an #[inline] hint. We should make this
114
115
// available to normal end-users.
115
- return true
116
+ if tcx. sess . opts . incremental . is_none ( ) {
117
+ return true ;
118
+ }
119
+ // When compiling with incremental, we can generate a *lot* of
120
+ // codegen units. Including drop glue into all of them has a
121
+ // considerable compile time cost.
122
+ //
123
+ // We include enums without destructors to allow, say, optimizing
124
+ // drops of `Option::None` before LTO. We also respect the intent of
125
+ // `#[inline]` on `Drop::drop` implementations.
126
+ return ty. ty_adt_def ( )
127
+ . map_or ( true , |adt_def| {
128
+ adt_def. destructor ( tcx)
129
+ . map_or (
130
+ adt_def. is_enum ( ) ,
131
+ |dtor| tcx. codegen_fn_attrs ( dtor. did ) . requests_inline ( ) ,
132
+ )
133
+ } )
116
134
}
117
135
tcx. codegen_fn_attrs ( self . def_id ( ) ) . requests_inline ( )
118
136
}
0 commit comments