1package main
2
3import "fmt"
4
5// Test of initialization order of package-level vars.
6
7var counter int
8
9func next() int {
10	c := counter
11	counter++
12	return c
13}
14
15func next2() (x int, y int) {
16	x = next()
17	y = next()
18	return
19}
20
21func makeOrder() int {
22	_, _, _, _ = f, b, d, e
23	return 0
24}
25
26func main() {
27	// Initialization constraints:
28	// - {f,b,c/d,e} < order  (ref graph traversal)
29	// - order < {a}          (lexical order)
30	// - b < c/d < e < f      (lexical order)
31	// Solution: a b c/d e f
32	abcdef := [6]int{a, b, c, d, e, f}
33	if abcdef != [6]int{0, 1, 2, 3, 4, 5} {
34		panic(abcdef)
35	}
36}
37
38var order = makeOrder()
39
40var a, b = next(), next()
41var c, d = next2()
42var e, f = next(), next()
43
44// ------------------------------------------------------------------------
45
46var order2 []string
47
48func create(x int, name string) int {
49	order2 = append(order2, name)
50	return x
51}
52
53var C = create(B+1, "C")
54var A, B = create(1, "A"), create(2, "B")
55
56// Initialization order of package-level value specs.
57func init() {
58	x := fmt.Sprint(order2)
59	// Result varies by toolchain.  This is a spec bug.
60	if x != "[B C A]" && // gc
61		x != "[A B C]" { // go/types
62		panic(x)
63	}
64	if C != 3 {
65		panic(c)
66	}
67}
68