Skip to content

Commit

Permalink
Conservatively assume dropping a generator touches its upvars, via lo…
Browse files Browse the repository at this point in the history
…cals' 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.
  • Loading branch information
pnkfelix committed May 1, 2018
1 parent 4d7bbdd commit edb8d1c
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions src/librustc_traits/dropck_outlives.rs
Expand Up @@ -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) => {
Expand Down

0 comments on commit edb8d1c

Please sign in to comment.