]> git.lizzy.rs Git - rust.git/blob - src/test/debuginfo/recursive-struct.rs
Regression test for issue #54477.
[rust.git] / src / test / debuginfo / recursive-struct.rs
1 // Copyright 2013-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 // ignore-tidy-linelength
12 // ignore-lldb
13 // ignore-gdb-version: 7.11.90 - 7.12.9
14
15 // compile-flags:-g
16
17 // gdb-command:run
18
19 // gdb-command:print stack_unique.value
20 // gdb-check:$1 = 0
21 // gdbg-command:print stack_unique.next.RUST$ENCODED$ENUM$0$Empty.val->value
22 // gdbr-command:print stack_unique.next.val.value
23 // gdb-check:$2 = 1
24
25 // gdbg-command:print unique_unique->value
26 // gdbr-command:print unique_unique.value
27 // gdb-check:$3 = 2
28 // gdbg-command:print unique_unique->next.RUST$ENCODED$ENUM$0$Empty.val->value
29 // gdbr-command:print unique_unique.next.val.value
30 // gdb-check:$4 = 3
31
32 // gdb-command:print vec_unique[0].value
33 // gdb-check:$5 = 6.5
34 // gdbg-command:print vec_unique[0].next.RUST$ENCODED$ENUM$0$Empty.val->value
35 // gdbr-command:print vec_unique[0].next.val.value
36 // gdb-check:$6 = 7.5
37
38 // gdbg-command:print borrowed_unique->value
39 // gdbr-command:print borrowed_unique.value
40 // gdb-check:$7 = 8.5
41 // gdbg-command:print borrowed_unique->next.RUST$ENCODED$ENUM$0$Empty.val->value
42 // gdbr-command:print borrowed_unique.next.val.value
43 // gdb-check:$8 = 9.5
44
45 // LONG CYCLE
46 // gdb-command:print long_cycle1.value
47 // gdb-check:$9 = 20
48 // gdbg-command:print long_cycle1.next->value
49 // gdbr-command:print long_cycle1.next.value
50 // gdb-check:$10 = 21
51 // gdbg-command:print long_cycle1.next->next->value
52 // gdbr-command:print long_cycle1.next.next.value
53 // gdb-check:$11 = 22
54 // gdbg-command:print long_cycle1.next->next->next->value
55 // gdbr-command:print long_cycle1.next.next.next.value
56 // gdb-check:$12 = 23
57
58 // gdb-command:print long_cycle2.value
59 // gdb-check:$13 = 24
60 // gdbg-command:print long_cycle2.next->value
61 // gdbr-command:print long_cycle2.next.value
62 // gdb-check:$14 = 25
63 // gdbg-command:print long_cycle2.next->next->value
64 // gdbr-command:print long_cycle2.next.next.value
65 // gdb-check:$15 = 26
66
67 // gdb-command:print long_cycle3.value
68 // gdb-check:$16 = 27
69 // gdbg-command:print long_cycle3.next->value
70 // gdbr-command:print long_cycle3.next.value
71 // gdb-check:$17 = 28
72
73 // gdb-command:print long_cycle4.value
74 // gdb-check:$18 = 29.5
75
76 // gdbg-command:print (*****long_cycle_w_anonymous_types).value
77 // gdbr-command:print long_cycle_w_anonymous_types.value
78 // gdb-check:$19 = 30
79
80 // gdbg-command:print (*****((*****long_cycle_w_anonymous_types).next.RUST$ENCODED$ENUM$0$Empty.val)).value
81 // gdbr-command:print long_cycle_w_anonymous_types.next.val.value
82 // gdb-check:$20 = 31
83
84 // gdb-command:continue
85
86 #![allow(unused_variables)]
87 #![feature(box_syntax)]
88 #![feature(omit_gdb_pretty_printer_section)]
89 #![omit_gdb_pretty_printer_section]
90
91 use self::Opt::{Empty, Val};
92
93 enum Opt<T> {
94     Empty,
95     Val { val: T }
96 }
97
98 struct UniqueNode<T> {
99     next: Opt<Box<UniqueNode<T>>>,
100     value: T
101 }
102
103 struct LongCycle1<T> {
104     next: Box<LongCycle2<T>>,
105     value: T,
106 }
107
108 struct LongCycle2<T> {
109     next: Box<LongCycle3<T>>,
110     value: T,
111 }
112
113 struct LongCycle3<T> {
114     next: Box<LongCycle4<T>>,
115     value: T,
116 }
117
118 struct LongCycle4<T> {
119     next: Option<Box<LongCycle1<T>>>,
120     value: T,
121 }
122
123 struct LongCycleWithAnonymousTypes {
124     next: Opt<Box<Box<Box<Box<Box<LongCycleWithAnonymousTypes>>>>>>,
125     value: usize,
126 }
127
128 // This test case makes sure that recursive structs are properly described. The Node structs are
129 // generic so that we can have a new type (that newly needs to be described) for the different
130 // cases. The potential problem with recursive types is that the DI generation algorithm gets
131 // trapped in an endless loop. To make sure, we actually test this in the different cases, we have
132 // to operate on a new type each time, otherwise we would just hit the DI cache for all but the
133 // first case.
134
135 // The different cases below (stack_*, unique_*, box_*, etc) are set up so that the type description
136 // algorithm will enter the type reference cycle that is created by a recursive definition from a
137 // different context each time.
138
139 // The "long cycle" cases are constructed to span a longer, indirect recursion cycle between types.
140 // The different locals will cause the DI algorithm to enter the type reference cycle at different
141 // points.
142
143 fn main() {
144     let stack_unique: UniqueNode<u16> = UniqueNode {
145         next: Val {
146             val: box UniqueNode {
147                 next: Empty,
148                 value: 1,
149             }
150         },
151         value: 0,
152     };
153
154     let unique_unique: Box<UniqueNode<u32>> = box UniqueNode {
155         next: Val {
156             val: box UniqueNode {
157                 next: Empty,
158                 value: 3,
159             }
160         },
161         value: 2,
162     };
163
164     let vec_unique: [UniqueNode<f32>; 1] = [UniqueNode {
165         next: Val {
166             val: box UniqueNode {
167                 next: Empty,
168                 value: 7.5,
169             }
170         },
171         value: 6.5,
172     }];
173
174     let borrowed_unique: &UniqueNode<f64> = &UniqueNode {
175         next: Val {
176             val: box UniqueNode {
177                 next: Empty,
178                 value: 9.5,
179             }
180         },
181         value: 8.5,
182     };
183
184     // LONG CYCLE
185     let long_cycle1: LongCycle1<u16> = LongCycle1 {
186         next: box LongCycle2 {
187             next: box LongCycle3 {
188                 next: box LongCycle4 {
189                     next: None,
190                     value: 23,
191                 },
192                 value: 22,
193             },
194             value: 21
195         },
196         value: 20
197     };
198
199     let long_cycle2: LongCycle2<u32> = LongCycle2 {
200         next: box LongCycle3 {
201             next: box LongCycle4 {
202                 next: None,
203                 value: 26,
204             },
205             value: 25,
206         },
207         value: 24
208     };
209
210     let long_cycle3: LongCycle3<u64> = LongCycle3 {
211         next: box LongCycle4 {
212             next: None,
213             value: 28,
214         },
215         value: 27,
216     };
217
218     let long_cycle4: LongCycle4<f32> = LongCycle4 {
219         next: None,
220         value: 29.5,
221     };
222
223     // It's important that LongCycleWithAnonymousTypes is encountered only at the end of the
224     // `box` chain.
225     let long_cycle_w_anonymous_types = box box box box box LongCycleWithAnonymousTypes {
226         next: Val {
227             val: box box box box box LongCycleWithAnonymousTypes {
228                 next: Empty,
229                 value: 31,
230             }
231         },
232         value: 30
233     };
234
235     zzz(); // #break
236 }
237
238 fn zzz() {()}