@@ -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}
@@ -140,15 +136,14 @@ where
140136 // `ManuallyDrop`. If it's a struct or enum without a `Drop`
141137 // impl then check whether the field types need `Drop`.
142138 ty:: Adt ( adt_def, substs) => {
139+ debug ! ( "Got value {:?} with substs {:?}" , adt_def, substs) ;
143140 let tys = match ( self . adt_components ) ( adt_def, substs) {
144141 Err ( e) => return Some ( Err ( e) ) ,
145142 Ok ( tys) => tys,
146143 } ;
147144 for required_ty in tys {
148- let subst_ty = tcx. normalize_erasing_regions (
149- self . param_env ,
150- required_ty. subst ( tcx, substs) ,
151- ) ;
145+ let subst_ty =
146+ tcx. normalize_erasing_regions ( self . param_env , required_ty) ;
152147 queue_type ( self , subst_ty) ;
153148 }
154149 }
@@ -187,11 +182,12 @@ enum DtorType {
187182// Depending on the implentation of `adt_has_dtor`, it is used to check if the
188183// ADT has a destructor or if the ADT only has a significant destructor. For
189184// understanding significant destructor look at `adt_significant_drop_tys`.
190- fn adt_drop_tys_helper < ' tcx > (
185+ fn drop_tys_helper < ' tcx > (
191186 tcx : TyCtxt < ' tcx > ,
192- def_id : DefId ,
187+ ty : Ty < ' tcx > ,
188+ param_env : rustc_middle:: ty:: ParamEnv < ' tcx > ,
193189 adt_has_dtor : impl Fn ( & ty:: AdtDef ) -> Option < DtorType > ,
194- ) -> Result < & ty :: List < Ty < ' tcx > > , AlwaysRequiresDrop > {
190+ ) -> impl Iterator < Item = NeedsDropResult < Ty < ' tcx > > > {
195191 let adt_components = move |adt_def : & ty:: AdtDef , substs : SubstsRef < ' tcx > | {
196192 if adt_def. is_manually_drop ( ) {
197193 debug ! ( "adt_drop_tys: `{:?}` is manually drop" , adt_def) ;
@@ -215,31 +211,25 @@ fn adt_drop_tys_helper<'tcx>(
215211 debug ! ( "adt_drop_tys: `{:?}` is a union" , adt_def) ;
216212 return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
217213 }
218- Ok ( adt_def. all_fields ( ) . map ( |field| tcx. type_of ( field. did ) ) . collect :: < Vec < _ > > ( ) . into_iter ( ) )
214+ debug ! ( "Path" ) ;
215+ Ok ( adt_def
216+ . all_fields ( )
217+ . map ( |field| {
218+ let r = tcx. type_of ( field. did ) . subst ( tcx, substs) ;
219+ debug ! ( "Subst into {:?} with {:?} gettng {:?}" , field, substs, r) ;
220+ r
221+ } )
222+ . collect :: < Vec < _ > > ( )
223+ . into_iter ( ) )
219224 } ;
220225
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) )
226+ NeedsDropTypes :: new ( tcx, param_env, ty, adt_components)
228227}
229228
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 | {
229+ fn adt_consider_insignificant_dtor < ' tcx > (
230+ tcx : TyCtxt < ' tcx > ,
231+ ) -> impl Fn ( & ty:: AdtDef ) -> Option < DtorType > + ' tcx {
232+ move |adt_def : & ty:: AdtDef | {
243233 let is_marked_insig = tcx. has_attr ( adt_def. did , sym:: rustc_insignificant_dtor) ;
244234 if is_marked_insig {
245235 // In some cases like `std::collections::HashMap` where the struct is a wrapper around
@@ -256,8 +246,31 @@ fn adt_significant_drop_tys(
256246 // treat this as the simple case of Drop impl for type.
257247 None
258248 }
259- } ;
260- adt_drop_tys_helper ( tcx, def_id, adt_has_dtor)
249+ }
250+ }
251+
252+ fn adt_drop_tys ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
253+ // This is for the "adt_drop_tys" query, that considers all `Drop` impls, therefore all dtors are
254+ // significant.
255+ let adt_has_dtor =
256+ |adt_def : & ty:: AdtDef | adt_def. destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
257+ drop_tys_helper ( tcx, tcx. type_of ( def_id) , tcx. param_env ( def_id) , adt_has_dtor)
258+ . collect :: < Result < Vec < _ > , _ > > ( )
259+ . map ( |components| tcx. intern_type_list ( & components) )
260+ }
261+
262+ fn adt_significant_drop_tys (
263+ tcx : TyCtxt < ' _ > ,
264+ def_id : DefId ,
265+ ) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
266+ drop_tys_helper (
267+ tcx,
268+ tcx. type_of ( def_id) ,
269+ tcx. param_env ( def_id) ,
270+ adt_consider_insignificant_dtor ( tcx) ,
271+ )
272+ . collect :: < Result < Vec < _ > , _ > > ( )
273+ . map ( |components| tcx. intern_type_list ( & components) )
261274}
262275
263276pub ( crate ) fn provide ( providers : & mut ty:: query:: Providers ) {
0 commit comments