]> Cypherpunks.ru repositories - gostls13.git/blob - test/closure2.go
[dev.regabi] all: merge master (fca94ab) into dev.regabi
[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                 for i := range [2]int{} {
77                         if i == 0 {
78                                 g = func() int {
79                                         return i // test that we capture by ref here, i is mutated on every interaction
80                                 }
81                         }
82                 }
83                 if g() != 1 {
84                         panic("g() != 1")
85                 }
86         }
87
88         {
89                 var g func() int
90                 q := 0
91                 for range [2]int{} {
92                         q++
93                         g = func() int {
94                                 return q // test that we capture by ref here
95                                 // q++ must on a different decldepth than q declaration
96                         }
97                 }
98                 if g() != 2 {
99                         panic("g() != 2")
100                 }
101         }
102
103         {
104                 var g func() int
105                 var a [2]int
106                 q := 0
107                 for a[func() int {
108                         q++
109                         return 0
110                 }()] = range [2]int{} {
111                         g = func() int {
112                                 return q // test that we capture by ref here
113                                 // q++ must on a different decldepth than q declaration
114                         }
115                 }
116                 if g() != 2 {
117                         panic("g() != 2")
118                 }
119         }
120
121         {
122                 var g func() int
123                 q := 0
124                 q, g = 1, func() int { return q }
125                 if never {
126                         g = func() int { return 2 }
127                 }
128                 if g() != 1 {
129                         panic("g() != 1")
130                 }
131         }
132 }