]> git.proxmox.com Git - rustc.git/blame - tests/ui-fulldeps/dropck-tarena-cycle-checked.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / tests / ui-fulldeps / dropck-tarena-cycle-checked.rs
CommitLineData
85aaf69f
SL
1// Reject mixing cyclic structure and Drop when using TypedArena.
2//
5869c6ff 3// (Compare against dropck-vec-cycle-checked.rs)
85aaf69f 4//
5869c6ff 5// (Also compare against ui-fulldeps/dropck-tarena-unsound-drop.rs,
85aaf69f
SL
6// which is a reduction of this code to more directly show the reason
7// for the error message we see here.)
8
ea8adc8c 9#![feature(rustc_private)]
85aaf69f 10
f035d41b 11extern crate rustc_arena;
85aaf69f 12
f035d41b 13use rustc_arena::TypedArena;
85aaf69f
SL
14use std::cell::Cell;
15use id::Id;
16
17mod s {
62682a34 18 use std::sync::atomic::{AtomicUsize, Ordering};
85aaf69f 19
62682a34 20 static S_COUNT: AtomicUsize = AtomicUsize::new(0);
85aaf69f
SL
21
22 pub fn next_count() -> usize {
23 S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
24 }
25}
26
27mod 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
55trait HasId {
56 fn count(&self) -> usize;
57}
58
59#[derive(Debug)]
60struct CheckId<T:HasId> {
61 v: T
62}
63
64#[allow(non_snake_case)]
65fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
66
85aaf69f
SL
67impl<T:HasId> Drop for CheckId<T> {
68 fn drop(&mut self) {
69 assert!(self.v.count() > 0);
70 }
71}
72
73#[derive(Debug)]
74struct C<'a> {
75 id: Id,
76 v: Vec<CheckId<Cell<Option<&'a C<'a>>>>>,
77}
78
79impl<'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
88impl<'a> C<'a> {
89 fn new() -> C<'a> {
90 C { id: Id::new(), v: Vec::new() }
91 }
92}
93
94fn 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
114fn main() {
0bf4aa26 115 let arena = TypedArena::default();
c30ab7b3 116 f(&arena);
ff7c6d11 117} //~^ ERROR `arena` does not live long enough