| // 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") | |
| } | |
| } | |
| } |