]>
Commit | Line | Data |
---|---|---|
b039eaaf | 1 | // Check that an arena (TypedArena) cannot carry elements whose drop |
85aaf69f SL |
2 | // methods might access borrowed data of lifetime that does not |
3 | // strictly outlive the arena itself. | |
4 | // | |
5 | // Compare against run-pass/dropck_tarena_sound_drop.rs, which shows a | |
6 | // similar setup, but loosens `f` so that the struct `C<'a>` can be | |
7 | // fed a lifetime longer than that of the arena. | |
8 | // | |
9 | // (Also compare against dropck_tarena_cycle_checked.rs, from which | |
10 | // this was reduced to better understand its error message.) | |
11 | ||
476ff2be SL |
12 | #![feature(rustc_private)] |
13 | ||
85aaf69f SL |
14 | extern crate arena; |
15 | ||
16 | use arena::TypedArena; | |
17 | ||
18 | trait HasId { fn count(&self) -> usize; } | |
19 | ||
20 | struct CheckId<T:HasId> { v: T } | |
21 | ||
22 | // In the code below, the impl of HasId for `&'a usize` does not | |
23 | // actually access the borrowed data, but the point is that the | |
24 | // interface to CheckId does not (and cannot) know that, and therefore | |
b039eaaf | 25 | // when encountering a value V of type CheckId<S>, we must |
85aaf69f | 26 | // conservatively force the type S to strictly outlive V. |
85aaf69f SL |
27 | impl<T:HasId> Drop for CheckId<T> { |
28 | fn drop(&mut self) { | |
29 | assert!(self.v.count() > 0); | |
30 | } | |
31 | } | |
32 | ||
33 | struct C<'a> { v: CheckId<&'a usize>, } | |
34 | ||
35 | impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } } | |
36 | ||
37 | fn f<'a>(_arena: &'a TypedArena<C<'a>>) {} | |
38 | ||
39 | fn main() { | |
0bf4aa26 | 40 | let arena: TypedArena<C> = TypedArena::default(); |
c30ab7b3 | 41 | f(&arena); |
ff7c6d11 | 42 | } //~^ ERROR `arena` does not live long enough |
c30ab7b3 | 43 |