diff options
Diffstat (limited to 'tests/ui-fulldeps/dropck_tarena_sound_drop.rs')
-rw-r--r-- | tests/ui-fulldeps/dropck_tarena_sound_drop.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/tests/ui-fulldeps/dropck_tarena_sound_drop.rs b/tests/ui-fulldeps/dropck_tarena_sound_drop.rs new file mode 100644 index 000000000..ffad80171 --- /dev/null +++ b/tests/ui-fulldeps/dropck_tarena_sound_drop.rs @@ -0,0 +1,48 @@ +// run-pass + +#![allow(unknown_lints)] +// Check that an arena (TypedArena) can carry elements whose drop +// methods might access borrowed data, as long as the borrowed data +// has lifetime that strictly outlives the arena itself. +// +// Compare against ui-fulldeps/dropck-tarena-unsound-drop.rs, which +// shows a similar setup, but restricts `f` so that the struct `C<'a>` +// is force-fed a lifetime equal to that of the borrowed arena. + +#![allow(unstable)] +#![feature(rustc_private)] + +extern crate rustc_arena; + +// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta +// files. +#[allow(unused_extern_crates)] +extern crate rustc_driver; + +use rustc_arena::TypedArena; + +trait HasId { fn count(&self) -> usize; } + +struct CheckId<T:HasId> { v: T } + +// In the code below, the impl of HasId for `&'a usize` does not +// actually access the borrowed data, but the point is that the +// interface to CheckId does not (and cannot) know that, and therefore +// when encountering a value V of type CheckId<S>, we must +// conservatively force the type S to strictly outlive V. +impl<T:HasId> Drop for CheckId<T> { + fn drop(&mut self) { + assert!(self.v.count() > 0); + } +} + +struct C<'a> { _v: CheckId<&'a usize>, } + +impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } } + +fn f<'a, 'b>(_arena: &'a TypedArena<C<'b>>) {} + +fn main() { + let arena: TypedArena<C> = TypedArena::default(); + f(&arena); +} |