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