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