diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2018-04-13 17:11:53 +0200 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2018-05-01 22:28:54 +0200 |
| commit | edb8d1c0d4b2e32088f3c6a77437b091b10ddf7e (patch) | |
| tree | 004215cfb42495e6a8e8fea5ff93889140f90d50 | |
| parent | 4d7bbdd82682b0c4891538b241f7fe584f148710 (diff) | |
| download | rust-edb8d1c0d4b2e32088f3c6a77437b091b10ddf7e.tar.gz rust-edb8d1c0d4b2e32088f3c6a77437b091b10ddf7e.zip | |
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.
| -rw-r--r-- | src/librustc_traits/dropck_outlives.rs | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 5f4daf0d568..ba31ce2692f 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -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) => { |
