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
10package main
11
12var never bool
13
14func 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}
134