@@ -19,13 +19,32 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>
1919 // needs drop.
2020 let adt_has_dtor =
2121 |adt_def : ty:: AdtDef < ' tcx > | adt_def. destructor ( tcx) . map ( |_| DtorType :: Significant ) ;
22- let res =
23- drop_tys_helper ( tcx, query. value , query. param_env , adt_has_dtor, false ) . next ( ) . is_some ( ) ;
22+ let res = drop_tys_helper ( tcx, query. value , query. param_env , adt_has_dtor, false )
23+ . filter ( filter_array_elements ( tcx, query. param_env ) )
24+ . next ( )
25+ . is_some ( ) ;
2426
2527 debug ! ( "needs_drop_raw({:?}) = {:?}" , query, res) ;
2628 res
2729}
2830
31+ /// HACK: in order to not mistakenly assume that `[PhantomData<T>; N]` requires drop glue
32+ /// we check the element type for drop glue. The correct fix would be looking at the
33+ /// entirety of the code around `needs_drop_components` and this file and come up with
34+ /// logic that is easier to follow while not repeating any checks that may thus diverge.
35+ fn filter_array_elements < ' tcx > (
36+ tcx : TyCtxt < ' tcx > ,
37+ param_env : ty:: ParamEnv < ' tcx > ,
38+ ) -> impl Fn ( & Result < Ty < ' tcx > , AlwaysRequiresDrop > ) -> bool {
39+ move |ty| match ty {
40+ Ok ( ty) => match * ty. kind ( ) {
41+ ty:: Array ( elem, _) => tcx. needs_drop_raw ( param_env. and ( elem) ) ,
42+ _ => true ,
43+ } ,
44+ Err ( AlwaysRequiresDrop ) => true ,
45+ }
46+ }
47+
2948fn has_significant_drop_raw < ' tcx > (
3049 tcx : TyCtxt < ' tcx > ,
3150 query : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
@@ -37,6 +56,7 @@ fn has_significant_drop_raw<'tcx>(
3756 adt_consider_insignificant_dtor ( tcx) ,
3857 true ,
3958 )
59+ . filter ( filter_array_elements ( tcx, query. param_env ) )
4060 . next ( )
4161 . is_some ( ) ;
4262 debug ! ( "has_significant_drop_raw({:?}) = {:?}" , query, res) ;
0 commit comments