summaryrefslogtreecommitdiffstats
path: root/test/closure2.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/closure2.go')
-rw-r--r--test/closure2.go133
1 files changed, 133 insertions, 0 deletions
diff --git a/test/closure2.go b/test/closure2.go
new file mode 100644
index 0000000..081d2e2
--- /dev/null
+++ b/test/closure2.go
@@ -0,0 +1,133 @@
+// run
+
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check that these do not use "by value" capturing,
+// because changes are made to the value during the closure.
+
+package main
+
+var never bool
+
+func main() {
+ {
+ type X struct {
+ v int
+ }
+ var x X
+ func() {
+ x.v++
+ }()
+ if x.v != 1 {
+ panic("x.v != 1")
+ }
+
+ type Y struct {
+ X
+ }
+ var y Y
+ func() {
+ y.v = 1
+ }()
+ if y.v != 1 {
+ panic("y.v != 1")
+ }
+ }
+
+ {
+ type Z struct {
+ a [3]byte
+ }
+ var z Z
+ func() {
+ i := 0
+ for z.a[1] = 1; i < 10; i++ {
+ }
+ }()
+ if z.a[1] != 1 {
+ panic("z.a[1] != 1")
+ }
+ }
+
+ {
+ w := 0
+ tmp := 0
+ f := func() {
+ if w != 1 {
+ panic("w != 1")
+ }
+ }
+ func() {
+ tmp = w // force capture of w, but do not write to it yet
+ _ = tmp
+ func() {
+ func() {
+ w++ // write in a nested closure
+ }()
+ }()
+ }()
+ f()
+ }
+
+ {
+ var g func() int
+ var i int
+ for i = range [2]int{} {
+ if i == 0 {
+ g = func() int {
+ return i // test that we capture by ref here, i is mutated on every interaction
+ }
+ }
+ }
+ if g() != 1 {
+ panic("g() != 1")
+ }
+ }
+
+ {
+ var g func() int
+ q := 0
+ for range [2]int{} {
+ q++
+ g = func() int {
+ return q // test that we capture by ref here
+ // q++ must on a different decldepth than q declaration
+ }
+ }
+ if g() != 2 {
+ panic("g() != 2")
+ }
+ }
+
+ {
+ var g func() int
+ var a [2]int
+ q := 0
+ for a[func() int {
+ q++
+ return 0
+ }()] = range [2]int{} {
+ g = func() int {
+ return q // test that we capture by ref here
+ // q++ must on a different decldepth than q declaration
+ }
+ }
+ if g() != 2 {
+ panic("g() != 2")
+ }
+ }
+
+ {
+ var g func() int
+ q := 0
+ q, g = 1, func() int { return q }
+ if never {
+ g = func() int { return 2 }
+ }
+ if g() != 1 {
+ panic("g() != 1")
+ }
+ }
+}