@@ -54,7 +54,10 @@ pub enum InstanceDef<'tcx> {
54
54
call_once : DefId ,
55
55
} ,
56
56
57
- /// `drop_in_place::<T>; None` for empty drop glue.
57
+ /// `core::ptr::drop_in_place::<T>`.
58
+ /// The `DefId` is for `core::ptr::drop_in_place`.
59
+ /// The `Option<Ty<'tcx>>` is either `Some(T)`, or `None` for empty drop
60
+ /// glue.
58
61
DropGlue ( DefId , Option < Ty < ' tcx > > ) ,
59
62
60
63
///`<T as Clone>::clone` shim.
@@ -177,11 +180,25 @@ impl<'tcx> InstanceDef<'tcx> {
177
180
if self . requires_inline ( tcx) {
178
181
return true ;
179
182
}
180
- if let ty:: InstanceDef :: DropGlue ( ..) = * self {
181
- // Drop glue wants to be instantiated at every codegen
183
+ if let ty:: InstanceDef :: DropGlue ( .., Some ( ty ) ) = * self {
184
+ // Drop glue generally wants to be instantiated at every codegen
182
185
// unit, but without an #[inline] hint. We should make this
183
186
// available to normal end-users.
184
- return true ;
187
+ if tcx. sess . opts . incremental . is_none ( ) {
188
+ return true ;
189
+ }
190
+ // When compiling with incremental, we can generate a *lot* of
191
+ // codegen units. Including drop glue into all of them has a
192
+ // considerable compile time cost.
193
+ //
194
+ // We include enums without destructors to allow, say, optimizing
195
+ // drops of `Option::None` before LTO. We also respect the intent of
196
+ // `#[inline]` on `Drop::drop` implementations.
197
+ return ty. ty_adt_def ( ) . map_or ( true , |adt_def| {
198
+ adt_def. destructor ( tcx) . map_or ( adt_def. is_enum ( ) , |dtor| {
199
+ tcx. codegen_fn_attrs ( dtor. did ) . requests_inline ( )
200
+ } )
201
+ } ) ;
185
202
}
186
203
tcx. codegen_fn_attrs ( self . def_id ( ) ) . requests_inline ( )
187
204
}
0 commit comments