@@ -171,22 +171,40 @@ where
171
171
}
172
172
}
173
173
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
+
174
184
// This is a helper function for `adt_drop_tys` and `adt_significant_drop_tys`.
175
185
// Depending on the implentation of `adt_has_dtor`, it is used to check if the
176
186
// ADT has a destructor or if the ADT only has a significant destructor. For
177
187
// understanding significant destructor look at `adt_significant_drop_tys`.
178
188
fn adt_drop_tys_helper (
179
189
tcx : TyCtxt < ' _ > ,
180
190
def_id : DefId ,
181
- adt_has_dtor : impl Fn ( & ty:: AdtDef ) -> bool ,
191
+ adt_has_dtor : impl Fn ( & ty:: AdtDef ) -> Option < DtorType > ,
182
192
) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
183
193
let adt_components = move |adt_def : & ty:: AdtDef | {
184
194
if adt_def. is_manually_drop ( ) {
185
195
debug ! ( "adt_drop_tys: `{:?}` is manually drop" , adt_def) ;
186
196
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
+ }
190
208
} else if adt_def. is_union ( ) {
191
209
debug ! ( "adt_drop_tys: `{:?}` is a union" , adt_def) ;
192
210
return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
@@ -204,7 +222,10 @@ fn adt_drop_tys_helper(
204
222
}
205
223
206
224
fn 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 ) ;
208
229
adt_drop_tys_helper ( tcx, def_id, adt_has_dtor)
209
230
}
210
231
@@ -213,10 +234,13 @@ fn adt_significant_drop_tys(
213
234
def_id : DefId ,
214
235
) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
215
236
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
+ } )
220
244
} ;
221
245
adt_drop_tys_helper ( tcx, def_id, adt_has_dtor)
222
246
}
0 commit comments