Teach dropck about resume arguments

This commit is contained in:
Jonas Schievink 2020-01-27 23:26:37 +01:00
parent aae0f543cf
commit 9fa46fe153
4 changed files with 55 additions and 5 deletions

View file

@ -227,8 +227,8 @@ fn dtorck_constraint_for_ty<'tcx>(
// 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.
// derived from lifetimes attached to the upvars and resume
// argument, and we *do* incorporate those here.
constraints.outlives.extend(
substs
@ -236,6 +236,7 @@ fn dtorck_constraint_for_ty<'tcx>(
.upvar_tys(def_id, tcx)
.map(|t| -> ty::subst::GenericArg<'tcx> { t.into() }),
);
constraints.outlives.push(substs.as_generator().resume_ty(def_id, tcx).into());
}
ty::Adt(def, substs) => {

View file

@ -0,0 +1,33 @@
#![feature(generators, generator_trait)]
use std::ops::{Generator, GeneratorState};
use std::pin::Pin;
struct SetToNone<'a: 'b, 'b>(&'b mut Option<&'a i32>);
impl<'a, 'b> Drop for SetToNone<'a, 'b> {
fn drop(&mut self) {
*self.0 = None;
}
}
fn drop_using_generator() -> i32 {
let mut y = Some(&0);
let z = &mut y;
let r;
{
let mut g = move |r| {
let _s = SetToNone(r);
yield;
};
let mut g = Pin::new(&mut g);
g.as_mut().resume(z);
r = y.as_ref().unwrap();
//~^ ERROR cannot borrow `y` as immutable because it is also borrowed as mutable
}
**r
}
fn main() {
println!("{}", drop_using_generator());
}

View file

@ -0,0 +1,15 @@
error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
--> $DIR/dropck-resume.rs:25:13
|
LL | let z = &mut y;
| ------ mutable borrow occurs here
...
LL | r = y.as_ref().unwrap();
| ^ immutable borrow occurs here
LL |
LL | }
| - mutable borrow might be used here, when `g` is dropped and runs the destructor for generator
error: aborting due to previous error
For more information about this error, try `rustc --explain E0502`.

View file

@ -4,9 +4,10 @@ error[E0499]: cannot borrow `thing` as mutable more than once at a time
LL | gen.as_mut().resume(&mut thing);
| ---------- first mutable borrow occurs here
LL | gen.as_mut().resume(&mut thing);
| ------ ^^^^^^^^^^ second mutable borrow occurs here
| |
| first borrow later used by call
| ^^^^^^^^^^ second mutable borrow occurs here
LL |
LL | }
| - first borrow might be used here, when `gen` is dropped and runs the destructor for generator
error: aborting due to previous error