]> git.lizzy.rs Git - rust.git/blob - tests/ui-fulldeps/dropck-tarena-cycle-checked.rs
make more readable
[rust.git] / tests / ui-fulldeps / dropck-tarena-cycle-checked.rs
1 // Reject mixing cyclic structure and Drop when using TypedArena.
2 //
3 // (Compare against dropck-vec-cycle-checked.rs)
4 //
5 // (Also compare against ui-fulldeps/dropck-tarena-unsound-drop.rs,
6 //  which is a reduction of this code to more directly show the reason
7 //  for the error message we see here.)
8
9 #![feature(rustc_private)]
10
11 extern crate rustc_arena;
12
13 use rustc_arena::TypedArena;
14 use std::cell::Cell;
15 use id::Id;
16
17 mod s {
18     use std::sync::atomic::{AtomicUsize, Ordering};
19
20     static S_COUNT: AtomicUsize = AtomicUsize::new(0);
21
22     pub fn next_count() -> usize {
23         S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
24     }
25 }
26
27 mod id {
28     use s;
29     #[derive(Debug)]
30     pub struct Id {
31         orig_count: usize,
32         count: usize,
33     }
34
35     impl Id {
36         pub fn new() -> Id {
37             let c = s::next_count();
38             println!("building Id {}", c);
39             Id { orig_count: c, count: c }
40         }
41         pub fn count(&self) -> usize {
42             println!("Id::count on {} returns {}", self.orig_count, self.count);
43             self.count
44         }
45     }
46
47     impl Drop for Id {
48         fn drop(&mut self) {
49             println!("dropping Id {}", self.count);
50             self.count = 0;
51         }
52     }
53 }
54
55 trait HasId {
56     fn count(&self) -> usize;
57 }
58
59 #[derive(Debug)]
60 struct CheckId<T:HasId> {
61     v: T
62 }
63
64 #[allow(non_snake_case)]
65 fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
66
67 impl<T:HasId> Drop for CheckId<T> {
68     fn drop(&mut self) {
69         assert!(self.v.count() > 0);
70     }
71 }
72
73 #[derive(Debug)]
74 struct C<'a> {
75     id: Id,
76     v: Vec<CheckId<Cell<Option<&'a C<'a>>>>>,
77 }
78
79 impl<'a> HasId for Cell<Option<&'a C<'a>>> {
80     fn count(&self) -> usize {
81         match self.get() {
82             None => 1,
83             Some(c) => c.id.count(),
84         }
85     }
86 }
87
88 impl<'a> C<'a> {
89     fn new() -> C<'a> {
90         C { id: Id::new(), v: Vec::new() }
91     }
92 }
93
94 fn f<'a>(arena: &'a TypedArena<C<'a>>) {
95     let c1 = arena.alloc(C::new());
96     let c2 = arena.alloc(C::new());
97     let c3 = arena.alloc(C::new());
98
99     c1.v.push(CheckId(Cell::new(None)));
100     c1.v.push(CheckId(Cell::new(None)));
101     c2.v.push(CheckId(Cell::new(None)));
102     c2.v.push(CheckId(Cell::new(None)));
103     c3.v.push(CheckId(Cell::new(None)));
104     c3.v.push(CheckId(Cell::new(None)));
105
106     c1.v[0].v.set(Some(c2));
107     c1.v[1].v.set(Some(c3));
108     c2.v[0].v.set(Some(c2));
109     c2.v[1].v.set(Some(c3));
110     c3.v[0].v.set(Some(c1));
111     c3.v[1].v.set(Some(c2));
112 }
113
114 fn main() {
115     let arena = TypedArena::default();
116     f(&arena);
117 } //~^ ERROR `arena` does not live long enough