1 // Reject mixing cyclic structure and Drop when using trait
2 // objects to hide the cross-references.
4 // (Compare against ui/span/dropck_vec_cycle_checked.rs)
10 use std::sync::atomic::{AtomicUsize, Ordering};
12 static S_COUNT: AtomicUsize = AtomicUsize::new(0);
14 pub fn next_count() -> usize {
15 S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
29 let c = s::next_count();
30 println!("building Id {}", c);
31 Id { orig_count: c, count: c }
33 pub fn count(&self) -> usize {
34 println!("Id::count on {} returns {}", self.orig_count, self.count);
41 println!("dropping Id {}", self.count);
48 fn count(&self) -> usize;
52 struct CheckId<T:HasId> {
56 #[allow(non_snake_case)]
57 fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
59 impl<T:HasId> Drop for CheckId<T> {
61 assert!(self.v.count() > 0);
65 trait Obj<'a> : HasId {
66 fn set0(&self, b: &'a Box<dyn Obj<'a>>);
67 fn set1(&self, b: &'a Box<dyn Obj<'a>>);
72 obj0: CheckId<Cell<Option<&'a Box<dyn Obj<'a>>>>>,
73 obj1: CheckId<Cell<Option<&'a Box<dyn Obj<'a>>>>>,
76 impl<'a> HasId for O<'a> {
77 fn count(&self) -> usize { self.id.count() }
81 fn new() -> Box<O<'a>> {
84 obj0: CheckId(Cell::new(None)),
85 obj1: CheckId(Cell::new(None)),
90 impl<'a> HasId for Cell<Option<&'a Box<dyn Obj<'a>>>> {
91 fn count(&self) -> usize {
99 impl<'a> Obj<'a> for O<'a> {
100 fn set0(&self, b: &'a Box<dyn Obj<'a>>) {
101 self.obj0.v.set(Some(b))
103 fn set1(&self, b: &'a Box<dyn Obj<'a>>) {
104 self.obj1.v.set(Some(b))
110 let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
111 o1.set0(&o2); //~ ERROR `o2` does not live long enough
112 o1.set1(&o3); //~ ERROR `o3` does not live long enough
113 o2.set0(&o2); //~ ERROR `o2` does not live long enough
114 o2.set1(&o3); //~ ERROR `o3` does not live long enough
115 o3.set0(&o1); //~ ERROR `o1` does not live long enough
116 o3.set1(&o2); //~ ERROR `o2` does not live long enough