]> git.proxmox.com Git - rustc.git/blame - src/test/ui/drop/dropck_legal_cycles.rs
Update unsuspicious file list
[rustc.git] / src / test / ui / drop / dropck_legal_cycles.rs
CommitLineData
b7449926 1// run-pass
c1a9b12d
SL
2// This test exercises cases where cyclic structure is legal,
3// including when the cycles go through data-structures such
4// as `Vec` or `TypedArena`.
5//
6// The intent is to cover as many such cases as possible, ensuring
7// that if the compiler did not complain circa Rust 1.x (1.2 as of
8// this writing), then it will continue to not complain in the future.
9//
10// Note that while some of the tests are only exercising using the
11// given collection as a "backing store" for a set of nodes that hold
12// the actual cycle (and thus the cycle does not go through the
13// collection itself in such cases), in general we *do* want to make
14// sure to have at least one example exercising a cycle that goes
15// through the collection, for every collection type that supports
16// this.
17
b039eaaf
SL
18// HIGH LEVEL DESCRIPTION OF THE TEST ARCHITECTURE
19// -----------------------------------------------
20//
21// We pick a data structure and want to make a cyclic construction
22// from it. Each test of interest is labelled starting with "Cycle N:
23// { ... }" where N is the test number and the "..."`is filled in with
24// a graphviz-style description of the graph structure that the
25// author believes is being made. So "{ a -> b, b -> (c,d), (c,d) -> e }"
26// describes a line connected to a diamond:
27//
28// c
29// / \
30// a - b e
31// \ /
32// d
33//
34// (Note that the above directed graph is actually acyclic.)
35//
36// The different graph structures are often composed of different data
37// types. Some may be built atop `Vec`, others atop `HashMap`, etc.
38//
39// For each graph structure, we actually *confirm* that a cycle exists
40// (as a safe-guard against a test author accidentally leaving it out)
41// by traversing each graph and "proving" that a cycle exists within it.
42//
43// To do this, while trying to keep the code uniform (despite working
44// with different underlying collection and smart-pointer types), we
45// have a standard traversal API:
46//
47// 1. every node in the graph carries a `mark` (a u32, init'ed to 0).
48//
49// 2. every node provides a method to visit its children
50//
51// 3. a traversal attmepts to visit the nodes of the graph and prove that
52// it sees the same node twice. It does this by setting the mark of each
53// node to a fresh non-zero value, and if it sees the current mark, it
54// "knows" that it must have found a cycle, and stops attempting further
55// traversal.
56//
57// 4. each traversal is controlled by a bit-string that tells it which child
58// it visit when it can take different paths. As a simple example,
59// in a binary tree, 0 could mean "left" (and 1, "right"), so that
60// "00010" means "left, left, left, right, left". (In general it will
61// read as many bits as it needs to choose one child.)
62//
63// The graphs in this test are all meant to be very small, and thus
64// short bitstrings of less than 64 bits should always suffice.
65//
66// (An earlier version of this test infrastructure simply had any
67// given traversal visit all children it encountered, in a
68// depth-first manner; one problem with this approach is that an
69// acyclic graph can still have sharing, which would then be treated
70// as a repeat mark and reported as a detected cycle.)
71//
72// The travseral code is a little more complicated because it has been
73// programmed in a somewhat defensive manner. For example it also has
74// a max threshold for the number of nodes it will visit, to guard
75// against scenarios where the nodes are not correctly setting their
76// mark when asked. There are various other methods not discussed here
77// that are for aiding debugging the test when it runs, such as the
78// `name` method that all nodes provide.
79//
80// So each test:
81//
82// 1. allocates the nodes in the graph,
83//
84// 2. sets up the links in the graph,
85//
86// 3. clones the "ContextData"
87//
88// 4. chooses a new current mark value for this test
89//
90// 5. initiates a traversal, potentially from multiple starting points
91// (aka "roots"), with a given control-string (potentially a
92// different string for each root). if it does start from a
93// distinct root, then such a test should also increment the
94// current mark value, so that this traversal is considered
95// distinct from the prior one on this graph structure.
96//
97// Note that most of the tests work with the default control string
98// of all-zeroes.
99//
100// 6. assert that the context confirms that it actually saw a cycle (since a traversal
0731742a 101// might have terminated, e.g., on a tree structure that contained no cycles).
c1a9b12d 102
b039eaaf 103use std::cell::{Cell, RefCell};
c1a9b12d
SL
104use std::cmp::Ordering;
105use std::collections::BinaryHeap;
106use std::collections::HashMap;
107use std::collections::LinkedList;
108use std::collections::VecDeque;
c1a9b12d
SL
109use std::collections::btree_map::BTreeMap;
110use std::collections::btree_set::BTreeSet;
111use std::hash::{Hash, Hasher};
b039eaaf
SL
112use std::rc::Rc;
113use std::sync::{Arc, RwLock, Mutex};
c1a9b12d
SL
114
115const PRINT: bool = false;
116
117pub fn main() {
118 let c_orig = ContextData {
119 curr_depth: 0,
120 max_depth: 3,
121 visited: 0,
122 max_visits: 1000,
123 skipped: 0,
124 curr_mark: 0,
125 saw_prev_marked: false,
b039eaaf 126 control_bits: 0,
c1a9b12d
SL
127 };
128
b039eaaf
SL
129 // SANITY CHECK FOR TEST SUITE (thus unnumbered)
130 // Not a cycle: { v[0] -> (v[1], v[2]), v[1] -> v[3], v[2] -> v[3] };
131 let v: Vec<S2> = vec![Named::new("s0"),
132 Named::new("s1"),
133 Named::new("s2"),
134 Named::new("s3")];
135 v[0].next.set((Some(&v[1]), Some(&v[2])));
136 v[1].next.set((Some(&v[3]), None));
137 v[2].next.set((Some(&v[3]), None));
138 v[3].next.set((None, None));
139
140 let mut c = c_orig.clone();
141 c.curr_mark = 10;
142 assert!(!c.saw_prev_marked);
143 v[0].descend_into_self(&mut c);
144 assert!(!c.saw_prev_marked); // <-- different from below, b/c acyclic above
145
e1599b0c 146 if PRINT { println!(); }
b039eaaf 147
c1a9b12d
SL
148 // Cycle 1: { v[0] -> v[1], v[1] -> v[0] };
149 // does not exercise `v` itself
150 let v: Vec<S> = vec![Named::new("s0"),
151 Named::new("s1")];
152 v[0].next.set(Some(&v[1]));
153 v[1].next.set(Some(&v[0]));
154
155 let mut c = c_orig.clone();
156 c.curr_mark = 10;
157 assert!(!c.saw_prev_marked);
b039eaaf 158 v[0].descend_into_self(&mut c);
c1a9b12d
SL
159 assert!(c.saw_prev_marked);
160
e1599b0c 161 if PRINT { println!(); }
c1a9b12d
SL
162
163 // Cycle 2: { v[0] -> v, v[1] -> v }
164 let v: V = Named::new("v");
165 v.contents[0].set(Some(&v));
166 v.contents[1].set(Some(&v));
167
168 let mut c = c_orig.clone();
169 c.curr_mark = 20;
170 assert!(!c.saw_prev_marked);
b039eaaf 171 v.descend_into_self(&mut c);
c1a9b12d
SL
172 assert!(c.saw_prev_marked);
173
e1599b0c 174 if PRINT { println!(); }
c1a9b12d
SL
175
176 // Cycle 3: { hk0 -> hv0, hv0 -> hk0, hk1 -> hv1, hv1 -> hk1 };
177 // does not exercise `h` itself
178
179 let mut h: HashMap<H,H> = HashMap::new();
180 h.insert(Named::new("hk0"), Named::new("hv0"));
181 h.insert(Named::new("hk1"), Named::new("hv1"));
182 for (key, val) in h.iter() {
183 val.next.set(Some(key));
184 key.next.set(Some(val));
185 }
186
187 let mut c = c_orig.clone();
188 c.curr_mark = 30;
189 for (key, _) in h.iter() {
190 c.curr_mark += 1;
191 c.saw_prev_marked = false;
b039eaaf 192 key.descend_into_self(&mut c);
c1a9b12d
SL
193 assert!(c.saw_prev_marked);
194 }
195
e1599b0c 196 if PRINT { println!(); }
c1a9b12d
SL
197
198 // Cycle 4: { h -> (hmk0,hmv0,hmk1,hmv1), {hmk0,hmv0,hmk1,hmv1} -> h }
199
200 let mut h: HashMap<HM,HM> = HashMap::new();
201 h.insert(Named::new("hmk0"), Named::new("hmv0"));
202 h.insert(Named::new("hmk0"), Named::new("hmv0"));
203 for (key, val) in h.iter() {
204 val.contents.set(Some(&h));
205 key.contents.set(Some(&h));
206 }
207
208 let mut c = c_orig.clone();
209 c.max_depth = 2;
210 c.curr_mark = 40;
211 for (key, _) in h.iter() {
212 c.curr_mark += 1;
213 c.saw_prev_marked = false;
b039eaaf 214 key.descend_into_self(&mut c);
c1a9b12d
SL
215 assert!(c.saw_prev_marked);
216 // break;
217 }
218
e1599b0c 219 if PRINT { println!(); }
c1a9b12d
SL
220
221 // Cycle 5: { vd[0] -> vd[1], vd[1] -> vd[0] };
222 // does not exercise vd itself
223 let mut vd: VecDeque<S> = VecDeque::new();
224 vd.push_back(Named::new("d0"));
225 vd.push_back(Named::new("d1"));
226 vd[0].next.set(Some(&vd[1]));
227 vd[1].next.set(Some(&vd[0]));
228
229 let mut c = c_orig.clone();
230 c.curr_mark = 50;
231 assert!(!c.saw_prev_marked);
b039eaaf 232 vd[0].descend_into_self(&mut c);
c1a9b12d
SL
233 assert!(c.saw_prev_marked);
234
e1599b0c 235 if PRINT { println!(); }
c1a9b12d
SL
236
237 // Cycle 6: { vd -> (vd0, vd1), {vd0, vd1} -> vd }
238 let mut vd: VecDeque<VD> = VecDeque::new();
239 vd.push_back(Named::new("vd0"));
240 vd.push_back(Named::new("vd1"));
241 vd[0].contents.set(Some(&vd));
242 vd[1].contents.set(Some(&vd));
243
244 let mut c = c_orig.clone();
245 c.curr_mark = 60;
246 assert!(!c.saw_prev_marked);
b039eaaf 247 vd[0].descend_into_self(&mut c);
c1a9b12d
SL
248 assert!(c.saw_prev_marked);
249
e1599b0c 250 if PRINT { println!(); }
c1a9b12d
SL
251
252 // Cycle 7: { vm -> (vm0, vm1), {vm0, vm1} -> vm }
e9174d1e 253 let mut vm: HashMap<usize, VM> = HashMap::new();
c1a9b12d
SL
254 vm.insert(0, Named::new("vm0"));
255 vm.insert(1, Named::new("vm1"));
e9174d1e
SL
256 vm[&0].contents.set(Some(&vm));
257 vm[&1].contents.set(Some(&vm));
c1a9b12d
SL
258
259 let mut c = c_orig.clone();
260 c.curr_mark = 70;
261 assert!(!c.saw_prev_marked);
b039eaaf 262 vm[&0].descend_into_self(&mut c);
c1a9b12d
SL
263 assert!(c.saw_prev_marked);
264
e1599b0c 265 if PRINT { println!(); }
c1a9b12d
SL
266
267 // Cycle 8: { ll -> (ll0, ll1), {ll0, ll1} -> ll }
268 let mut ll: LinkedList<LL> = LinkedList::new();
269 ll.push_back(Named::new("ll0"));
270 ll.push_back(Named::new("ll1"));
271 for e in &ll {
272 e.contents.set(Some(&ll));
273 }
274
275 let mut c = c_orig.clone();
276 c.curr_mark = 80;
277 for e in &ll {
278 c.curr_mark += 1;
279 c.saw_prev_marked = false;
b039eaaf 280 e.descend_into_self(&mut c);
c1a9b12d
SL
281 assert!(c.saw_prev_marked);
282 // break;
283 }
284
e1599b0c 285 if PRINT { println!(); }
c1a9b12d
SL
286
287 // Cycle 9: { bh -> (bh0, bh1), {bh0, bh1} -> bh }
288 let mut bh: BinaryHeap<BH> = BinaryHeap::new();
289 bh.push(Named::new("bh0"));
290 bh.push(Named::new("bh1"));
291 for b in bh.iter() {
292 b.contents.set(Some(&bh));
293 }
294
295 let mut c = c_orig.clone();
296 c.curr_mark = 90;
297 for b in &bh {
298 c.curr_mark += 1;
299 c.saw_prev_marked = false;
b039eaaf 300 b.descend_into_self(&mut c);
c1a9b12d
SL
301 assert!(c.saw_prev_marked);
302 // break;
303 }
304
e1599b0c 305 if PRINT { println!(); }
c1a9b12d
SL
306
307 // Cycle 10: { btm -> (btk0, btv1), {bt0, bt1} -> btm }
308 let mut btm: BTreeMap<BTM, BTM> = BTreeMap::new();
309 btm.insert(Named::new("btk0"), Named::new("btv0"));
310 btm.insert(Named::new("btk1"), Named::new("btv1"));
311 for (k, v) in btm.iter() {
312 k.contents.set(Some(&btm));
313 v.contents.set(Some(&btm));
314 }
315
316 let mut c = c_orig.clone();
317 c.curr_mark = 100;
318 for (k, _) in &btm {
319 c.curr_mark += 1;
320 c.saw_prev_marked = false;
b039eaaf 321 k.descend_into_self(&mut c);
c1a9b12d
SL
322 assert!(c.saw_prev_marked);
323 // break;
324 }
325
e1599b0c 326 if PRINT { println!(); }
c1a9b12d
SL
327
328 // Cycle 10: { bts -> (bts0, bts1), {bts0, bts1} -> btm }
329 let mut bts: BTreeSet<BTS> = BTreeSet::new();
330 bts.insert(Named::new("bts0"));
331 bts.insert(Named::new("bts1"));
332 for v in bts.iter() {
333 v.contents.set(Some(&bts));
334 }
335
336 let mut c = c_orig.clone();
337 c.curr_mark = 100;
338 for b in &bts {
339 c.curr_mark += 1;
340 c.saw_prev_marked = false;
b039eaaf 341 b.descend_into_self(&mut c);
c1a9b12d
SL
342 assert!(c.saw_prev_marked);
343 // break;
344 }
b039eaaf 345
e1599b0c 346 if PRINT { println!(); }
b039eaaf
SL
347
348 // Cycle 11: { rc0 -> (rc1, rc2), rc1 -> (), rc2 -> rc0 }
349 let (rc0, rc1, rc2): (RCRC, RCRC, RCRC);
350 rc0 = RCRC::new("rcrc0");
351 rc1 = RCRC::new("rcrc1");
352 rc2 = RCRC::new("rcrc2");
353 rc0.0.borrow_mut().children.0 = Some(&rc1);
354 rc0.0.borrow_mut().children.1 = Some(&rc2);
355 rc2.0.borrow_mut().children.0 = Some(&rc0);
356
357 let mut c = c_orig.clone();
358 c.control_bits = 0b1;
359 c.curr_mark = 110;
360 assert!(!c.saw_prev_marked);
361 rc0.descend_into_self(&mut c);
362 assert!(c.saw_prev_marked);
363
e1599b0c 364 if PRINT { println!(); }
b039eaaf
SL
365
366 // We want to take the previous Rc case and generalize it to Arc.
367 //
368 // We can use refcells if we're single-threaded (as this test is).
369 // If one were to generalize these constructions to a
370 // multi-threaded context, then it might seem like we could choose
94222f64 371 // between either an RwLock or a Mutex to hold the owned arcs on
b039eaaf
SL
372 // each node.
373 //
374 // Part of the point of this test is to actually confirm that the
375 // cycle exists by traversing it. We can do that just fine with an
376 // RwLock (since we can grab the child pointers in read-only
377 // mode), but we cannot lock a std::sync::Mutex to guard reading
378 // from each node via the same pattern, since once you hit the
b7449926 379 // cycle, you'll be trying to acquiring the same lock twice.
b039eaaf
SL
380 // (We deal with this by exiting the traversal early if try_lock fails.)
381
382 // Cycle 12: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, refcells
383 let (arc0, arc1, arc2): (ARCRC, ARCRC, ARCRC);
384 arc0 = ARCRC::new("arcrc0");
385 arc1 = ARCRC::new("arcrc1");
386 arc2 = ARCRC::new("arcrc2");
387 arc0.0.borrow_mut().children.0 = Some(&arc1);
388 arc0.0.borrow_mut().children.1 = Some(&arc2);
389 arc2.0.borrow_mut().children.0 = Some(&arc0);
390
391 let mut c = c_orig.clone();
392 c.control_bits = 0b1;
393 c.curr_mark = 110;
394 assert!(!c.saw_prev_marked);
395 arc0.descend_into_self(&mut c);
396 assert!(c.saw_prev_marked);
397
e1599b0c 398 if PRINT { println!(); }
b039eaaf
SL
399
400 // Cycle 13: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, rwlocks
401 let (arc0, arc1, arc2): (ARCRW, ARCRW, ARCRW);
402 arc0 = ARCRW::new("arcrw0");
403 arc1 = ARCRW::new("arcrw1");
404 arc2 = ARCRW::new("arcrw2");
405 arc0.0.write().unwrap().children.0 = Some(&arc1);
406 arc0.0.write().unwrap().children.1 = Some(&arc2);
407 arc2.0.write().unwrap().children.0 = Some(&arc0);
408
409 let mut c = c_orig.clone();
410 c.control_bits = 0b1;
411 c.curr_mark = 110;
412 assert!(!c.saw_prev_marked);
413 arc0.descend_into_self(&mut c);
414 assert!(c.saw_prev_marked);
415
e1599b0c 416 if PRINT { println!(); }
b039eaaf
SL
417
418 // Cycle 14: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, mutexs
419 let (arc0, arc1, arc2): (ARCM, ARCM, ARCM);
420 arc0 = ARCM::new("arcm0");
421 arc1 = ARCM::new("arcm1");
422 arc2 = ARCM::new("arcm2");
423 arc0.1.lock().unwrap().children.0 = Some(&arc1);
424 arc0.1.lock().unwrap().children.1 = Some(&arc2);
425 arc2.1.lock().unwrap().children.0 = Some(&arc0);
426
427 let mut c = c_orig.clone();
428 c.control_bits = 0b1;
429 c.curr_mark = 110;
430 assert!(!c.saw_prev_marked);
431 arc0.descend_into_self(&mut c);
432 assert!(c.saw_prev_marked);
c1a9b12d
SL
433}
434
435trait Named {
041b39d2 436 fn new(_: &'static str) -> Self;
c1a9b12d
SL
437 fn name(&self) -> &str;
438}
439
440trait Marked<M> {
441 fn mark(&self) -> M;
442 fn set_mark(&self, mark: M);
443}
444
445struct S<'a> {
446 name: &'static str,
447 mark: Cell<u32>,
448 next: Cell<Option<&'a S<'a>>>,
449}
450
451impl<'a> Named for S<'a> {
3157f602 452 fn new(name: &'static str) -> S<'a> {
c1a9b12d
SL
453 S { name: name, mark: Cell::new(0), next: Cell::new(None) }
454 }
455 fn name(&self) -> &str { self.name }
456}
457
458impl<'a> Marked<u32> for S<'a> {
459 fn mark(&self) -> u32 { self.mark.get() }
460 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
461}
462
b039eaaf
SL
463struct S2<'a> {
464 name: &'static str,
465 mark: Cell<u32>,
466 next: Cell<(Option<&'a S2<'a>>, Option<&'a S2<'a>>)>,
467}
468
469impl<'a> Named for S2<'a> {
3157f602 470 fn new(name: &'static str) -> S2<'a> {
b039eaaf
SL
471 S2 { name: name, mark: Cell::new(0), next: Cell::new((None, None)) }
472 }
473 fn name(&self) -> &str { self.name }
474}
475
476impl<'a> Marked<u32> for S2<'a> {
477 fn mark(&self) -> u32 { self.mark.get() }
478 fn set_mark(&self, mark: u32) {
479 self.mark.set(mark);
480 }
481}
482
c1a9b12d
SL
483struct V<'a> {
484 name: &'static str,
485 mark: Cell<u32>,
486 contents: Vec<Cell<Option<&'a V<'a>>>>,
487}
488
489impl<'a> Named for V<'a> {
3157f602 490 fn new(name: &'static str) -> V<'a> {
c1a9b12d
SL
491 V { name: name,
492 mark: Cell::new(0),
493 contents: vec![Cell::new(None), Cell::new(None)]
494 }
495 }
496 fn name(&self) -> &str { self.name }
497}
498
499impl<'a> Marked<u32> for V<'a> {
500 fn mark(&self) -> u32 { self.mark.get() }
501 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
502}
503
504#[derive(Eq)]
505struct H<'a> {
506 name: &'static str,
507 mark: Cell<u32>,
508 next: Cell<Option<&'a H<'a>>>,
509}
510
511impl<'a> Named for H<'a> {
3157f602 512 fn new(name: &'static str) -> H<'a> {
c1a9b12d
SL
513 H { name: name, mark: Cell::new(0), next: Cell::new(None) }
514 }
515 fn name(&self) -> &str { self.name }
516}
517
518impl<'a> Marked<u32> for H<'a> {
519 fn mark(&self) -> u32 { self.mark.get() }
520 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
521}
522
523impl<'a> PartialEq for H<'a> {
524 fn eq(&self, rhs: &H<'a>) -> bool {
525 self.name == rhs.name
526 }
527}
528
529impl<'a> Hash for H<'a> {
530 fn hash<H: Hasher>(&self, state: &mut H) {
531 self.name.hash(state)
532 }
533}
534
535#[derive(Eq)]
536struct HM<'a> {
537 name: &'static str,
538 mark: Cell<u32>,
539 contents: Cell<Option<&'a HashMap<HM<'a>, HM<'a>>>>,
540}
541
542impl<'a> Named for HM<'a> {
3157f602 543 fn new(name: &'static str) -> HM<'a> {
c1a9b12d
SL
544 HM { name: name,
545 mark: Cell::new(0),
546 contents: Cell::new(None)
547 }
548 }
549 fn name(&self) -> &str { self.name }
550}
551
552impl<'a> Marked<u32> for HM<'a> {
553 fn mark(&self) -> u32 { self.mark.get() }
554 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
555}
556
557impl<'a> PartialEq for HM<'a> {
558 fn eq(&self, rhs: &HM<'a>) -> bool {
559 self.name == rhs.name
560 }
561}
562
563impl<'a> Hash for HM<'a> {
564 fn hash<H: Hasher>(&self, state: &mut H) {
565 self.name.hash(state)
566 }
567}
568
569
570struct VD<'a> {
571 name: &'static str,
572 mark: Cell<u32>,
573 contents: Cell<Option<&'a VecDeque<VD<'a>>>>,
574}
575
576impl<'a> Named for VD<'a> {
3157f602 577 fn new(name: &'static str) -> VD<'a> {
c1a9b12d
SL
578 VD { name: name,
579 mark: Cell::new(0),
580 contents: Cell::new(None)
581 }
582 }
583 fn name(&self) -> &str { self.name }
584}
585
586impl<'a> Marked<u32> for VD<'a> {
587 fn mark(&self) -> u32 { self.mark.get() }
588 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
589}
590
591struct VM<'a> {
592 name: &'static str,
593 mark: Cell<u32>,
e9174d1e 594 contents: Cell<Option<&'a HashMap<usize, VM<'a>>>>,
c1a9b12d
SL
595}
596
597impl<'a> Named for VM<'a> {
3157f602 598 fn new(name: &'static str) -> VM<'a> {
c1a9b12d
SL
599 VM { name: name,
600 mark: Cell::new(0),
601 contents: Cell::new(None)
602 }
603 }
604 fn name(&self) -> &str { self.name }
605}
606
607impl<'a> Marked<u32> for VM<'a> {
608 fn mark(&self) -> u32 { self.mark.get() }
609 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
610}
611
612struct LL<'a> {
613 name: &'static str,
614 mark: Cell<u32>,
615 contents: Cell<Option<&'a LinkedList<LL<'a>>>>,
616}
617
618impl<'a> Named for LL<'a> {
3157f602 619 fn new(name: &'static str) -> LL<'a> {
c1a9b12d
SL
620 LL { name: name,
621 mark: Cell::new(0),
622 contents: Cell::new(None)
623 }
624 }
625 fn name(&self) -> &str { self.name }
626}
627
628impl<'a> Marked<u32> for LL<'a> {
629 fn mark(&self) -> u32 { self.mark.get() }
630 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
631}
632
633struct BH<'a> {
634 name: &'static str,
635 mark: Cell<u32>,
636 contents: Cell<Option<&'a BinaryHeap<BH<'a>>>>,
637}
638
639impl<'a> Named for BH<'a> {
3157f602 640 fn new(name: &'static str) -> BH<'a> {
c1a9b12d
SL
641 BH { name: name,
642 mark: Cell::new(0),
643 contents: Cell::new(None)
644 }
645 }
646 fn name(&self) -> &str { self.name }
647}
648
649impl<'a> Marked<u32> for BH<'a> {
650 fn mark(&self) -> u32 { self.mark.get() }
651 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
652}
653
654impl<'a> Eq for BH<'a> { }
655
656impl<'a> PartialEq for BH<'a> {
657 fn eq(&self, rhs: &BH<'a>) -> bool {
658 self.name == rhs.name
659 }
660}
661
662impl<'a> PartialOrd for BH<'a> {
663 fn partial_cmp(&self, rhs: &BH<'a>) -> Option<Ordering> {
664 Some(self.cmp(rhs))
665 }
666}
667
668impl<'a> Ord for BH<'a> {
669 fn cmp(&self, rhs: &BH<'a>) -> Ordering {
670 self.name.cmp(rhs.name)
671 }
672}
673
674struct BTM<'a> {
675 name: &'static str,
676 mark: Cell<u32>,
677 contents: Cell<Option<&'a BTreeMap<BTM<'a>, BTM<'a>>>>,
678}
679
680impl<'a> Named for BTM<'a> {
3157f602 681 fn new(name: &'static str) -> BTM<'a> {
c1a9b12d
SL
682 BTM { name: name,
683 mark: Cell::new(0),
684 contents: Cell::new(None)
685 }
686 }
687 fn name(&self) -> &str { self.name }
688}
689
690impl<'a> Marked<u32> for BTM<'a> {
691 fn mark(&self) -> u32 { self.mark.get() }
692 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
693}
694
695impl<'a> Eq for BTM<'a> { }
696
697impl<'a> PartialEq for BTM<'a> {
698 fn eq(&self, rhs: &BTM<'a>) -> bool {
699 self.name == rhs.name
700 }
701}
702
703impl<'a> PartialOrd for BTM<'a> {
704 fn partial_cmp(&self, rhs: &BTM<'a>) -> Option<Ordering> {
705 Some(self.cmp(rhs))
706 }
707}
708
709impl<'a> Ord for BTM<'a> {
710 fn cmp(&self, rhs: &BTM<'a>) -> Ordering {
711 self.name.cmp(rhs.name)
712 }
713}
714
715struct BTS<'a> {
716 name: &'static str,
717 mark: Cell<u32>,
718 contents: Cell<Option<&'a BTreeSet<BTS<'a>>>>,
719}
720
721impl<'a> Named for BTS<'a> {
3157f602 722 fn new(name: &'static str) -> BTS<'a> {
c1a9b12d
SL
723 BTS { name: name,
724 mark: Cell::new(0),
725 contents: Cell::new(None)
726 }
727 }
728 fn name(&self) -> &str { self.name }
729}
730
731impl<'a> Marked<u32> for BTS<'a> {
732 fn mark(&self) -> u32 { self.mark.get() }
733 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
734}
735
736impl<'a> Eq for BTS<'a> { }
737
738impl<'a> PartialEq for BTS<'a> {
739 fn eq(&self, rhs: &BTS<'a>) -> bool {
740 self.name == rhs.name
741 }
742}
743
744impl<'a> PartialOrd for BTS<'a> {
745 fn partial_cmp(&self, rhs: &BTS<'a>) -> Option<Ordering> {
746 Some(self.cmp(rhs))
747 }
748}
749
750impl<'a> Ord for BTS<'a> {
751 fn cmp(&self, rhs: &BTS<'a>) -> Ordering {
752 self.name.cmp(rhs.name)
753 }
754}
755
b039eaaf
SL
756#[derive(Clone)]
757struct RCRCData<'a> {
758 name: &'static str,
759 mark: Cell<u32>,
760 children: (Option<&'a RCRC<'a>>, Option<&'a RCRC<'a>>),
761}
762#[derive(Clone)]
763struct RCRC<'a>(Rc<RefCell<RCRCData<'a>>>);
764
765impl<'a> Named for RCRC<'a> {
766 fn new(name: &'static str) -> Self {
767 RCRC(Rc::new(RefCell::new(RCRCData {
768 name: name, mark: Cell::new(0), children: (None, None), })))
769 }
770 fn name(&self) -> &str { self.0.borrow().name }
771}
772
773impl<'a> Marked<u32> for RCRC<'a> {
774 fn mark(&self) -> u32 { self.0.borrow().mark.get() }
775 fn set_mark(&self, mark: u32) { self.0.borrow().mark.set(mark); }
776}
777
778impl<'a> Children<'a> for RCRC<'a> {
779 fn count_children(&self) -> usize { 2 }
780 fn descend_one_child<C>(&self, context: &mut C, index: usize)
781 where C: Context + PrePost<Self>, Self: Sized
782 {
783 let children = &self.0.borrow().children;
784 let child = match index {
785 0 => if let Some(child) = children.0 { child } else { return; },
786 1 => if let Some(child) = children.1 { child } else { return; },
787 _ => panic!("bad children"),
788 };
789 // println!("S2 {} descending into child {} at index {}", self.name, child.name, index);
790 child.descend_into_self(context);
791 }
792}
793#[derive(Clone)]
794struct ARCRCData<'a> {
795 name: &'static str,
796 mark: Cell<u32>,
797 children: (Option<&'a ARCRC<'a>>, Option<&'a ARCRC<'a>>),
798}
799#[derive(Clone)]
800struct ARCRC<'a>(Arc<RefCell<ARCRCData<'a>>>);
801
802impl<'a> Named for ARCRC<'a> {
803 fn new(name: &'static str) -> Self {
804 ARCRC(Arc::new(RefCell::new(ARCRCData {
805 name: name, mark: Cell::new(0), children: (None, None), })))
806 }
807 fn name(&self) -> &str { self.0.borrow().name }
808}
809
810impl<'a> Marked<u32> for ARCRC<'a> {
811 fn mark(&self) -> u32 { self.0.borrow().mark.get() }
812 fn set_mark(&self, mark: u32) { self.0.borrow().mark.set(mark); }
813}
814
815impl<'a> Children<'a> for ARCRC<'a> {
816 fn count_children(&self) -> usize { 2 }
817 fn descend_one_child<C>(&self, context: &mut C, index: usize)
818 where C: Context + PrePost<Self>, Self: Sized
819 {
820 let children = &self.0.borrow().children;
821 match index {
822 0 => if let Some(ref child) = children.0 {
823 child.descend_into_self(context);
824 },
825 1 => if let Some(ref child) = children.1 {
826 child.descend_into_self(context);
827 },
828 _ => panic!("bad children!"),
829 }
830 }
831}
832
833#[derive(Clone)]
834struct ARCMData<'a> {
835 mark: Cell<u32>,
836 children: (Option<&'a ARCM<'a>>, Option<&'a ARCM<'a>>),
837}
838
839#[derive(Clone)]
840struct ARCM<'a>(&'static str, Arc<Mutex<ARCMData<'a>>>);
841
842impl<'a> Named for ARCM<'a> {
843 fn new(name: &'static str) -> Self {
844 ARCM(name, Arc::new(Mutex::new(ARCMData {
845 mark: Cell::new(0), children: (None, None), })))
846 }
847 fn name(&self) -> &str { self.0 }
848}
849
850impl<'a> Marked<u32> for ARCM<'a> {
851 fn mark(&self) -> u32 { self.1.lock().unwrap().mark.get() }
852 fn set_mark(&self, mark: u32) { self.1.lock().unwrap().mark.set(mark); }
853}
854
855impl<'a> Children<'a> for ARCM<'a> {
856 fn count_children(&self) -> usize { 2 }
857 fn descend_one_child<C>(&self, context: &mut C, index: usize)
858 where C: Context + PrePost<Self>, Self: Sized
859 {
860 let ref children = if let Ok(data) = self.1.try_lock() {
861 data.children
862 } else { return; };
863 match index {
864 0 => if let Some(ref child) = children.0 {
865 child.descend_into_self(context);
866 },
867 1 => if let Some(ref child) = children.1 {
868 child.descend_into_self(context);
869 },
870 _ => panic!("bad children!"),
871 }
872 }
873}
874
875#[derive(Clone)]
876struct ARCRWData<'a> {
877 name: &'static str,
878 mark: Cell<u32>,
879 children: (Option<&'a ARCRW<'a>>, Option<&'a ARCRW<'a>>),
880}
881
882#[derive(Clone)]
883struct ARCRW<'a>(Arc<RwLock<ARCRWData<'a>>>);
884
885impl<'a> Named for ARCRW<'a> {
886 fn new(name: &'static str) -> Self {
887 ARCRW(Arc::new(RwLock::new(ARCRWData {
888 name: name, mark: Cell::new(0), children: (None, None), })))
889 }
890 fn name(&self) -> &str { self.0.read().unwrap().name }
891}
892
893impl<'a> Marked<u32> for ARCRW<'a> {
894 fn mark(&self) -> u32 { self.0.read().unwrap().mark.get() }
895 fn set_mark(&self, mark: u32) { self.0.read().unwrap().mark.set(mark); }
896}
897
898impl<'a> Children<'a> for ARCRW<'a> {
899 fn count_children(&self) -> usize { 2 }
900 fn descend_one_child<C>(&self, context: &mut C, index: usize)
901 where C: Context + PrePost<Self>, Self: Sized
902 {
903 let children = &self.0.read().unwrap().children;
904 match index {
905 0 => if let Some(ref child) = children.0 {
906 child.descend_into_self(context);
907 },
908 1 => if let Some(ref child) = children.1 {
909 child.descend_into_self(context);
910 },
911 _ => panic!("bad children!"),
912 }
913 }
914}
c1a9b12d
SL
915
916trait Context {
b039eaaf 917 fn next_index(&mut self, len: usize) -> usize;
c1a9b12d
SL
918 fn should_act(&self) -> bool;
919 fn increase_visited(&mut self);
920 fn increase_skipped(&mut self);
921 fn increase_depth(&mut self);
922 fn decrease_depth(&mut self);
923}
924
925trait PrePost<T> {
041b39d2
XL
926 fn pre(&mut self, _: &T);
927 fn post(&mut self, _: &T);
928 fn hit_limit(&mut self, _: &T);
c1a9b12d
SL
929}
930
931trait Children<'a> {
b039eaaf
SL
932 fn count_children(&self) -> usize;
933 fn descend_one_child<C>(&self, context: &mut C, index: usize)
c1a9b12d
SL
934 where C: Context + PrePost<Self>, Self: Sized;
935
b039eaaf
SL
936 fn next_child<C>(&self, context: &mut C)
937 where C: Context + PrePost<Self>, Self: Sized
938 {
939 let index = context.next_index(self.count_children());
940 self.descend_one_child(context, index);
941 }
942
c1a9b12d
SL
943 fn descend_into_self<C>(&self, context: &mut C)
944 where C: Context + PrePost<Self>, Self: Sized
945 {
946 context.pre(self);
947 if context.should_act() {
948 context.increase_visited();
949 context.increase_depth();
b039eaaf 950 self.next_child(context);
c1a9b12d
SL
951 context.decrease_depth();
952 } else {
953 context.hit_limit(self);
954 context.increase_skipped();
955 }
956 context.post(self);
957 }
958
959 fn descend<'b, C>(&self, c: &Cell<Option<&'b Self>>, context: &mut C)
960 where C: Context + PrePost<Self>, Self: Sized
961 {
962 if let Some(r) = c.get() {
963 r.descend_into_self(context);
964 }
965 }
966}
967
968impl<'a> Children<'a> for S<'a> {
b039eaaf
SL
969 fn count_children(&self) -> usize { 1 }
970 fn descend_one_child<C>(&self, context: &mut C, _: usize)
971 where C: Context + PrePost<Self>, Self: Sized {
972 self.descend(&self.next, context);
973 }
974}
975
976impl<'a> Children<'a> for S2<'a> {
977 fn count_children(&self) -> usize { 2 }
978 fn descend_one_child<C>(&self, context: &mut C, index: usize)
979 where C: Context + PrePost<Self>, Self: Sized
c1a9b12d 980 {
b039eaaf
SL
981 let children = self.next.get();
982 let child = match index {
983 0 => if let Some(child) = children.0 { child } else { return; },
984 1 => if let Some(child) = children.1 { child } else { return; },
985 _ => panic!("bad children"),
986 };
987 // println!("S2 {} descending into child {} at index {}", self.name, child.name, index);
988 child.descend_into_self(context);
c1a9b12d
SL
989 }
990}
991
992impl<'a> Children<'a> for V<'a> {
b039eaaf
SL
993 fn count_children(&self) -> usize { self.contents.len() }
994 fn descend_one_child<C>(&self, context: &mut C, index: usize)
995 where C: Context + PrePost<Self>, Self: Sized
c1a9b12d 996 {
b039eaaf
SL
997 if let Some(child) = self.contents[index].get() {
998 child.descend_into_self(context);
c1a9b12d
SL
999 }
1000 }
1001}
1002
1003impl<'a> Children<'a> for H<'a> {
b039eaaf
SL
1004 fn count_children(&self) -> usize { 1 }
1005 fn descend_one_child<C>(&self, context: &mut C, _: usize)
1006 where C: Context + PrePost<Self>, Self: Sized
c1a9b12d
SL
1007 {
1008 self.descend(&self.next, context);
1009 }
1010}
1011
1012impl<'a> Children<'a> for HM<'a> {
b039eaaf
SL
1013 fn count_children(&self) -> usize {
1014 if let Some(m) = self.contents.get() { 2 * m.iter().count() } else { 0 }
1015 }
1016 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1017 where C: Context + PrePost<Self>, Self: Sized
c1a9b12d
SL
1018 {
1019 if let Some(ref hm) = self.contents.get() {
2b03887a 1020 if let Some((k, v)) = hm.iter().nth(index / 2) {
b039eaaf 1021 [k, v][index % 2].descend_into_self(context);
c1a9b12d
SL
1022 }
1023 }
1024 }
1025}
1026
1027impl<'a> Children<'a> for VD<'a> {
b039eaaf
SL
1028 fn count_children(&self) -> usize {
1029 if let Some(d) = self.contents.get() { d.iter().count() } else { 0 }
1030 }
1031 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1032 where C: Context + PrePost<Self>, Self: Sized
c1a9b12d
SL
1033 {
1034 if let Some(ref vd) = self.contents.get() {
2b03887a 1035 if let Some(r) = vd.iter().nth(index) {
c1a9b12d
SL
1036 r.descend_into_self(context);
1037 }
1038 }
1039 }
1040}
1041
1042impl<'a> Children<'a> for VM<'a> {
b039eaaf
SL
1043 fn count_children(&self) -> usize {
1044 if let Some(m) = self.contents.get() { m.iter().count() } else { 0 }
1045 }
1046 fn descend_one_child<C>(&self, context: &mut C, index: usize)
c1a9b12d
SL
1047 where C: Context + PrePost<VM<'a>>
1048 {
1049 if let Some(ref vd) = self.contents.get() {
2b03887a 1050 if let Some((_idx, r)) = vd.iter().nth(index) {
c1a9b12d
SL
1051 r.descend_into_self(context);
1052 }
1053 }
1054 }
1055}
1056
1057impl<'a> Children<'a> for LL<'a> {
b039eaaf
SL
1058 fn count_children(&self) -> usize {
1059 if let Some(l) = self.contents.get() { l.iter().count() } else { 0 }
1060 }
1061 fn descend_one_child<C>(&self, context: &mut C, index: usize)
c1a9b12d
SL
1062 where C: Context + PrePost<LL<'a>>
1063 {
1064 if let Some(ref ll) = self.contents.get() {
2b03887a 1065 if let Some(r) = ll.iter().nth(index) {
c1a9b12d
SL
1066 r.descend_into_self(context);
1067 }
1068 }
1069 }
1070}
1071
1072impl<'a> Children<'a> for BH<'a> {
b039eaaf
SL
1073 fn count_children(&self) -> usize {
1074 if let Some(h) = self.contents.get() { h.iter().count() } else { 0 }
1075 }
1076 fn descend_one_child<C>(&self, context: &mut C, index: usize)
c1a9b12d
SL
1077 where C: Context + PrePost<BH<'a>>
1078 {
1079 if let Some(ref bh) = self.contents.get() {
2b03887a 1080 if let Some(r) = bh.iter().nth(index) {
c1a9b12d
SL
1081 r.descend_into_self(context);
1082 }
1083 }
1084 }
1085}
1086
1087impl<'a> Children<'a> for BTM<'a> {
b039eaaf
SL
1088 fn count_children(&self) -> usize {
1089 if let Some(m) = self.contents.get() { 2 * m.iter().count() } else { 0 }
1090 }
1091 fn descend_one_child<C>(&self, context: &mut C, index: usize)
c1a9b12d
SL
1092 where C: Context + PrePost<BTM<'a>>
1093 {
1094 if let Some(ref bh) = self.contents.get() {
2b03887a 1095 if let Some((k, v)) = bh.iter().nth(index / 2) {
b039eaaf 1096 [k, v][index % 2].descend_into_self(context);
c1a9b12d
SL
1097 }
1098 }
1099 }
1100}
1101
1102impl<'a> Children<'a> for BTS<'a> {
b039eaaf
SL
1103 fn count_children(&self) -> usize {
1104 if let Some(s) = self.contents.get() { s.iter().count() } else { 0 }
1105 }
1106 fn descend_one_child<C>(&self, context: &mut C, index: usize)
c1a9b12d
SL
1107 where C: Context + PrePost<BTS<'a>>
1108 {
1109 if let Some(ref bh) = self.contents.get() {
2b03887a 1110 if let Some(r) = bh.iter().nth(index) {
c1a9b12d
SL
1111 r.descend_into_self(context);
1112 }
1113 }
1114 }
1115}
1116
1117#[derive(Copy, Clone)]
1118struct ContextData {
1119 curr_depth: usize,
1120 max_depth: usize,
1121 visited: usize,
1122 max_visits: usize,
1123 skipped: usize,
1124 curr_mark: u32,
1125 saw_prev_marked: bool,
b039eaaf 1126 control_bits: u64,
c1a9b12d
SL
1127}
1128
1129impl Context for ContextData {
b039eaaf
SL
1130 fn next_index(&mut self, len: usize) -> usize {
1131 if len < 2 { return 0; }
1132 let mut pow2 = len.next_power_of_two();
1133 let _pow2_orig = pow2;
1134 let mut idx = 0;
1135 let mut bits = self.control_bits;
1136 while pow2 > 1 {
1137 idx = (idx << 1) | (bits & 1) as usize;
1138 bits = bits >> 1;
1139 pow2 = pow2 >> 1;
1140 }
1141 idx = idx % len;
1142 // println!("next_index({} [{:b}]) says {}, pre(bits): {:b} post(bits): {:b}",
1143 // len, _pow2_orig, idx, self.control_bits, bits);
1144 self.control_bits = bits;
1145 return idx;
1146 }
c1a9b12d
SL
1147 fn should_act(&self) -> bool {
1148 self.curr_depth < self.max_depth && self.visited < self.max_visits
1149 }
1150 fn increase_visited(&mut self) { self.visited += 1; }
1151 fn increase_skipped(&mut self) { self.skipped += 1; }
1152 fn increase_depth(&mut self) { self.curr_depth += 1; }
1153 fn decrease_depth(&mut self) { self.curr_depth -= 1; }
1154}
1155
1156impl<T:Named+Marked<u32>> PrePost<T> for ContextData {
1157 fn pre(&mut self, t: &T) {
1158 for _ in 0..self.curr_depth {
1159 if PRINT { print!(" "); }
1160 }
1161 if PRINT { println!("prev {}", t.name()); }
1162 if t.mark() == self.curr_mark {
1163 for _ in 0..self.curr_depth {
1164 if PRINT { print!(" "); }
1165 }
1166 if PRINT { println!("(probably previously marked)"); }
1167 self.saw_prev_marked = true;
1168 }
1169 t.set_mark(self.curr_mark);
1170 }
1171 fn post(&mut self, t: &T) {
1172 for _ in 0..self.curr_depth {
1173 if PRINT { print!(" "); }
1174 }
1175 if PRINT { println!("post {}", t.name()); }
1176 }
1177 fn hit_limit(&mut self, t: &T) {
1178 for _ in 0..self.curr_depth {
1179 if PRINT { print!(" "); }
1180 }
1181 if PRINT { println!("LIMIT {}", t.name()); }
1182 }
1183}