Teach dropck about resume arguments
This commit is contained in:
parent
aae0f543cf
commit
9fa46fe153
4 changed files with 55 additions and 5 deletions
|
|
@ -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) => {
|
||||
|
|
|
|||
33
src/test/ui/generator/dropck-resume.rs
Normal file
33
src/test/ui/generator/dropck-resume.rs
Normal 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());
|
||||
}
|
||||
15
src/test/ui/generator/dropck-resume.stderr
Normal file
15
src/test/ui/generator/dropck-resume.stderr
Normal 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`.
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue