recursive-struct.rs 5.8 KB
Newer Older
1
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 3 4 5 6 7 8 9 10
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

11
// ignore-tidy-linelength
12
// ignore-android: FIXME(#10381)
13
// ignore-lldb
14

D
Daniel Micay 已提交
15

16
// compile-flags:-g
17 18 19 20 21 22 23
// gdb-command:set print pretty off
// gdb-command:rbreak zzz
// gdb-command:run
// gdb-command:finish

// gdb-command:print stack_unique.value
// gdb-check:$1 = 0
24
// gdb-command:print stack_unique.next.RUST$ENCODED$ENUM$0$Empty.val->value
25 26 27 28
// gdb-check:$2 = 1

// gdb-command:print unique_unique->value
// gdb-check:$3 = 2
29
// gdb-command:print unique_unique->next.RUST$ENCODED$ENUM$0$Empty.val->value
30 31 32 33
// gdb-check:$4 = 3

// gdb-command:print vec_unique[0].value
// gdb-check:$7 = 6.5
34
// gdb-command:print vec_unique[0].next.RUST$ENCODED$ENUM$0$Empty.val->value
35 36 37 38
// gdb-check:$8 = 7.5

// gdb-command:print borrowed_unique->value
// gdb-check:$9 = 8.5
39
// gdb-command:print borrowed_unique->next.RUST$ENCODED$ENUM$0$Empty.val->value
40
// gdb-check:$10 = 9.5
41 42

// LONG CYCLE
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
// gdb-command:print long_cycle1.value
// gdb-check:$21 = 20
// gdb-command:print long_cycle1.next->value
// gdb-check:$22 = 21
// gdb-command:print long_cycle1.next->next->value
// gdb-check:$23 = 22
// gdb-command:print long_cycle1.next->next->next->value
// gdb-check:$24 = 23

// gdb-command:print long_cycle2.value
// gdb-check:$25 = 24
// gdb-command:print long_cycle2.next->value
// gdb-check:$26 = 25
// gdb-command:print long_cycle2.next->next->value
// gdb-check:$27 = 26

// gdb-command:print long_cycle3.value
// gdb-check:$28 = 27
// gdb-command:print long_cycle3.next->value
// gdb-check:$29 = 28

// gdb-command:print long_cycle4.value
// gdb-check:$30 = 29.5

// gdb-command:print (*****long_cycle_w_anonymous_types).value
// gdb-check:$31 = 30

70
// gdb-command:print (*****((*****long_cycle_w_anonymous_types).next.RUST$ENCODED$ENUM$0$Empty.val)).value
71 72 73
// gdb-check:$32 = 31

// gdb-command:continue
74

75 76
#![allow(unused_variable)]
#![feature(struct_variant)]
77 78 79 80 81 82 83

enum Opt<T> {
    Empty,
    Val { val: T }
}

struct UniqueNode<T> {
84
    next: Opt<Box<UniqueNode<T>>>,
85 86 87 88
    value: T
}

struct LongCycle1<T> {
89
    next: Box<LongCycle2<T>>,
90 91 92 93
    value: T,
}

struct LongCycle2<T> {
94
    next: Box<LongCycle3<T>>,
95 96 97 98
    value: T,
}

struct LongCycle3<T> {
99
    next: Box<LongCycle4<T>>,
100 101 102 103
    value: T,
}

struct LongCycle4<T> {
104
    next: Option<Box<LongCycle1<T>>>,
105 106 107 108
    value: T,
}

struct LongCycleWithAnonymousTypes {
109
    next: Opt<Box<Box<Box<Box<Box<LongCycleWithAnonymousTypes>>>>>>,
110 111 112 113 114
    value: uint,
}

// This test case makes sure that recursive structs are properly described. The Node structs are
// generic so that we can have a new type (that newly needs to be described) for the different
115 116 117 118
// cases. The potential problem with recursive types is that the DI generation algorithm gets
// trapped in an endless loop. To make sure, we actually test this in the different cases, we have
// to operate on a new type each time, otherwise we would just hit the DI cache for all but the
// first case.
119 120 121

// The different cases below (stack_*, unique_*, box_*, etc) are set up so that the type description
// algorithm will enter the type reference cycle that is created by a recursive definition from a
122
// different context each time.
123 124 125 126 127 128 129 130

// The "long cycle" cases are constructed to span a longer, indirect recursion cycle between types.
// The different locals will cause the DI algorithm to enter the type reference cycle at different
// points.

fn main() {
    let stack_unique: UniqueNode<u16> = UniqueNode {
        next: Val {
131
            val: box UniqueNode {
132 133 134 135 136 137 138
                next: Empty,
                value: 1_u16,
            }
        },
        value: 0_u16,
    };

139
    let unique_unique: Box<UniqueNode<u32>> = box UniqueNode {
140
        next: Val {
141
            val: box UniqueNode {
142 143 144 145 146 147 148 149 150
                next: Empty,
                value: 3,
            }
        },
        value: 2,
    };

    let vec_unique: [UniqueNode<f32>, ..1] = [UniqueNode {
        next: Val {
151
            val: box UniqueNode {
152 153 154 155 156 157 158 159 160
                next: Empty,
                value: 7.5,
            }
        },
        value: 6.5,
    }];

    let borrowed_unique: &UniqueNode<f64> = &UniqueNode {
        next: Val {
161
            val: box UniqueNode {
162 163 164 165 166 167 168 169 170
                next: Empty,
                value: 9.5,
            }
        },
        value: 8.5,
    };

    // LONG CYCLE
    let long_cycle1: LongCycle1<u16> = LongCycle1 {
171 172 173
        next: box LongCycle2 {
            next: box LongCycle3 {
                next: box LongCycle4 {
174 175 176 177 178 179 180 181 182 183 184
                    next: None,
                    value: 23,
                },
                value: 22,
            },
            value: 21
        },
        value: 20
    };

    let long_cycle2: LongCycle2<u32> = LongCycle2 {
185 186
        next: box LongCycle3 {
            next: box LongCycle4 {
187 188 189 190 191 192 193 194 195
                next: None,
                value: 26,
            },
            value: 25,
        },
        value: 24
    };

    let long_cycle3: LongCycle3<u64> = LongCycle3 {
196
        next: box LongCycle4 {
197 198 199 200 201 202 203 204 205 206 207 208
            next: None,
            value: 28,
        },
        value: 27,
    };

    let long_cycle4: LongCycle4<f32> = LongCycle4 {
        next: None,
        value: 29.5,
    };

    // It's important that LongCycleWithAnonymousTypes is encountered only at the end of the
209 210
    // `box` chain.
    let long_cycle_w_anonymous_types = box box box box box LongCycleWithAnonymousTypes {
211
        next: Val {
212
            val: box box box box box LongCycleWithAnonymousTypes {
213 214 215 216 217 218 219 220 221 222 223 224
                next: Empty,
                value: 31,
            }
        },
        value: 30
    };

    zzz();
}

fn zzz() {()}