Home | History | Annotate | Download | only in test
      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 
     10 package main
     11 
     12 func main() {
     13 	{
     14 		type X struct {
     15 			v int
     16 		}
     17 		var x X
     18 		func() {
     19 			x.v++
     20 		}()
     21 		if x.v != 1 {
     22 			panic("x.v != 1")
     23 		}
     24 
     25 		type Y struct {
     26 			X
     27 		}
     28 		var y Y
     29 		func() {
     30 			y.v = 1
     31 		}()
     32 		if y.v != 1 {
     33 			panic("y.v != 1")
     34 		}
     35 	}
     36 
     37 	{
     38 		type Z struct {
     39 			a [3]byte
     40 		}
     41 		var z Z
     42 		func() {
     43 			i := 0
     44 			for z.a[1] = 1; i < 10; i++ {
     45 			}
     46 		}()
     47 		if z.a[1] != 1 {
     48 			panic("z.a[1] != 1")
     49 		}
     50 	}
     51 
     52 	{
     53 		w := 0
     54 		tmp := 0
     55 		f := func() {
     56 			if w != 1 {
     57 				panic("w != 1")
     58 			}
     59 		}
     60 		func() {
     61 			tmp = w // force capture of w, but do not write to it yet
     62 			_ = tmp
     63 			func() {
     64 				func() {
     65 					w++ // write in a nested closure
     66 				}()
     67 			}()
     68 		}()
     69 		f()
     70 	}
     71 
     72 	{
     73 		var g func() int
     74 		for i := range [2]int{} {
     75 			if i == 0 {
     76 				g = func() int {
     77 					return i // test that we capture by ref here, i is mutated on every interation
     78 				}
     79 			}
     80 		}
     81 		if g() != 1 {
     82 			panic("g() != 1")
     83 		}
     84 	}
     85 
     86 	{
     87 		var g func() int
     88 		q := 0
     89 		for range [2]int{} {
     90 			q++
     91 			g = func() int {
     92 				return q // test that we capture by ref here
     93 					 // q++ must on a different decldepth than q declaration
     94 			}
     95 		}
     96 		if g() != 2 {
     97 			panic("g() != 2")
     98 		}
     99 	}
    100 
    101 	{
    102 		var g func() int
    103 		var a [2]int
    104 		q := 0
    105 		for a[func() int {
    106 			q++
    107 			return 0
    108 		}()] = range [2]int{} {
    109 			g = func() int {
    110 				return q // test that we capture by ref here
    111 					 // q++ must on a different decldepth than q declaration
    112 			}
    113 		}
    114 		if g() != 2 {
    115 			panic("g() != 2")
    116 		}
    117 	}
    118 }
    119