blob: 812d41f8ce02cf3659d75d216a1cf17d7e9e162d [file] [log] [blame]
Dan Willemsen09eb3b12015-09-16 14:34:17 -07001// 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
10package main
11
Dan Willemsencc753b72021-08-31 13:25:42 -070012var never bool
13
Dan Willemsen09eb3b12015-09-16 14:34:17 -070014func 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 {
Patrice Arruda748609c2020-06-25 12:12:21 -070079 return i // test that we capture by ref here, i is mutated on every interaction
Dan Willemsen09eb3b12015-09-16 14:34:17 -070080 }
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
Patrice Arruda748609c2020-06-25 12:12:21 -070095 // q++ must on a different decldepth than q declaration
Dan Willemsen09eb3b12015-09-16 14:34:17 -070096 }
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
Patrice Arruda748609c2020-06-25 12:12:21 -0700113 // q++ must on a different decldepth than q declaration
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700114 }
115 }
116 if g() != 2 {
117 panic("g() != 2")
118 }
119 }
Dan Willemsencc753b72021-08-31 13:25:42 -0700120
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 }
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700132}