]>
git.proxmox.com Git - rustc.git/blob - compiler/rustc_data_structures/src/transitive_relation/tests.rs
3 impl<T
: Eq
+ Hash
> TransitiveRelation
<T
> {
4 /// A "best" parent in some sense. See `parents` and
5 /// `postdom_upper_bound` for more details.
6 fn postdom_parent(&self, a
: &T
) -> Option
<&T
> {
7 self.mutual_immediate_postdominator(self.parents(a
))
13 let mut relation
= TransitiveRelation
::default();
14 relation
.add("a", "b");
15 relation
.add("a", "c");
16 assert
!(relation
.contains(&"a", &"c"));
17 assert
!(relation
.contains(&"a", &"b"));
18 assert
!(!relation
.contains(&"b", &"a"));
19 assert
!(!relation
.contains(&"a", &"d"));
23 fn test_many_steps() {
24 let mut relation
= TransitiveRelation
::default();
25 relation
.add("a", "b");
26 relation
.add("a", "c");
27 relation
.add("a", "f");
29 relation
.add("b", "c");
30 relation
.add("b", "d");
31 relation
.add("b", "e");
33 relation
.add("e", "g");
35 assert
!(relation
.contains(&"a", &"b"));
36 assert
!(relation
.contains(&"a", &"c"));
37 assert
!(relation
.contains(&"a", &"d"));
38 assert
!(relation
.contains(&"a", &"e"));
39 assert
!(relation
.contains(&"a", &"f"));
40 assert
!(relation
.contains(&"a", &"g"));
42 assert
!(relation
.contains(&"b", &"g"));
44 assert
!(!relation
.contains(&"a", &"x"));
45 assert
!(!relation
.contains(&"b", &"f"));
54 let mut relation
= TransitiveRelation
::default();
55 relation
.add("a", "tcx");
56 relation
.add("b", "tcx");
57 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"tcx"]);
58 assert_eq
!(relation
.parents(&"a"), vec
![&"tcx"]);
59 assert_eq
!(relation
.parents(&"b"), vec
![&"tcx"]);
63 fn mubs_best_choice1() {
71 // This tests a particular state in the algorithm, in which we
72 // need the second pare down call to get the right result (after
73 // intersection, we have [1, 2], but 2 -> 1).
75 let mut relation
= TransitiveRelation
::default();
76 relation
.add("0", "1");
77 relation
.add("0", "2");
79 relation
.add("2", "1");
81 relation
.add("3", "1");
82 relation
.add("3", "2");
84 assert_eq
!(relation
.minimal_upper_bounds(&"0", &"3"), vec
![&"2"]);
85 assert_eq
!(relation
.parents(&"0"), vec
![&"2"]);
86 assert_eq
!(relation
.parents(&"2"), vec
![&"1"]);
87 assert
!(relation
.parents(&"1").is_empty());
91 fn mubs_best_choice2() {
99 // Like the precedecing test, but in this case intersection is [2,
100 // 1], and hence we rely on the first pare down call.
102 let mut relation
= TransitiveRelation
::default();
103 relation
.add("0", "1");
104 relation
.add("0", "2");
106 relation
.add("1", "2");
108 relation
.add("3", "1");
109 relation
.add("3", "2");
111 assert_eq
!(relation
.minimal_upper_bounds(&"0", &"3"), vec
![&"1"]);
112 assert_eq
!(relation
.parents(&"0"), vec
![&"1"]);
113 assert_eq
!(relation
.parents(&"1"), vec
![&"2"]);
114 assert
!(relation
.parents(&"2").is_empty());
118 fn mubs_no_best_choice() {
119 // in this case, the intersection yields [1, 2], and the "pare
120 // down" calls find nothing to remove.
121 let mut relation
= TransitiveRelation
::default();
122 relation
.add("0", "1");
123 relation
.add("0", "2");
125 relation
.add("3", "1");
126 relation
.add("3", "2");
128 assert_eq
!(relation
.minimal_upper_bounds(&"0", &"3"), vec
![&"1", &"2"]);
129 assert_eq
!(relation
.parents(&"0"), vec
![&"1", &"2"]);
130 assert_eq
!(relation
.parents(&"3"), vec
![&"1", &"2"]);
134 fn mubs_best_choice_scc() {
135 // in this case, 1 and 2 form a cycle; we pick arbitrarily (but
138 let mut relation
= TransitiveRelation
::default();
139 relation
.add("0", "1");
140 relation
.add("0", "2");
142 relation
.add("1", "2");
143 relation
.add("2", "1");
145 relation
.add("3", "1");
146 relation
.add("3", "2");
148 assert_eq
!(relation
.minimal_upper_bounds(&"0", &"3"), vec
![&"1"]);
149 assert_eq
!(relation
.parents(&"0"), vec
![&"1"]);
153 fn pdub_crisscross() {
154 // diagonal edges run left-to-right
160 let mut relation
= TransitiveRelation
::default();
161 relation
.add("a", "a1");
162 relation
.add("a", "b1");
163 relation
.add("b", "a1");
164 relation
.add("b", "b1");
165 relation
.add("a1", "x");
166 relation
.add("b1", "x");
168 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"a1", &"b1"]);
169 assert_eq
!(relation
.postdom_upper_bound(&"a", &"b"), Some(&"x"));
170 assert_eq
!(relation
.postdom_parent(&"a"), Some(&"x"));
171 assert_eq
!(relation
.postdom_parent(&"b"), Some(&"x"));
175 fn pdub_crisscross_more() {
176 // diagonal edges run left-to-right
177 // a -> a1 -> a2 -> a3 -> x
180 // b -> b1 -> b2 ---------+
182 let mut relation
= TransitiveRelation
::default();
183 relation
.add("a", "a1");
184 relation
.add("a", "b1");
185 relation
.add("b", "a1");
186 relation
.add("b", "b1");
188 relation
.add("a1", "a2");
189 relation
.add("a1", "b2");
190 relation
.add("b1", "a2");
191 relation
.add("b1", "b2");
193 relation
.add("a2", "a3");
195 relation
.add("a3", "x");
196 relation
.add("b2", "x");
198 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"a1", &"b1"]);
199 assert_eq
!(relation
.minimal_upper_bounds(&"a1", &"b1"), vec
![&"a2", &"b2"]);
200 assert_eq
!(relation
.postdom_upper_bound(&"a", &"b"), Some(&"x"));
202 assert_eq
!(relation
.postdom_parent(&"a"), Some(&"x"));
203 assert_eq
!(relation
.postdom_parent(&"b"), Some(&"x"));
213 let mut relation
= TransitiveRelation
::default();
214 relation
.add("a", "a1");
215 relation
.add("b", "b1");
216 relation
.add("a1", "x");
217 relation
.add("b1", "x");
219 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"x"]);
220 assert_eq
!(relation
.postdom_upper_bound(&"a", &"b"), Some(&"x"));
222 assert_eq
!(relation
.postdom_parent(&"a"), Some(&"a1"));
223 assert_eq
!(relation
.postdom_parent(&"b"), Some(&"b1"));
224 assert_eq
!(relation
.postdom_parent(&"a1"), Some(&"x"));
225 assert_eq
!(relation
.postdom_parent(&"b1"), Some(&"x"));
229 fn mubs_intermediate_node_on_one_side_only() {
235 // "digraph { a -> c -> d; b -> d; }",
236 let mut relation
= TransitiveRelation
::default();
237 relation
.add("a", "c");
238 relation
.add("c", "d");
239 relation
.add("b", "d");
241 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"d"]);
254 // "digraph { a -> c -> d; d -> c; a -> d; b -> d; }",
255 let mut relation
= TransitiveRelation
::default();
256 relation
.add("a", "c");
257 relation
.add("c", "d");
258 relation
.add("d", "c");
259 relation
.add("a", "d");
260 relation
.add("b", "d");
262 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"c"]);
274 // "digraph { a -> c -> d; d -> c; b -> d; b -> c; }",
275 let mut relation
= TransitiveRelation
::default();
276 relation
.add("a", "c");
277 relation
.add("c", "d");
278 relation
.add("d", "c");
279 relation
.add("b", "d");
280 relation
.add("b", "c");
282 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"c"]);
294 // "digraph { a -> c -> d -> e -> c; b -> d; b -> e; }",
295 let mut relation
= TransitiveRelation
::default();
296 relation
.add("a", "c");
297 relation
.add("c", "d");
298 relation
.add("d", "e");
299 relation
.add("e", "c");
300 relation
.add("b", "d");
301 relation
.add("b", "e");
303 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"c"]);
316 // "digraph { a -> c -> d -> e -> c; a -> d; b -> e; }"
317 let mut relation
= TransitiveRelation
::default();
318 relation
.add("a", "c");
319 relation
.add("c", "d");
320 relation
.add("d", "e");
321 relation
.add("e", "c");
322 relation
.add("a", "d");
323 relation
.add("b", "e");
325 assert_eq
!(relation
.minimal_upper_bounds(&"a", &"b"), vec
![&"c"]);
330 // An example that was misbehaving in the compiler.
337 // plus a bunch of self-loops
339 // Here `->` represents `<=` and `0` is `'static`.
355 let mut relation
= TransitiveRelation
::default();
356 for (a
, b
) in pairs
{
360 let p
= relation
.postdom_parent(&3);
361 assert_eq
!(p
, Some(&0));