@@ -54,7 +54,10 @@ pub enum InstanceDef<'tcx> {
5454 call_once : DefId ,
5555 } ,
5656
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.
5861 DropGlue ( DefId , Option < Ty < ' tcx > > ) ,
5962
6063 ///`<T as Clone>::clone` shim.
@@ -177,11 +180,25 @@ impl<'tcx> InstanceDef<'tcx> {
177180 if self . requires_inline ( tcx) {
178181 return true ;
179182 }
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
182185 // unit, but without an #[inline] hint. We should make this
183186 // 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+ } ) ;
185202 }
186203 tcx. codegen_fn_attrs ( self . def_id ( ) ) . requests_inline ( )
187204 }
0 commit comments