]>
Commit | Line | Data |
---|---|---|
9ffffee4 FG |
1 | #![feature(generators)] |
2 | #![feature(generator_clone)] | |
3 | #![feature(generator_trait)] | |
353b0b11 | 4 | #![feature(rustc_attrs, stmt_expr_attributes)] |
9ffffee4 FG |
5 | |
6 | use std::ops::Generator; | |
7 | use std::pin::Pin; | |
8 | ||
9 | fn copy<T: Copy>(x: T) -> T { | |
10 | x | |
11 | } | |
12 | ||
13 | fn main() { | |
14 | let mut g = || { | |
15 | // This is desuraged as 4 stages: | |
16 | // - allocate a `*mut u8` with `exchange_malloc`; | |
17 | // - create a Box that is ignored for trait computations; | |
18 | // - compute fields (and yields); | |
19 | // - assign to `t`. | |
353b0b11 FG |
20 | let t = #[rustc_box] |
21 | Box::new((5, yield)); | |
9ffffee4 FG |
22 | drop(t); |
23 | }; | |
24 | ||
25 | // Allocate the temporary box. | |
26 | Pin::new(&mut g).resume(()); | |
27 | ||
28 | // The temporary box is in generator locals. | |
29 | // As it is not taken into account for trait computation, | |
30 | // the generator is `Copy`. | |
31 | let mut h = copy(g); | |
781aab86 | 32 | //~^ ERROR the trait bound `Box<(i32, ())>: Copy` is not satisfied in |
9ffffee4 FG |
33 | |
34 | // We now have 2 boxes with the same backing allocation: | |
35 | // one inside `g` and one inside `h`. | |
36 | // Proceed and drop `t` in `g`. | |
37 | Pin::new(&mut g).resume(()); | |
781aab86 | 38 | //~^ ERROR borrow of moved value: `g` |
9ffffee4 FG |
39 | |
40 | // Proceed and drop `t` in `h` -> double free! | |
41 | Pin::new(&mut h).resume(()); | |
42 | } |