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