Conservatively assume dropping a generator touches its upvars, via locals' dtors.

This is meant to address rust-lang/rust#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.
This commit is contained in:
Felix S. Klock II 2018-04-13 17:11:53 +02:00
parent 4d7bbdd826
commit edb8d1c0d4

View File

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