1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // This test exercises cases where cyclic structure is legal,
12 // including when the cycles go through data-structures such
13 // as `Vec` or `TypedArena`.
15 // The intent is to cover as many such cases as possible, ensuring
16 // that if the compiler did not complain circa Rust 1.x (1.2 as of
17 // this writing), then it will continue to not complain in the future.
19 // Note that while some of the tests are only exercising using the
20 // given collection as a "backing store" for a set of nodes that hold
21 // the actual cycle (and thus the cycle does not go through the
22 // collection itself in such cases), in general we *do* want to make
23 // sure to have at least one example exercising a cycle that goes
24 // through the collection, for every collection type that supports
30 use std
::cmp
::Ordering
;
31 use std
::collections
::BinaryHeap
;
32 use std
::collections
::HashMap
;
33 use std
::collections
::LinkedList
;
34 use std
::collections
::VecDeque
;
35 use std
::collections
::VecMap
;
36 use std
::collections
::btree_map
::BTreeMap
;
37 use std
::collections
::btree_set
::BTreeSet
;
38 use std
::hash
::{Hash, Hasher}
;
40 const PRINT
: bool
= false;
43 let c_orig
= ContextData
{
50 saw_prev_marked
: false,
53 // Cycle 1: { v[0] -> v[1], v[1] -> v[0] };
54 // does not exercise `v` itself
55 let v
: Vec
<S
> = vec
![Named
::new("s0"),
57 v
[0].next
.set(Some(&v
[1]));
58 v
[1].next
.set(Some(&v
[0]));
60 let mut c
= c_orig
.clone();
62 assert
!(!c
.saw_prev_marked
);
63 v
[0].for_each_child(&mut c
);
64 assert
!(c
.saw_prev_marked
);
66 if PRINT { println!(""); }
68 // Cycle 2: { v[0] -> v, v[1] -> v }
69 let v
: V
= Named
::new("v");
70 v
.contents
[0].set(Some(&v
));
71 v
.contents
[1].set(Some(&v
));
73 let mut c
= c_orig
.clone();
75 assert
!(!c
.saw_prev_marked
);
76 v
.for_each_child(&mut c
);
77 assert
!(c
.saw_prev_marked
);
79 if PRINT { println!(""); }
81 // Cycle 3: { hk0 -> hv0, hv0 -> hk0, hk1 -> hv1, hv1 -> hk1 };
82 // does not exercise `h` itself
84 let mut h
: HashMap
<H
,H
> = HashMap
::new();
85 h
.insert(Named
::new("hk0"), Named
::new("hv0"));
86 h
.insert(Named
::new("hk1"), Named
::new("hv1"));
87 for (key
, val
) in h
.iter() {
88 val
.next
.set(Some(key
));
89 key
.next
.set(Some(val
));
92 let mut c
= c_orig
.clone();
94 for (key
, _
) in h
.iter() {
96 c
.saw_prev_marked
= false;
97 key
.for_each_child(&mut c
);
98 assert
!(c
.saw_prev_marked
);
101 if PRINT { println!(""); }
103 // Cycle 4: { h -> (hmk0,hmv0,hmk1,hmv1), {hmk0,hmv0,hmk1,hmv1} -> h }
105 let mut h
: HashMap
<HM
,HM
> = HashMap
::new();
106 h
.insert(Named
::new("hmk0"), Named
::new("hmv0"));
107 h
.insert(Named
::new("hmk0"), Named
::new("hmv0"));
108 for (key
, val
) in h
.iter() {
109 val
.contents
.set(Some(&h
));
110 key
.contents
.set(Some(&h
));
113 let mut c
= c_orig
.clone();
116 for (key
, _
) in h
.iter() {
118 c
.saw_prev_marked
= false;
119 key
.for_each_child(&mut c
);
120 assert
!(c
.saw_prev_marked
);
124 if PRINT { println!(""); }
126 // Cycle 5: { vd[0] -> vd[1], vd[1] -> vd[0] };
127 // does not exercise vd itself
128 let mut vd
: VecDeque
<S
> = VecDeque
::new();
129 vd
.push_back(Named
::new("d0"));
130 vd
.push_back(Named
::new("d1"));
131 vd
[0].next
.set(Some(&vd
[1]));
132 vd
[1].next
.set(Some(&vd
[0]));
134 let mut c
= c_orig
.clone();
136 assert
!(!c
.saw_prev_marked
);
137 vd
[0].for_each_child(&mut c
);
138 assert
!(c
.saw_prev_marked
);
140 if PRINT { println!(""); }
142 // Cycle 6: { vd -> (vd0, vd1), {vd0, vd1} -> vd }
143 let mut vd
: VecDeque
<VD
> = VecDeque
::new();
144 vd
.push_back(Named
::new("vd0"));
145 vd
.push_back(Named
::new("vd1"));
146 vd
[0].contents
.set(Some(&vd
));
147 vd
[1].contents
.set(Some(&vd
));
149 let mut c
= c_orig
.clone();
151 assert
!(!c
.saw_prev_marked
);
152 vd
[0].for_each_child(&mut c
);
153 assert
!(c
.saw_prev_marked
);
155 if PRINT { println!(""); }
157 // Cycle 7: { vm -> (vm0, vm1), {vm0, vm1} -> vm }
158 let mut vm
: VecMap
<VM
> = VecMap
::new();
159 vm
.insert(0, Named
::new("vm0"));
160 vm
.insert(1, Named
::new("vm1"));
161 vm
[0].contents
.set(Some(&vm
));
162 vm
[1].contents
.set(Some(&vm
));
164 let mut c
= c_orig
.clone();
166 assert
!(!c
.saw_prev_marked
);
167 vm
[0].for_each_child(&mut c
);
168 assert
!(c
.saw_prev_marked
);
170 if PRINT { println!(""); }
172 // Cycle 8: { ll -> (ll0, ll1), {ll0, ll1} -> ll }
173 let mut ll
: LinkedList
<LL
> = LinkedList
::new();
174 ll
.push_back(Named
::new("ll0"));
175 ll
.push_back(Named
::new("ll1"));
177 e
.contents
.set(Some(&ll
));
180 let mut c
= c_orig
.clone();
184 c
.saw_prev_marked
= false;
185 e
.for_each_child(&mut c
);
186 assert
!(c
.saw_prev_marked
);
190 if PRINT { println!(""); }
192 // Cycle 9: { bh -> (bh0, bh1), {bh0, bh1} -> bh }
193 let mut bh
: BinaryHeap
<BH
> = BinaryHeap
::new();
194 bh
.push(Named
::new("bh0"));
195 bh
.push(Named
::new("bh1"));
197 b
.contents
.set(Some(&bh
));
200 let mut c
= c_orig
.clone();
204 c
.saw_prev_marked
= false;
205 b
.for_each_child(&mut c
);
206 assert
!(c
.saw_prev_marked
);
210 if PRINT { println!(""); }
212 // Cycle 10: { btm -> (btk0, btv1), {bt0, bt1} -> btm }
213 let mut btm
: BTreeMap
<BTM
, BTM
> = BTreeMap
::new();
214 btm
.insert(Named
::new("btk0"), Named
::new("btv0"));
215 btm
.insert(Named
::new("btk1"), Named
::new("btv1"));
216 for (k
, v
) in btm
.iter() {
217 k
.contents
.set(Some(&btm
));
218 v
.contents
.set(Some(&btm
));
221 let mut c
= c_orig
.clone();
225 c
.saw_prev_marked
= false;
226 k
.for_each_child(&mut c
);
227 assert
!(c
.saw_prev_marked
);
231 if PRINT { println!(""); }
233 // Cycle 10: { bts -> (bts0, bts1), {bts0, bts1} -> btm }
234 let mut bts
: BTreeSet
<BTS
> = BTreeSet
::new();
235 bts
.insert(Named
::new("bts0"));
236 bts
.insert(Named
::new("bts1"));
237 for v
in bts
.iter() {
238 v
.contents
.set(Some(&bts
));
241 let mut c
= c_orig
.clone();
245 c
.saw_prev_marked
= false;
246 b
.for_each_child(&mut c
);
247 assert
!(c
.saw_prev_marked
);
253 fn new(&'
static str) -> Self;
254 fn name(&self) -> &str;
259 fn set_mark(&self, mark
: M
);
265 next
: Cell
<Option
<&'a S
<'a
>>>,
268 impl<'a
> Named
for S
<'a
> {
269 fn new
<'b
>(name
: &'
static str) -> S
<'b
> {
270 S { name: name, mark: Cell::new(0), next: Cell::new(None) }
272 fn name(&self) -> &str { self.name }
275 impl<'a
> Marked
<u32> for S
<'a
> {
276 fn mark(&self) -> u32 { self.mark.get() }
277 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
283 contents
: Vec
<Cell
<Option
<&'a V
<'a
>>>>,
286 impl<'a
> Named
for V
<'a
> {
287 fn new
<'b
>(name
: &'
static str) -> V
<'b
> {
290 contents
: vec
![Cell
::new(None
), Cell
::new(None
)]
293 fn name(&self) -> &str { self.name }
296 impl<'a
> Marked
<u32> for V
<'a
> {
297 fn mark(&self) -> u32 { self.mark.get() }
298 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
305 next
: Cell
<Option
<&'a H
<'a
>>>,
308 impl<'a
> Named
for H
<'a
> {
309 fn new
<'b
>(name
: &'
static str) -> H
<'b
> {
310 H { name: name, mark: Cell::new(0), next: Cell::new(None) }
312 fn name(&self) -> &str { self.name }
315 impl<'a
> Marked
<u32> for H
<'a
> {
316 fn mark(&self) -> u32 { self.mark.get() }
317 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
320 impl<'a
> PartialEq
for H
<'a
> {
321 fn eq(&self, rhs
: &H
<'a
>) -> bool
{
322 self.name
== rhs
.name
326 impl<'a
> Hash
for H
<'a
> {
327 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
328 self.name
.hash(state
)
336 contents
: Cell
<Option
<&'a HashMap
<HM
<'a
>, HM
<'a
>>>>,
339 impl<'a
> Named
for HM
<'a
> {
340 fn new
<'b
>(name
: &'
static str) -> HM
<'b
> {
343 contents
: Cell
::new(None
)
346 fn name(&self) -> &str { self.name }
349 impl<'a
> Marked
<u32> for HM
<'a
> {
350 fn mark(&self) -> u32 { self.mark.get() }
351 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
354 impl<'a
> PartialEq
for HM
<'a
> {
355 fn eq(&self, rhs
: &HM
<'a
>) -> bool
{
356 self.name
== rhs
.name
360 impl<'a
> Hash
for HM
<'a
> {
361 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
362 self.name
.hash(state
)
370 contents
: Cell
<Option
<&'a VecDeque
<VD
<'a
>>>>,
373 impl<'a
> Named
for VD
<'a
> {
374 fn new
<'b
>(name
: &'
static str) -> VD
<'b
> {
377 contents
: Cell
::new(None
)
380 fn name(&self) -> &str { self.name }
383 impl<'a
> Marked
<u32> for VD
<'a
> {
384 fn mark(&self) -> u32 { self.mark.get() }
385 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
391 contents
: Cell
<Option
<&'a VecMap
<VM
<'a
>>>>,
394 impl<'a
> Named
for VM
<'a
> {
395 fn new
<'b
>(name
: &'
static str) -> VM
<'b
> {
398 contents
: Cell
::new(None
)
401 fn name(&self) -> &str { self.name }
404 impl<'a
> Marked
<u32> for VM
<'a
> {
405 fn mark(&self) -> u32 { self.mark.get() }
406 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
412 contents
: Cell
<Option
<&'a LinkedList
<LL
<'a
>>>>,
415 impl<'a
> Named
for LL
<'a
> {
416 fn new
<'b
>(name
: &'
static str) -> LL
<'b
> {
419 contents
: Cell
::new(None
)
422 fn name(&self) -> &str { self.name }
425 impl<'a
> Marked
<u32> for LL
<'a
> {
426 fn mark(&self) -> u32 { self.mark.get() }
427 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
433 contents
: Cell
<Option
<&'a BinaryHeap
<BH
<'a
>>>>,
436 impl<'a
> Named
for BH
<'a
> {
437 fn new
<'b
>(name
: &'
static str) -> BH
<'b
> {
440 contents
: Cell
::new(None
)
443 fn name(&self) -> &str { self.name }
446 impl<'a
> Marked
<u32> for BH
<'a
> {
447 fn mark(&self) -> u32 { self.mark.get() }
448 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
451 impl<'a
> Eq
for BH
<'a
> { }
453 impl<'a
> PartialEq
for BH
<'a
> {
454 fn eq(&self, rhs
: &BH
<'a
>) -> bool
{
455 self.name
== rhs
.name
459 impl<'a
> PartialOrd
for BH
<'a
> {
460 fn partial_cmp(&self, rhs
: &BH
<'a
>) -> Option
<Ordering
> {
465 impl<'a
> Ord
for BH
<'a
> {
466 fn cmp(&self, rhs
: &BH
<'a
>) -> Ordering
{
467 self.name
.cmp(rhs
.name
)
474 contents
: Cell
<Option
<&'a BTreeMap
<BTM
<'a
>, BTM
<'a
>>>>,
477 impl<'a
> Named
for BTM
<'a
> {
478 fn new
<'b
>(name
: &'
static str) -> BTM
<'b
> {
481 contents
: Cell
::new(None
)
484 fn name(&self) -> &str { self.name }
487 impl<'a
> Marked
<u32> for BTM
<'a
> {
488 fn mark(&self) -> u32 { self.mark.get() }
489 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
492 impl<'a
> Eq
for BTM
<'a
> { }
494 impl<'a
> PartialEq
for BTM
<'a
> {
495 fn eq(&self, rhs
: &BTM
<'a
>) -> bool
{
496 self.name
== rhs
.name
500 impl<'a
> PartialOrd
for BTM
<'a
> {
501 fn partial_cmp(&self, rhs
: &BTM
<'a
>) -> Option
<Ordering
> {
506 impl<'a
> Ord
for BTM
<'a
> {
507 fn cmp(&self, rhs
: &BTM
<'a
>) -> Ordering
{
508 self.name
.cmp(rhs
.name
)
515 contents
: Cell
<Option
<&'a BTreeSet
<BTS
<'a
>>>>,
518 impl<'a
> Named
for BTS
<'a
> {
519 fn new
<'b
>(name
: &'
static str) -> BTS
<'b
> {
522 contents
: Cell
::new(None
)
525 fn name(&self) -> &str { self.name }
528 impl<'a
> Marked
<u32> for BTS
<'a
> {
529 fn mark(&self) -> u32 { self.mark.get() }
530 fn set_mark(&self, mark
: u32) { self.mark.set(mark); }
533 impl<'a
> Eq
for BTS
<'a
> { }
535 impl<'a
> PartialEq
for BTS
<'a
> {
536 fn eq(&self, rhs
: &BTS
<'a
>) -> bool
{
537 self.name
== rhs
.name
541 impl<'a
> PartialOrd
for BTS
<'a
> {
542 fn partial_cmp(&self, rhs
: &BTS
<'a
>) -> Option
<Ordering
> {
547 impl<'a
> Ord
for BTS
<'a
> {
548 fn cmp(&self, rhs
: &BTS
<'a
>) -> Ordering
{
549 self.name
.cmp(rhs
.name
)
555 fn should_act(&self) -> bool
;
556 fn increase_visited(&mut self);
557 fn increase_skipped(&mut self);
558 fn increase_depth(&mut self);
559 fn decrease_depth(&mut self);
563 fn pre(&mut self, &T
);
564 fn post(&mut self, &T
);
565 fn hit_limit(&mut self, &T
);
569 fn for_each_child
<C
>(&self, context
: &mut C
)
570 where C
: Context
+ PrePost
<Self>, Self: Sized
;
572 fn descend_into_self
<C
>(&self, context
: &mut C
)
573 where C
: Context
+ PrePost
<Self>, Self: Sized
576 if context
.should_act() {
577 context
.increase_visited();
578 context
.increase_depth();
579 self.for_each_child(context
);
580 context
.decrease_depth();
582 context
.hit_limit(self);
583 context
.increase_skipped();
588 fn descend
<'b
, C
>(&self, c
: &Cell
<Option
<&'b
Self>>, context
: &mut C
)
589 where C
: Context
+ PrePost
<Self>, Self: Sized
591 if let Some(r
) = c
.get() {
592 r
.descend_into_self(context
);
597 impl<'a
> Children
<'a
> for S
<'a
> {
598 fn for_each_child
<C
>(&self, context
: &mut C
)
599 where C
: Context
+ PrePost
<S
<'a
>>
601 self.descend(&self.next
, context
);
605 impl<'a
> Children
<'a
> for V
<'a
> {
606 fn for_each_child
<C
>(&self, context
: &mut C
)
607 where C
: Context
+ PrePost
<V
<'a
>>
609 for r
in &self.contents
{
610 self.descend(r
, context
);
615 impl<'a
> Children
<'a
> for H
<'a
> {
616 fn for_each_child
<C
>(&self, context
: &mut C
)
617 where C
: Context
+ PrePost
<H
<'a
>>
619 self.descend(&self.next
, context
);
623 impl<'a
> Children
<'a
> for HM
<'a
> {
624 fn for_each_child
<C
>(&self, context
: &mut C
)
625 where C
: Context
+ PrePost
<HM
<'a
>>
627 if let Some(ref hm
) = self.contents
.get() {
628 for (k
, v
) in hm
.iter() {
630 r
.descend_into_self(context
);
637 impl<'a
> Children
<'a
> for VD
<'a
> {
638 fn for_each_child
<C
>(&self, context
: &mut C
)
639 where C
: Context
+ PrePost
<VD
<'a
>>
641 if let Some(ref vd
) = self.contents
.get() {
643 r
.descend_into_self(context
);
649 impl<'a
> Children
<'a
> for VM
<'a
> {
650 fn for_each_child
<C
>(&self, context
: &mut C
)
651 where C
: Context
+ PrePost
<VM
<'a
>>
653 if let Some(ref vd
) = self.contents
.get() {
654 for (_idx
, r
) in vd
.iter() {
655 r
.descend_into_self(context
);
661 impl<'a
> Children
<'a
> for LL
<'a
> {
662 fn for_each_child
<C
>(&self, context
: &mut C
)
663 where C
: Context
+ PrePost
<LL
<'a
>>
665 if let Some(ref ll
) = self.contents
.get() {
667 r
.descend_into_self(context
);
673 impl<'a
> Children
<'a
> for BH
<'a
> {
674 fn for_each_child
<C
>(&self, context
: &mut C
)
675 where C
: Context
+ PrePost
<BH
<'a
>>
677 if let Some(ref bh
) = self.contents
.get() {
679 r
.descend_into_self(context
);
685 impl<'a
> Children
<'a
> for BTM
<'a
> {
686 fn for_each_child
<C
>(&self, context
: &mut C
)
687 where C
: Context
+ PrePost
<BTM
<'a
>>
689 if let Some(ref bh
) = self.contents
.get() {
690 for (k
, v
) in bh
.iter() {
692 r
.descend_into_self(context
);
699 impl<'a
> Children
<'a
> for BTS
<'a
> {
700 fn for_each_child
<C
>(&self, context
: &mut C
)
701 where C
: Context
+ PrePost
<BTS
<'a
>>
703 if let Some(ref bh
) = self.contents
.get() {
705 r
.descend_into_self(context
);
711 #[derive(Copy, Clone)]
719 saw_prev_marked
: bool
,
722 impl Context
for ContextData
{
723 fn should_act(&self) -> bool
{
724 self.curr_depth
< self.max_depth
&& self.visited
< self.max_visits
726 fn increase_visited(&mut self) { self.visited += 1; }
727 fn increase_skipped(&mut self) { self.skipped += 1; }
728 fn increase_depth(&mut self) { self.curr_depth += 1; }
729 fn decrease_depth(&mut self) { self.curr_depth -= 1; }
732 impl<T
:Named
+Marked
<u32>> PrePost
<T
> for ContextData
{
733 fn pre(&mut self, t
: &T
) {
734 for _
in 0..self.curr_depth
{
735 if PRINT { print!(" "); }
737 if PRINT { println!("prev {}
", t.name()); }
738 if t.mark() == self.curr_mark {
739 for _ in 0..self.curr_depth {
740 if PRINT { print!(" "); }
742 if PRINT { println!("(probably previously marked)"); }
743 self.saw_prev_marked = true;
745 t.set_mark(self.curr_mark);
747 fn post(&mut self, t: &T) {
748 for _ in 0..self.curr_depth {
749 if PRINT { print!(" "); }
751 if PRINT { println!("post {}", t
.name()); }
753 fn hit_limit(&mut self, t
: &T
) {
754 for _
in 0..self.curr_depth
{
755 if PRINT { print!(" "); }
757 if PRINT { println!("LIMIT {}
", t.name()); }