@@ -101,9 +101,6 @@ fn has_significant_drop_raw<'tcx>(
101101struct NeedsDropTypes < ' tcx , F > {
102102 tcx : TyCtxt < ' tcx > ,
103103 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 ,
107104 query_ty : Ty < ' tcx > ,
108105 seen_tys : FxHashSet < Ty < ' tcx > > ,
109106 /// A stack of types left to process, and the recursion depth when we
@@ -115,6 +112,15 @@ struct NeedsDropTypes<'tcx, F> {
115112 adt_components : F ,
116113 /// Set this to true if an exhaustive list of types involved in
117114 /// 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.
118124 exhaustive : bool ,
119125}
120126
@@ -131,7 +137,6 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
131137 Self {
132138 tcx,
133139 typing_env,
134- reveal_coroutine_witnesses : exhaustive,
135140 seen_tys,
136141 query_ty : ty,
137142 unchecked_tys : vec ! [ ( ty, 0 ) ] ,
@@ -195,23 +200,27 @@ where
195200 // for the coroutine witness and check whether any of the contained types
196201 // need to be dropped, and only require the captured types to be live
197202 // 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+ }
201218 } else {
202219 return Some ( self . always_drop_component ( ty) ) ;
203220 }
204221 }
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" ) ;
215224 }
216225
217226 ty:: UnsafeBinder ( bound_ty) => {
0 commit comments