diff options
Diffstat (limited to 'src/test/ui/span/vec-must-not-hide-type-from-dropck.rs')
-rw-r--r-- | src/test/ui/span/vec-must-not-hide-type-from-dropck.rs | 125 |
1 files changed, 0 insertions, 125 deletions
diff --git a/src/test/ui/span/vec-must-not-hide-type-from-dropck.rs b/src/test/ui/span/vec-must-not-hide-type-from-dropck.rs deleted file mode 100644 index 9bfbfab06..000000000 --- a/src/test/ui/span/vec-must-not-hide-type-from-dropck.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Checking that `Vec<T>` cannot hide lifetimes within `T` when `T` -// implements `Drop` and might access methods of values that have -// since been deallocated. -// -// In this case, the values in question hold (non-zero) unique-ids -// that zero themselves out when dropped, and are wrapped in another -// type with a destructor that asserts that the ids it references are -// indeed non-zero (i.e., effectively checking that the id's are not -// dropped while there are still any outstanding references). -// -// However, the values in question are also formed into a -// cyclic-structure, ensuring that there is no way for all of the -// conditions above to be satisfied, meaning that if the dropck is -// sound, it should reject this code. - - - -use std::cell::Cell; -use id::Id; - -mod s { - use std::sync::atomic::{AtomicUsize, Ordering}; - - static S_COUNT: AtomicUsize = AtomicUsize::new(0); - - /// generates globally unique count (global across the current - /// process, that is) - pub fn next_count() -> usize { - S_COUNT.fetch_add(1, Ordering::SeqCst) + 1 - } -} - -mod id { - use s; - - /// Id represents a globally unique identifier (global across the - /// current process, that is). When dropped, it automatically - /// clears its `count` field, but leaves `orig_count` untouched, - /// so that if there are subsequent (erroneous) invocations of its - /// method (which is unsound), we can observe it by seeing that - /// the `count` is 0 while the `orig_count` is non-zero. - #[derive(Debug)] - pub struct Id { - orig_count: usize, - count: usize, - } - - impl Id { - /// Creates an `Id` with a globally unique count. - pub fn new() -> Id { - let c = s::next_count(); - println!("building Id {}", c); - Id { orig_count: c, count: c } - } - /// returns the `count` of self; should be non-zero if - /// everything is working. - pub fn count(&self) -> usize { - println!("Id::count on {} returns {}", self.orig_count, self.count); - self.count - } - } - - impl Drop for Id { - fn drop(&mut self) { - println!("dropping Id {}", self.count); - self.count = 0; - } - } -} - -trait HasId { - fn count(&self) -> usize; -} - -#[derive(Debug)] -struct CheckId<T:HasId> { - v: T -} - -#[allow(non_snake_case)] -fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } } - -impl<T:HasId> Drop for CheckId<T> { - fn drop(&mut self) { - assert!(self.v.count() > 0); - } -} - -#[derive(Debug)] -struct C<'a> { - id: Id, - v: Vec<CheckId<Cell<Option<&'a C<'a>>>>>, -} - -impl<'a> HasId for Cell<Option<&'a C<'a>>> { - fn count(&self) -> usize { - match self.get() { - None => 1, - Some(c) => c.id.count(), - } - } -} - -impl<'a> C<'a> { - fn new() -> C<'a> { - C { id: Id::new(), v: Vec::new() } - } -} - -fn f() { - let (mut c1, mut c2); - c1 = C::new(); - c2 = C::new(); - - c1.v.push(CheckId(Cell::new(None))); - c2.v.push(CheckId(Cell::new(None))); - c1.v[0].v.set(Some(&c2)); - //~^ ERROR `c2` does not live long enough - c2.v[0].v.set(Some(&c1)); - //~^ ERROR `c1` does not live long enough -} - -fn main() { - f(); -} |