Dan Willemsen | 09eb3b1 | 2015-09-16 14:34:17 -0700 | [diff] [blame] | 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 | |
Dan Willemsen | cc753b7 | 2021-08-31 13:25:42 -0700 | [diff] [blame] | 12 | var never bool |
| 13 | |
Dan Willemsen | 09eb3b1 | 2015-09-16 14:34:17 -0700 | [diff] [blame] | 14 | func 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 | for i := range [2]int{} { |
| 77 | if i == 0 { |
| 78 | g = func() int { |
Patrice Arruda | 748609c | 2020-06-25 12:12:21 -0700 | [diff] [blame] | 79 | return i // test that we capture by ref here, i is mutated on every interaction |
Dan Willemsen | 09eb3b1 | 2015-09-16 14:34:17 -0700 | [diff] [blame] | 80 | } |
| 81 | } |
| 82 | } |
| 83 | if g() != 1 { |
| 84 | panic("g() != 1") |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | { |
| 89 | var g func() int |
| 90 | q := 0 |
| 91 | for range [2]int{} { |
| 92 | q++ |
| 93 | g = func() int { |
| 94 | return q // test that we capture by ref here |
Patrice Arruda | 748609c | 2020-06-25 12:12:21 -0700 | [diff] [blame] | 95 | // q++ must on a different decldepth than q declaration |
Dan Willemsen | 09eb3b1 | 2015-09-16 14:34:17 -0700 | [diff] [blame] | 96 | } |
| 97 | } |
| 98 | if g() != 2 { |
| 99 | panic("g() != 2") |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | { |
| 104 | var g func() int |
| 105 | var a [2]int |
| 106 | q := 0 |
| 107 | for a[func() int { |
| 108 | q++ |
| 109 | return 0 |
| 110 | }()] = range [2]int{} { |
| 111 | g = func() int { |
| 112 | return q // test that we capture by ref here |
Patrice Arruda | 748609c | 2020-06-25 12:12:21 -0700 | [diff] [blame] | 113 | // q++ must on a different decldepth than q declaration |
Dan Willemsen | 09eb3b1 | 2015-09-16 14:34:17 -0700 | [diff] [blame] | 114 | } |
| 115 | } |
| 116 | if g() != 2 { |
| 117 | panic("g() != 2") |
| 118 | } |
| 119 | } |
Dan Willemsen | cc753b7 | 2021-08-31 13:25:42 -0700 | [diff] [blame] | 120 | |
| 121 | { |
| 122 | var g func() int |
| 123 | q := 0 |
| 124 | q, g = 1, func() int { return q } |
| 125 | if never { |
| 126 | g = func() int { return 2 } |
| 127 | } |
| 128 | if g() != 1 { |
| 129 | panic("g() != 1") |
| 130 | } |
| 131 | } |
Dan Willemsen | 09eb3b1 | 2015-09-16 14:34:17 -0700 | [diff] [blame] | 132 | } |