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