@@ -171,22 +171,40 @@ where
171171 }
172172}
173173
174+ enum DtorType {
175+ /// Type has a `Drop` but it is considered insignificant.
176+ /// Check the query `adt_significant_drop_tys` for understanding
177+ /// "significant" / "insignificant".
178+ Insignificant ,
179+
180+ /// Type has a `Drop` implentation.
181+ Significant ,
182+ }
183+
174184// This is a helper function for `adt_drop_tys` and `adt_significant_drop_tys`.
175185// Depending on the implentation of `adt_has_dtor`, it is used to check if the
176186// ADT has a destructor or if the ADT only has a significant destructor. For
177187// understanding significant destructor look at `adt_significant_drop_tys`.
178188fn adt_drop_tys_helper (
179189 tcx : TyCtxt < ' _ > ,
180190 def_id : DefId ,
181- adt_has_dtor : impl Fn ( & ty:: AdtDef ) -> bool ,
191+ adt_has_dtor : impl Fn ( & ty:: AdtDef ) -> Option < DtorType > ,
182192) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
183193 let adt_components = move |adt_def : & ty:: AdtDef | {
184194 if adt_def. is_manually_drop ( ) {
185195 debug ! ( "adt_drop_tys: `{:?}` is manually drop" , adt_def) ;
186196 return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
187- } else if adt_has_dtor ( adt_def) {
188- debug ! ( "adt_drop_tys: `{:?}` implements `Drop`" , adt_def) ;
189- return Err ( AlwaysRequiresDrop ) ;
197+ } else if let Some ( dtor_info) = adt_has_dtor ( adt_def) {
198+ match dtor_info {
199+ DtorType :: Significant => {
200+ debug ! ( "adt_drop_tys: `{:?}` implements `Drop`" , adt_def) ;
201+ return Err ( AlwaysRequiresDrop ) ;
202+ }
203+ DtorType :: Insignificant => {
204+ debug ! ( "adt_drop_tys: `{:?}` drop is insignificant" , adt_def) ;
205+ return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
206+ }
207+ }
190208 } else if adt_def. is_union ( ) {
191209 debug ! ( "adt_drop_tys: `{:?}` is a union" , adt_def) ;
192210 return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
@@ -204,7 +222,10 @@ fn adt_drop_tys_helper(
204222}
205223
206224fn adt_drop_tys ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
207- let adt_has_dtor = |adt_def : & ty:: AdtDef | adt_def. destructor ( tcx) . is_some ( ) ;
225+ // This is for the "needs_drop" query, that considers all `Drop` impls, therefore all dtors are
226+ // significant.
227+ let adt_has_dtor =
228+ |adt_def : & ty:: AdtDef | adt_def. destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
208229 adt_drop_tys_helper ( tcx, def_id, adt_has_dtor)
209230}
210231
@@ -213,10 +234,13 @@ fn adt_significant_drop_tys(
213234 def_id : DefId ,
214235) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
215236 let adt_has_dtor = |adt_def : & ty:: AdtDef | {
216- adt_def
217- . destructor ( tcx)
218- . map ( |dtor| !tcx. has_attr ( dtor. did , sym:: rustc_insignificant_dtor) )
219- . unwrap_or ( false )
237+ adt_def. destructor ( tcx) . map ( |dtor| {
238+ if tcx. has_attr ( dtor. did , sym:: rustc_insignificant_dtor) {
239+ DtorType :: Insignificant
240+ } else {
241+ DtorType :: Significant
242+ }
243+ } )
220244 } ;
221245 adt_drop_tys_helper ( tcx, def_id, adt_has_dtor)
222246}
0 commit comments