@@ -12,14 +12,12 @@ use rustc_span::{sym, DUMMY_SP};
1212type NeedsDropResult < T > = Result < T , AlwaysRequiresDrop > ;
1313
1414fn 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-
1815 // If we don't know a type doesn't need drop, for example if it's a type
1916 // parameter without a `Copy` bound, then we conservatively return that it
2017 // 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 ( ) ;
2321
2422 debug ! ( "needs_drop_raw({:?}) = {:?}" , query, res) ;
2523 res
@@ -29,12 +27,10 @@ fn has_significant_drop_raw<'tcx>(
2927 tcx : TyCtxt < ' tcx > ,
3028 query : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
3129) -> 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 ( ) ;
3834 debug ! ( "has_significant_drop_raw({:?}) = {:?}" , query, res) ;
3935 res
4036}
@@ -145,10 +141,8 @@ where
145141 Ok ( tys) => tys,
146142 } ;
147143 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) ;
152146 queue_type ( self , subst_ty) ;
153147 }
154148 }
@@ -187,23 +181,24 @@ enum DtorType {
187181// Depending on the implentation of `adt_has_dtor`, it is used to check if the
188182// ADT has a destructor or if the ADT only has a significant destructor. For
189183// understanding significant destructor look at `adt_significant_drop_tys`.
190- fn adt_drop_tys_helper < ' tcx > (
184+ fn drop_tys_helper < ' tcx > (
191185 tcx : TyCtxt < ' tcx > ,
192- def_id : DefId ,
186+ ty : Ty < ' tcx > ,
187+ param_env : rustc_middle:: ty:: ParamEnv < ' tcx > ,
193188 adt_has_dtor : impl Fn ( & ty:: AdtDef ) -> Option < DtorType > ,
194- ) -> Result < & ty :: List < Ty < ' tcx > > , AlwaysRequiresDrop > {
189+ ) -> impl Iterator < Item = NeedsDropResult < Ty < ' tcx > > > {
195190 let adt_components = move |adt_def : & ty:: AdtDef , substs : SubstsRef < ' tcx > | {
196191 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) ;
198193 return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
199194 } else if let Some ( dtor_info) = adt_has_dtor ( adt_def) {
200195 match dtor_info {
201196 DtorType :: Significant => {
202- debug ! ( "adt_drop_tys : `{:?}` implements `Drop`" , adt_def) ;
197+ debug ! ( "drop_tys_helper : `{:?}` implements `Drop`" , adt_def) ;
203198 return Err ( AlwaysRequiresDrop ) ;
204199 }
205200 DtorType :: Insignificant => {
206- debug ! ( "adt_drop_tys : `{:?}` drop is insignificant" , adt_def) ;
201+ debug ! ( "drop_tys_helper : `{:?}` drop is insignificant" , adt_def) ;
207202
208203 // Since the destructor is insignificant, we just want to make sure all of
209204 // the passed in type parameters are also insignificant.
@@ -212,34 +207,27 @@ fn adt_drop_tys_helper<'tcx>(
212207 }
213208 }
214209 } 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) ;
216211 return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
217212 }
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 ( ) )
219222 } ;
220223
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)
228225}
229226
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 | {
243231 let is_marked_insig = tcx. has_attr ( adt_def. did , sym:: rustc_insignificant_dtor) ;
244232 if is_marked_insig {
245233 // In some cases like `std::collections::HashMap` where the struct is a wrapper around
@@ -256,8 +244,31 @@ fn adt_significant_drop_tys(
256244 // treat this as the simple case of Drop impl for type.
257245 None
258246 }
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) )
261272}
262273
263274pub ( crate ) fn provide ( providers : & mut ty:: query:: Providers ) {
0 commit comments