@@ -12,14 +12,12 @@ use rustc_span::{sym, DUMMY_SP};
12
12
type NeedsDropResult < T > = Result < T , AlwaysRequiresDrop > ;
13
13
14
14
fn needs_drop_raw < ' tcx > ( tcx : TyCtxt < ' tcx > , query : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ) -> bool {
15
- let adt_components =
16
- move |adt_def : & ty:: AdtDef , _| tcx. adt_drop_tys ( adt_def. did ) . map ( |tys| tys. iter ( ) ) ;
17
-
18
15
// If we don't know a type doesn't need drop, for example if it's a type
19
16
// parameter without a `Copy` bound, then we conservatively return that it
20
17
// needs drop.
21
- let res =
22
- NeedsDropTypes :: new ( tcx, query. param_env , query. value , adt_components) . next ( ) . is_some ( ) ;
18
+ let adt_has_dtor =
19
+ |adt_def : & ty:: AdtDef | adt_def. destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
20
+ let res = drop_tys_helper ( tcx, query. value , query. param_env , adt_has_dtor) . next ( ) . is_some ( ) ;
23
21
24
22
debug ! ( "needs_drop_raw({:?}) = {:?}" , query, res) ;
25
23
res
@@ -29,12 +27,10 @@ fn has_significant_drop_raw<'tcx>(
29
27
tcx : TyCtxt < ' tcx > ,
30
28
query : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
31
29
) -> bool {
32
- let significant_drop_fields = move |adt_def : & ty:: AdtDef , _| {
33
- tcx. adt_significant_drop_tys ( adt_def. did ) . map ( |tys| tys. iter ( ) )
34
- } ;
35
- let res = NeedsDropTypes :: new ( tcx, query. param_env , query. value , significant_drop_fields)
36
- . next ( )
37
- . is_some ( ) ;
30
+ let res =
31
+ drop_tys_helper ( tcx, query. value , query. param_env , adt_consider_insignificant_dtor ( tcx) )
32
+ . next ( )
33
+ . is_some ( ) ;
38
34
debug ! ( "has_significant_drop_raw({:?}) = {:?}" , query, res) ;
39
35
res
40
36
}
@@ -145,10 +141,8 @@ where
145
141
Ok ( tys) => tys,
146
142
} ;
147
143
for required_ty in tys {
148
- let subst_ty = tcx. normalize_erasing_regions (
149
- self . param_env ,
150
- required_ty. subst ( tcx, substs) ,
151
- ) ;
144
+ let subst_ty =
145
+ tcx. normalize_erasing_regions ( self . param_env , required_ty) ;
152
146
queue_type ( self , subst_ty) ;
153
147
}
154
148
}
@@ -187,23 +181,24 @@ enum DtorType {
187
181
// Depending on the implentation of `adt_has_dtor`, it is used to check if the
188
182
// ADT has a destructor or if the ADT only has a significant destructor. For
189
183
// understanding significant destructor look at `adt_significant_drop_tys`.
190
- fn adt_drop_tys_helper < ' tcx > (
184
+ fn drop_tys_helper < ' tcx > (
191
185
tcx : TyCtxt < ' tcx > ,
192
- def_id : DefId ,
186
+ ty : Ty < ' tcx > ,
187
+ param_env : rustc_middle:: ty:: ParamEnv < ' tcx > ,
193
188
adt_has_dtor : impl Fn ( & ty:: AdtDef ) -> Option < DtorType > ,
194
- ) -> Result < & ty :: List < Ty < ' tcx > > , AlwaysRequiresDrop > {
189
+ ) -> impl Iterator < Item = NeedsDropResult < Ty < ' tcx > > > {
195
190
let adt_components = move |adt_def : & ty:: AdtDef , substs : SubstsRef < ' tcx > | {
196
191
if adt_def. is_manually_drop ( ) {
197
- debug ! ( "adt_drop_tys : `{:?}` is manually drop" , adt_def) ;
192
+ debug ! ( "drop_tys_helper : `{:?}` is manually drop" , adt_def) ;
198
193
return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
199
194
} else if let Some ( dtor_info) = adt_has_dtor ( adt_def) {
200
195
match dtor_info {
201
196
DtorType :: Significant => {
202
- debug ! ( "adt_drop_tys : `{:?}` implements `Drop`" , adt_def) ;
197
+ debug ! ( "drop_tys_helper : `{:?}` implements `Drop`" , adt_def) ;
203
198
return Err ( AlwaysRequiresDrop ) ;
204
199
}
205
200
DtorType :: Insignificant => {
206
- debug ! ( "adt_drop_tys : `{:?}` drop is insignificant" , adt_def) ;
201
+ debug ! ( "drop_tys_helper : `{:?}` drop is insignificant" , adt_def) ;
207
202
208
203
// Since the destructor is insignificant, we just want to make sure all of
209
204
// the passed in type parameters are also insignificant.
@@ -212,34 +207,27 @@ fn adt_drop_tys_helper<'tcx>(
212
207
}
213
208
}
214
209
} else if adt_def. is_union ( ) {
215
- debug ! ( "adt_drop_tys : `{:?}` is a union" , adt_def) ;
210
+ debug ! ( "drop_tys_helper : `{:?}` is a union" , adt_def) ;
216
211
return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
217
212
}
218
- Ok ( adt_def. all_fields ( ) . map ( |field| tcx. type_of ( field. did ) ) . collect :: < Vec < _ > > ( ) . into_iter ( ) )
213
+ Ok ( adt_def
214
+ . all_fields ( )
215
+ . map ( |field| {
216
+ let r = tcx. type_of ( field. did ) . subst ( tcx, substs) ;
217
+ debug ! ( "drop_tys_helper: Subst into {:?} with {:?} gettng {:?}" , field, substs, r) ;
218
+ r
219
+ } )
220
+ . collect :: < Vec < _ > > ( )
221
+ . into_iter ( ) )
219
222
} ;
220
223
221
- let adt_ty = tcx. type_of ( def_id) ;
222
- let param_env = tcx. param_env ( def_id) ;
223
- let res: Result < Vec < _ > , _ > =
224
- NeedsDropTypes :: new ( tcx, param_env, adt_ty, adt_components) . collect ( ) ;
225
-
226
- debug ! ( "adt_drop_tys(`{}`) = `{:?}`" , tcx. def_path_str( def_id) , res) ;
227
- res. map ( |components| tcx. intern_type_list ( & components) )
224
+ NeedsDropTypes :: new ( tcx, param_env, ty, adt_components)
228
225
}
229
226
230
- fn adt_drop_tys ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
231
- // This is for the "needs_drop" query, that considers all `Drop` impls, therefore all dtors are
232
- // significant.
233
- let adt_has_dtor =
234
- |adt_def : & ty:: AdtDef | adt_def. destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
235
- adt_drop_tys_helper ( tcx, def_id, adt_has_dtor)
236
- }
237
-
238
- fn adt_significant_drop_tys (
239
- tcx : TyCtxt < ' _ > ,
240
- def_id : DefId ,
241
- ) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
242
- let adt_has_dtor = |adt_def : & ty:: AdtDef | {
227
+ fn adt_consider_insignificant_dtor < ' tcx > (
228
+ tcx : TyCtxt < ' tcx > ,
229
+ ) -> impl Fn ( & ty:: AdtDef ) -> Option < DtorType > + ' tcx {
230
+ move |adt_def : & ty:: AdtDef | {
243
231
let is_marked_insig = tcx. has_attr ( adt_def. did , sym:: rustc_insignificant_dtor) ;
244
232
if is_marked_insig {
245
233
// In some cases like `std::collections::HashMap` where the struct is a wrapper around
@@ -256,8 +244,31 @@ fn adt_significant_drop_tys(
256
244
// treat this as the simple case of Drop impl for type.
257
245
None
258
246
}
259
- } ;
260
- adt_drop_tys_helper ( tcx, def_id, adt_has_dtor)
247
+ }
248
+ }
249
+
250
+ fn adt_drop_tys ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
251
+ // This is for the "adt_drop_tys" query, that considers all `Drop` impls, therefore all dtors are
252
+ // significant.
253
+ let adt_has_dtor =
254
+ |adt_def : & ty:: AdtDef | adt_def. destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
255
+ drop_tys_helper ( tcx, tcx. type_of ( def_id) , tcx. param_env ( def_id) , adt_has_dtor)
256
+ . collect :: < Result < Vec < _ > , _ > > ( )
257
+ . map ( |components| tcx. intern_type_list ( & components) )
258
+ }
259
+
260
+ fn adt_significant_drop_tys (
261
+ tcx : TyCtxt < ' _ > ,
262
+ def_id : DefId ,
263
+ ) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
264
+ drop_tys_helper (
265
+ tcx,
266
+ tcx. type_of ( def_id) ,
267
+ tcx. param_env ( def_id) ,
268
+ adt_consider_insignificant_dtor ( tcx) ,
269
+ )
270
+ . collect :: < Result < Vec < _ > , _ > > ( )
271
+ . map ( |components| tcx. intern_type_list ( & components) )
261
272
}
262
273
263
274
pub ( crate ) fn provide ( providers : & mut ty:: query:: Providers ) {
0 commit comments