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