Skip to content

Commit edb8d1c

Browse files
committed
Conservatively assume dropping a generator touches its upvars, via locals' dtors.
This is meant to address #49918. Review feedback: put back comment justifying skipping interior traversal. Review feedback: dropck generators like trait objects: all their upvars must outlive the generator itself, so just create a DtorckConstraint saying so.
1 parent 4d7bbdd commit edb8d1c

File tree

1 file changed

+32
-8
lines changed

1 file changed

+32
-8
lines changed

src/librustc_traits/dropck_outlives.rs

+32-8
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)