]> git.lizzy.rs Git - rust.git/blob - src/librustc_data_structures/obligation_forest/test.rs
Auto merge of #30931 - oli-obk:trans_disr_newtype, r=arielb1
[rust.git] / src / librustc_data_structures / obligation_forest / test.rs
1 // Copyright 2014 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.
4 //
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.
10
11 use super::{ObligationForest, Outcome, Error};
12
13 #[test]
14 fn push_pop() {
15     let mut forest = ObligationForest::new();
16     forest.push_root("A");
17     forest.push_root("B");
18     forest.push_root("C");
19
20     // first round, B errors out, A has subtasks, and C completes, creating this:
21     //      A |-> A.1
22     //        |-> A.2
23     //        |-> A.3
24     let Outcome { completed: ok, errors: err, .. } = forest.process_obligations(|obligation, _| {
25         match *obligation {
26             "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
27             "B" => Err("B is for broken"),
28             "C" => Ok(Some(vec![])),
29             _ => unreachable!(),
30         }
31     });
32     assert_eq!(ok, vec!["C"]);
33     assert_eq!(err, vec![Error {error: "B is for broken",
34                                 backtrace: vec!["B"]}]);
35
36     // second round: two delays, one success, creating an uneven set of subtasks:
37     //      A |-> A.1
38     //        |-> A.2
39     //        |-> A.3 |-> A.3.i
40     //      D |-> D.1
41     //        |-> D.2
42     forest.push_root("D");
43     let Outcome { completed: ok, errors: err, .. }: Outcome<&'static str, ()> =
44         forest.process_obligations(|obligation, _| {
45             match *obligation {
46                 "A.1" => Ok(None),
47                 "A.2" => Ok(None),
48                 "A.3" => Ok(Some(vec!["A.3.i"])),
49                 "D" => Ok(Some(vec!["D.1", "D.2"])),
50                 _ => unreachable!(),
51             }
52         });
53     assert_eq!(ok, Vec::<&'static str>::new());
54     assert_eq!(err, Vec::new());
55
56
57     // third round: ok in A.1 but trigger an error in A.2. Check that it
58     // propagates to A.3.i, but not D.1 or D.2.
59     //      D |-> D.1 |-> D.1.i
60     //        |-> D.2 |-> D.2.i
61     let Outcome { completed: ok, errors: err, .. } = forest.process_obligations(|obligation, _| {
62         match *obligation {
63             "A.1" => Ok(Some(vec![])),
64             "A.2" => Err("A is for apple"),
65             "D.1" => Ok(Some(vec!["D.1.i"])),
66             "D.2" => Ok(Some(vec!["D.2.i"])),
67             _ => unreachable!(),
68         }
69     });
70     assert_eq!(ok, vec!["A.1"]);
71     assert_eq!(err, vec![Error { error: "A is for apple",
72                                  backtrace: vec!["A.2", "A"] }]);
73
74     // fourth round: error in D.1.i that should propagate to D.2.i
75     let Outcome { completed: ok, errors: err, .. } = forest.process_obligations(|obligation, _| {
76         match *obligation {
77             "D.1.i" => Err("D is for dumb"),
78             _ => panic!("unexpected obligation {:?}", obligation),
79         }
80     });
81     assert_eq!(ok, Vec::<&'static str>::new());
82     assert_eq!(err, vec![Error { error: "D is for dumb",
83                                  backtrace: vec!["D.1.i", "D.1", "D"] }]);
84 }
85
86 // Test that if a tree with grandchildren succeeds, everything is
87 // reported as expected:
88 // A
89 //   A.1
90 //   A.2
91 //      A.2.i
92 //      A.2.ii
93 //   A.3
94 #[test]
95 fn success_in_grandchildren() {
96     let mut forest = ObligationForest::new();
97     forest.push_root("A");
98
99     let Outcome { completed: ok, errors: err, .. } =
100         forest.process_obligations::<(),_>(|obligation, _| {
101             match *obligation {
102                 "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
103                 _ => unreachable!(),
104             }
105         });
106     assert!(ok.is_empty());
107     assert!(err.is_empty());
108
109     let Outcome { completed: ok, errors: err, .. } =
110         forest.process_obligations::<(),_>(|obligation, _| {
111             match *obligation {
112                 "A.1" => Ok(Some(vec![])),
113                 "A.2" => Ok(Some(vec!["A.2.i", "A.2.ii"])),
114                 "A.3" => Ok(Some(vec![])),
115                 _ => unreachable!(),
116             }
117         });
118     assert_eq!(ok, vec!["A.3", "A.1"]);
119     assert!(err.is_empty());
120
121     let Outcome { completed: ok, errors: err, .. } =
122         forest.process_obligations::<(),_>(|obligation, _| {
123             match *obligation {
124                 "A.2.i" => Ok(Some(vec!["A.2.i.a"])),
125                 "A.2.ii" => Ok(Some(vec![])),
126                 _ => unreachable!(),
127             }
128         });
129     assert_eq!(ok, vec!["A.2.ii"]);
130     assert!(err.is_empty());
131
132     let Outcome { completed: ok, errors: err, .. } =
133         forest.process_obligations::<(),_>(|obligation, _| {
134             match *obligation {
135                 "A.2.i.a" => Ok(Some(vec![])),
136                 _ => unreachable!(),
137             }
138         });
139     assert_eq!(ok, vec!["A.2.i.a", "A.2.i", "A.2", "A"]);
140     assert!(err.is_empty());
141
142     let Outcome { completed: ok, errors: err, .. } =
143         forest.process_obligations::<(),_>(|_, _| unreachable!());
144     assert!(ok.is_empty());
145     assert!(err.is_empty());
146 }
147
148 #[test]
149 fn to_errors_no_throw() {
150     // check that converting multiple children with common parent (A)
151     // only yields one of them (and does not panic, in particular).
152     let mut forest = ObligationForest::new();
153     forest.push_root("A");
154     let Outcome { completed: ok, errors: err, .. } =
155         forest.process_obligations::<(),_>(|obligation, _| {
156             match *obligation {
157                 "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
158                 _ => unreachable!(),
159             }
160         });
161     assert_eq!(ok.len(), 0);
162     assert_eq!(err.len(), 0);
163     let errors = forest.to_errors(());
164     assert_eq!(errors.len(), 1);
165 }
166
167 #[test]
168 fn backtrace() {
169     // check that converting multiple children with common parent (A)
170     // only yields one of them (and does not panic, in particular).
171     let mut forest: ObligationForest<&'static str> = ObligationForest::new();
172     forest.push_root("A");
173     let Outcome { completed: ok, errors: err, .. } =
174         forest.process_obligations::<(),_>(|obligation, mut backtrace| {
175             assert!(backtrace.next().is_none());
176             match *obligation {
177                 "A" => Ok(Some(vec!["A.1"])),
178                 _ => unreachable!(),
179             }
180         });
181     assert!(ok.is_empty());
182     assert!(err.is_empty());
183     let Outcome { completed: ok, errors: err, .. } =
184         forest.process_obligations::<(),_>(|obligation, mut backtrace| {
185             assert!(backtrace.next().unwrap() == &"A");
186             assert!(backtrace.next().is_none());
187             match *obligation {
188                 "A.1" => Ok(Some(vec!["A.1.i"])),
189                 _ => unreachable!(),
190             }
191         });
192     assert!(ok.is_empty());
193     assert!(err.is_empty());
194     let Outcome { completed: ok, errors: err, .. } =
195         forest.process_obligations::<(),_>(|obligation, mut backtrace| {
196             assert!(backtrace.next().unwrap() == &"A.1");
197             assert!(backtrace.next().unwrap() == &"A");
198             assert!(backtrace.next().is_none());
199             match *obligation {
200                 "A.1.i" => Ok(None),
201                 _ => unreachable!(),
202             }
203         });
204     assert_eq!(ok.len(), 0);
205     assert!(err.is_empty());
206 }