]> git.lizzy.rs Git - rust.git/blob - src/fuzzer/cycles.rs
Update CC fuzzer
[rust.git] / src / fuzzer / cycles.rs
1 use std;
2 import std::rand;
3 import uint::range;
4
5 // random uint less than n
6 fn under(r : rand::rng, n : uint) -> uint { assert n != 0u; r.next() as uint % n }
7
8 // random choice from a vec
9 fn choice<T: copy>(r : rand::rng, v : [const T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }
10
11 // k in n chance of being true
12 fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k }
13
14
15 const iters : uint = 1000u;
16 const vlen  : uint = 100u;
17
18 enum maybe_pointy {
19     none,
20     p(@pointy)
21 }
22
23 type pointy = {
24     mut a : maybe_pointy,
25     mut b : ~maybe_pointy,
26     mut c : @maybe_pointy,
27
28     mut f : fn@()->(),
29     mut g : fn~()->(),
30
31     mut m : [maybe_pointy],
32     mut n : [mut maybe_pointy],
33     mut o : {x : int, y : maybe_pointy}
34 };
35 // To add: objects; ifaces; anything type-parameterized?
36
37 fn empty_pointy() -> @pointy {
38     ret @{
39         mut a : none,
40         mut b : ~none,
41         mut c : @none,
42
43         mut f : fn@()->(){},
44         mut g : fn~()->(){},
45
46         mut m : [],
47         mut n : [mut],
48         mut o : {x : 0, y : none}
49     }
50 }
51
52 fn nopP(_x : @pointy) { }
53 fn nop<T>(_x: T) { }
54
55 fn test_cycles(r : rand::rng, k: uint, n: uint)
56 {
57     let v : [mut @pointy] = [mut];
58
59     // Create a graph with no edges
60     range(0u, vlen) {|_i|
61         v += [mut empty_pointy()];
62     }
63
64     // Fill in the graph with random edges, with density k/n
65     range(0u, vlen) {|i|
66         if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); }
67         if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); }
68         if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); }
69
70         if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); }
71         //if (false)               { v[i].g = bind (fn~(_x: @pointy) { })(choice(r, v)); }
72           // https://github.com/mozilla/rust/issues/1899
73
74         if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
75         if (likelihood(r, k, n)) { v[i].n += [mut p(choice(r, v))]; }
76         if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
77     }
78
79     // Drop refs one at a time
80     range(0u, vlen) {|i|
81         v[i] = empty_pointy()
82     }
83 }
84
85 fn main()
86 {
87     let r = rand::rng();
88     range(0u, iters) {|i|
89         test_cycles(r, i, iters);
90     }
91 }