@@ -101,9 +101,6 @@ fn has_significant_drop_raw<'tcx>(
101
101
struct NeedsDropTypes < ' tcx , F > {
102
102
tcx : TyCtxt < ' tcx > ,
103
103
typing_env : ty:: TypingEnv < ' tcx > ,
104
- /// Whether to reveal coroutine witnesses, this is set
105
- /// to `false` unless we compute `needs_drop` for a coroutine witness.
106
- reveal_coroutine_witnesses : bool ,
107
104
query_ty : Ty < ' tcx > ,
108
105
seen_tys : FxHashSet < Ty < ' tcx > > ,
109
106
/// A stack of types left to process, and the recursion depth when we
@@ -115,6 +112,15 @@ struct NeedsDropTypes<'tcx, F> {
115
112
adt_components : F ,
116
113
/// Set this to true if an exhaustive list of types involved in
117
114
/// drop obligation is requested.
115
+ // FIXME: Calling this bool `exhaustive` is confusing and possibly a footgun,
116
+ // since it does two things: It makes the iterator yield *all* of the types
117
+ // that need drop, and it also affects the computation of the drop components
118
+ // on `Coroutine`s. The latter is somewhat confusing, and probably should be
119
+ // a function of `typing_env`. See the HACK comment below for why this is
120
+ // necessary. If this isn't possible, then we probably should turn this into
121
+ // a `NeedsDropMode` so that we can have a variant like `CollectAllSignificantDrops`,
122
+ // which will more accurately indicate that we want *all* of the *significant*
123
+ // drops, which are the two important behavioral changes toggled by this bool.
118
124
exhaustive : bool ,
119
125
}
120
126
@@ -131,7 +137,6 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
131
137
Self {
132
138
tcx,
133
139
typing_env,
134
- reveal_coroutine_witnesses : exhaustive,
135
140
seen_tys,
136
141
query_ty : ty,
137
142
unchecked_tys : vec ! [ ( ty, 0 ) ] ,
@@ -195,23 +200,27 @@ where
195
200
// for the coroutine witness and check whether any of the contained types
196
201
// need to be dropped, and only require the captured types to be live
197
202
// if they do.
198
- ty:: Coroutine ( _, args) => {
199
- if self . reveal_coroutine_witnesses {
200
- queue_type ( self , args. as_coroutine ( ) . witness ( ) ) ;
203
+ ty:: Coroutine ( def_id, args) => {
204
+ // FIXME: See FIXME on `exhaustive` field above.
205
+ if self . exhaustive {
206
+ for upvar in args. as_coroutine ( ) . upvar_tys ( ) {
207
+ queue_type ( self , upvar) ;
208
+ }
209
+ queue_type ( self , args. as_coroutine ( ) . resume_ty ( ) ) ;
210
+ if let Some ( witness) = tcx. mir_coroutine_witnesses ( def_id) {
211
+ for field_ty in & witness. field_tys {
212
+ queue_type (
213
+ self ,
214
+ EarlyBinder :: bind ( field_ty. ty ) . instantiate ( tcx, args) ,
215
+ ) ;
216
+ }
217
+ }
201
218
} else {
202
219
return Some ( self . always_drop_component ( ty) ) ;
203
220
}
204
221
}
205
- ty:: CoroutineWitness ( def_id, args) => {
206
- if let Some ( witness) = tcx. mir_coroutine_witnesses ( def_id) {
207
- self . reveal_coroutine_witnesses = true ;
208
- for field_ty in & witness. field_tys {
209
- queue_type (
210
- self ,
211
- EarlyBinder :: bind ( field_ty. ty ) . instantiate ( tcx, args) ,
212
- ) ;
213
- }
214
- }
222
+ ty:: CoroutineWitness ( ..) => {
223
+ unreachable ! ( "witness should be handled in parent" ) ;
215
224
}
216
225
217
226
ty:: UnsafeBinder ( bound_ty) => {
0 commit comments