@@ -52,7 +52,8 @@ pub enum InstanceDef<'tcx> {
5252 /// `<[mut closure] as FnOnce>::call_once`
5353 ClosureOnceShim { call_once : DefId } ,
5454
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`.
5657 DropGlue ( DefId , Option < Ty < ' tcx > > ) ,
5758
5859 ///`<T as Clone>::clone` shim.
@@ -108,11 +109,28 @@ impl<'tcx> InstanceDef<'tcx> {
108109 if self . is_inline ( tcx) {
109110 return true
110111 }
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
113114 // unit, but without an #[inline] hint. We should make this
114115 // 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+ } )
116134 }
117135 tcx. codegen_fn_attrs ( self . def_id ( ) ) . requests_inline ( )
118136 }
0 commit comments