3
3
use rustc_data_structures:: fx:: FxHashSet ;
4
4
use rustc_hir:: def_id:: DefId ;
5
5
use rustc_middle:: ty:: subst:: Subst ;
6
+ use rustc_middle:: ty:: subst:: SubstsRef ;
6
7
use rustc_middle:: ty:: util:: { needs_drop_components, AlwaysRequiresDrop } ;
7
8
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
8
9
use rustc_session:: Limit ;
@@ -12,7 +13,7 @@ type NeedsDropResult<T> = Result<T, AlwaysRequiresDrop>;
12
13
13
14
fn needs_drop_raw < ' tcx > ( tcx : TyCtxt < ' tcx > , query : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ) -> bool {
14
15
let adt_components =
15
- move |adt_def : & ty:: AdtDef | tcx. adt_drop_tys ( adt_def. did ) . map ( |tys| tys. iter ( ) ) ;
16
+ move |adt_def : & ty:: AdtDef , _ | tcx. adt_drop_tys ( adt_def. did ) . map ( |tys| tys. iter ( ) ) ;
16
17
17
18
// If we don't know a type doesn't need drop, for example if it's a type
18
19
// parameter without a `Copy` bound, then we conservatively return that it
@@ -28,8 +29,9 @@ fn has_significant_drop_raw<'tcx>(
28
29
tcx : TyCtxt < ' tcx > ,
29
30
query : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
30
31
) -> bool {
31
- let significant_drop_fields =
32
- move |adt_def : & ty:: AdtDef | tcx. adt_significant_drop_tys ( adt_def. did ) . map ( |tys| tys. iter ( ) ) ;
32
+ let significant_drop_fields = move |adt_def : & ty:: AdtDef , _| {
33
+ tcx. adt_significant_drop_tys ( adt_def. did ) . map ( |tys| tys. iter ( ) )
34
+ } ;
33
35
let res = NeedsDropTypes :: new ( tcx, query. param_env , query. value , significant_drop_fields)
34
36
. next ( )
35
37
. is_some ( ) ;
@@ -74,7 +76,7 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
74
76
75
77
impl < ' tcx , F , I > Iterator for NeedsDropTypes < ' tcx , F >
76
78
where
77
- F : Fn ( & ty:: AdtDef ) -> NeedsDropResult < I > ,
79
+ F : Fn ( & ty:: AdtDef , SubstsRef < ' tcx > ) -> NeedsDropResult < I > ,
78
80
I : Iterator < Item = Ty < ' tcx > > ,
79
81
{
80
82
type Item = NeedsDropResult < Ty < ' tcx > > ;
@@ -138,7 +140,7 @@ where
138
140
// `ManuallyDrop`. If it's a struct or enum without a `Drop`
139
141
// impl then check whether the field types need `Drop`.
140
142
ty:: Adt ( adt_def, substs) => {
141
- let tys = match ( self . adt_components ) ( adt_def) {
143
+ let tys = match ( self . adt_components ) ( adt_def, substs ) {
142
144
Err ( e) => return Some ( Err ( e) ) ,
143
145
Ok ( tys) => tys,
144
146
} ;
@@ -185,12 +187,12 @@ enum DtorType {
185
187
// Depending on the implentation of `adt_has_dtor`, it is used to check if the
186
188
// ADT has a destructor or if the ADT only has a significant destructor. For
187
189
// understanding significant destructor look at `adt_significant_drop_tys`.
188
- fn adt_drop_tys_helper (
189
- tcx : TyCtxt < ' _ > ,
190
+ fn adt_drop_tys_helper < ' tcx > (
191
+ tcx : TyCtxt < ' tcx > ,
190
192
def_id : DefId ,
191
193
adt_has_dtor : impl Fn ( & ty:: AdtDef ) -> Option < DtorType > ,
192
- ) -> Result < & ty:: List < Ty < ' _ > > , AlwaysRequiresDrop > {
193
- let adt_components = move |adt_def : & ty:: AdtDef | {
194
+ ) -> Result < & ty:: List < Ty < ' tcx > > , AlwaysRequiresDrop > {
195
+ let adt_components = move |adt_def : & ty:: AdtDef , substs : SubstsRef < ' tcx > | {
194
196
if adt_def. is_manually_drop ( ) {
195
197
debug ! ( "adt_drop_tys: `{:?}` is manually drop" , adt_def) ;
196
198
return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
@@ -202,7 +204,11 @@ fn adt_drop_tys_helper(
202
204
}
203
205
DtorType :: Insignificant => {
204
206
debug ! ( "adt_drop_tys: `{:?}` drop is insignificant" , adt_def) ;
205
- return Ok ( Vec :: new ( ) . into_iter ( ) ) ;
207
+
208
+ // Since the destructor is insignificant, we just want to make sure all of
209
+ // the passed in type parameters are also insignificant.
210
+ // Eg: Vec<T> dtor is insignificant when T=i32 but significant when T=Mutex.
211
+ return Ok ( substs. types ( ) . collect :: < Vec < Ty < ' _ > > > ( ) . into_iter ( ) ) ;
206
212
}
207
213
}
208
214
} else if adt_def. is_union ( ) {
0 commit comments