]> Cypherpunks.ru repositories - gostls13.git/blob - test/closure2.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / closure2.go
1 // run
2
3 // Copyright 2015 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Check that these do not use "by value" capturing,
8 // because changes are made to the value during the closure.
9
10 package main
11
12 var never bool
13
14 func main() {
15         {
16                 type X struct {
17                         v int
18                 }
19                 var x X
20                 func() {
21                         x.v++
22                 }()
23                 if x.v != 1 {
24                         panic("x.v != 1")
25                 }
26
27                 type Y struct {
28                         X
29                 }
30                 var y Y
31                 func() {
32                         y.v = 1
33                 }()
34                 if y.v != 1 {
35                         panic("y.v != 1")
36                 }
37         }
38
39         {
40                 type Z struct {
41                         a [3]byte
42                 }
43                 var z Z
44                 func() {
45                         i := 0
46                         for z.a[1] = 1; i < 10; i++ {
47                         }
48                 }()
49                 if z.a[1] != 1 {
50                         panic("z.a[1] != 1")
51                 }
52         }
53
54         {
55                 w := 0
56                 tmp := 0
57                 f := func() {
58                         if w != 1 {
59                                 panic("w != 1")
60                         }
61                 }
62                 func() {
63                         tmp = w // force capture of w, but do not write to it yet
64                         _ = tmp
65                         func() {
66                                 func() {
67                                         w++ // write in a nested closure
68                                 }()
69                         }()
70                 }()
71                 f()
72         }
73
74         {
75                 var g func() int
76                 var i int
77                 for i = range [2]int{} {
78                         if i == 0 {
79                                 g = func() int {
80                                         return i // test that we capture by ref here, i is mutated on every interaction
81                                 }
82                         }
83                 }
84                 if g() != 1 {
85                         panic("g() != 1")
86                 }
87         }
88
89         {
90                 var g func() int
91                 q := 0
92                 for range [2]int{} {
93                         q++
94                         g = func() int {
95                                 return q // test that we capture by ref here
96                                 // q++ must on a different decldepth than q declaration
97                         }
98                 }
99                 if g() != 2 {
100                         panic("g() != 2")
101                 }
102         }
103
104         {
105                 var g func() int
106                 var a [2]int
107                 q := 0
108                 for a[func() int {
109                         q++
110                         return 0
111                 }()] = range [2]int{} {
112                         g = func() int {
113                                 return q // test that we capture by ref here
114                                 // q++ must on a different decldepth than q declaration
115                         }
116                 }
117                 if g() != 2 {
118                         panic("g() != 2")
119                 }
120         }
121
122         {
123                 var g func() int
124                 q := 0
125                 q, g = 1, func() int { return q }
126                 if never {
127                         g = func() int { return 2 }
128                 }
129                 if g() != 1 {
130                         panic("g() != 1")
131                 }
132         }
133 }