@@ -193,14 +193,38 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>(
193193 . map ( |ty| dtorck_constraint_for_ty ( tcx, span, for_ty, depth + 1 , ty) )
194194 . collect ( ) ,
195195
196- ty:: TyGenerator ( def_id, substs, _) => {
197- // Note that the interior types are ignored here.
198- // Any type reachable inside the interior must also be reachable
199- // through the upvars.
200- substs
201- . upvar_tys ( def_id, tcx)
202- . map ( |ty| dtorck_constraint_for_ty ( tcx, span, for_ty, depth + 1 , ty) )
203- . collect ( )
196+ ty:: TyGenerator ( def_id, substs, _interior) => {
197+ // rust-lang/rust#49918: types can be constructed, stored
198+ // in the interior, and sit idle when generator yields
199+ // (and is subsequently dropped).
200+ //
201+ // It would be nice to descend into interior of a
202+ // generator to determine what effects dropping it might
203+ // have (by looking at any drop effects associated with
204+ // its interior).
205+ //
206+ // However, the interior's representation uses things like
207+ // TyGeneratorWitness that explicitly assume they are not
208+ // traversed in such a manner. So instead, we will
209+ // simplify things for now by treating all generators as
210+ // if they were like trait objects, where its upvars must
211+ // all be alive for the generator's (potential)
212+ // destructor.
213+ //
214+ // In particular, skipping over `_interior` is safe
215+ // because any side-effects from dropping `_interior` can
216+ // only take place through references with lifetimes
217+ // derived from lifetimes attached to the upvars, and we
218+ // *do* incorporate the upvars here.
219+
220+ let constraint = DtorckConstraint {
221+ outlives : substs. upvar_tys ( def_id, tcx) . map ( |t| t. into ( ) ) . collect ( ) ,
222+ dtorck_types : vec ! [ ] ,
223+ overflows : vec ! [ ] ,
224+ } ;
225+ debug ! ( "dtorck_constraint: generator {:?} => {:?}" , def_id, constraint) ;
226+
227+ Ok ( constraint)
204228 }
205229
206230 ty:: TyAdt ( def, substs) => {
0 commit comments