// 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

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