Home | History | Annotate | Download | only in closure3.dir
      1 // Copyright 2017 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Check correctness of various closure corner cases that
      6 // that are expected to be inlined
      7 
      8 package main
      9 
     10 var ok bool
     11 var sink int
     12 
     13 func main() {
     14 	{
     15 		if x := func() int { // ERROR "can inline main.func1"
     16 			return 1
     17 		}(); x != 1 { // ERROR "inlining call to main.func1"
     18 			panic("x != 1")
     19 		}
     20 		if x := func() int { // ERROR "can inline main.func2" "func literal does not escape"
     21 			return 1
     22 		}; x() != 1 { // ERROR "inlining call to main.func2"
     23 			panic("x() != 1")
     24 		}
     25 	}
     26 
     27 	{
     28 		if y := func(x int) int { // ERROR "can inline main.func3"
     29 			return x + 2
     30 		}(40); y != 42 { // ERROR "inlining call to main.func3"
     31 			panic("y != 42")
     32 		}
     33 		if y := func(x int) int { // ERROR "can inline main.func4" "func literal does not escape"
     34 			return x + 2
     35 		}; y(40) != 42 { // ERROR "inlining call to main.func4"
     36 			panic("y(40) != 42")
     37 		}
     38 	}
     39 
     40 	{
     41 		y := func(x int) int { // ERROR "can inline main.func5" "func literal does not escape"
     42 			return x + 2
     43 		}
     44 		y = func(x int) int { // ERROR "can inline main.func6" "func literal does not escape"
     45 			return x + 1
     46 		}
     47 		if y(40) != 41 {
     48 			panic("y(40) != 41")
     49 		}
     50 	}
     51 
     52 	{
     53 		func() { // ERROR "func literal does not escape"
     54 			y := func(x int) int { // ERROR "can inline main.func7.1" "func literal does not escape"
     55 				return x + 2
     56 			}
     57 			y = func(x int) int { // ERROR "can inline main.func7.2" "func literal does not escape"
     58 				return x + 1
     59 			}
     60 			if y(40) != 41 {
     61 				panic("y(40) != 41")
     62 			}
     63 		}()
     64 	}
     65 
     66 	{
     67 		y := func(x int) int { // ERROR "can inline main.func8" "func literal does not escape"
     68 			return x + 2
     69 		}
     70 		y, sink = func(x int) int { // ERROR "can inline main.func9" "func literal does not escape"
     71 			return x + 1
     72 		}, 42
     73 		if y(40) != 41 {
     74 			panic("y(40) != 41")
     75 		}
     76 	}
     77 
     78 	{
     79 		func() { // ERROR "func literal does not escape"
     80 			y := func(x int) int { // ERROR "can inline main.func10.1" "func literal does not escape"
     81 				return x + 2
     82 			}
     83 			y, sink = func(x int) int { // ERROR "can inline main.func10.2" "func literal does not escape"
     84 				return x + 1
     85 			}, 42
     86 			if y(40) != 41 {
     87 				panic("y(40) != 41")
     88 			}
     89 		}()
     90 	}
     91 
     92 	{
     93 		y := func(x int) int { // ERROR "can inline main.func11" "func literal does not escape"
     94 			return x + 2
     95 		}
     96 		y, sink = func() (func(int)int, int) { // ERROR "func literal does not escape"
     97 			return func(x int) int { // ERROR "can inline main.func12" "func literal escapes"
     98 				return x + 1
     99 			}, 42
    100 		}()
    101 		if y(40) != 41 {
    102 			panic("y(40) != 41")
    103 		}
    104 	}
    105 
    106 	{
    107 		func() { // ERROR "func literal does not escape"
    108 			y := func(x int) int { // ERROR "can inline main.func13.1" "func literal does not escape"
    109 				return x + 2
    110 			}
    111 			y, sink = func() (func(int) int, int) { // ERROR "func literal does not escape"
    112 				return func(x int) int { // ERROR "can inline main.func13.2" "func literal escapes"
    113 					return x + 1
    114 				}, 42
    115 			}()
    116 			if y(40) != 41 {
    117 				panic("y(40) != 41")
    118 			}
    119 		}()
    120 	}
    121 
    122 	{
    123 		y := func(x int) int { // ERROR "can inline main.func14" "func literal does not escape"
    124 			return x + 2
    125 		}
    126 		y, ok = map[int]func(int)int { // ERROR "does not escape"
    127 			0: func (x int) int { return x + 1 }, // ERROR "can inline main.func15" "func literal escapes"
    128 		}[0]
    129 		if y(40) != 41 {
    130 			panic("y(40) != 41")
    131 		}
    132 	}
    133 
    134 	{
    135 		func() { // ERROR "func literal does not escape"
    136 			y := func(x int) int { // ERROR "can inline main.func16.1" "func literal does not escape"
    137 				return x + 2
    138 			}
    139 			y, ok = map[int]func(int) int{// ERROR "does not escape"
    140 				0: func(x int) int { return x + 1 }, // ERROR "can inline main.func16.2" "func literal escapes"
    141 			}[0]
    142 			if y(40) != 41 {
    143 				panic("y(40) != 41")
    144 			}
    145 		}()
    146 	}
    147 
    148 	{
    149 		y := func(x int) int { // ERROR "can inline main.func17" "func literal does not escape"
    150 			return x + 2
    151 		}
    152 		y, ok = interface{}(func (x int) int { // ERROR "can inline main.func18" "does not escape"
    153 			return x + 1
    154 		}).(func(int)int)
    155 		if y(40) != 41 {
    156 			panic("y(40) != 41")
    157 		}
    158 	}
    159 
    160 	{
    161 		func() { // ERROR "func literal does not escape"
    162 			y := func(x int) int { // ERROR "can inline main.func19.1" "func literal does not escape"
    163 				return x + 2
    164 			}
    165 			y, ok = interface{}(func(x int) int { // ERROR "can inline main.func19.2" "does not escape"
    166 				return x + 1
    167 			}).(func(int) int)
    168 			if y(40) != 41 {
    169 				panic("y(40) != 41")
    170 			}
    171 		}()
    172 	}
    173 
    174 	{
    175 		x := 42
    176 		if y := func() int { // ERROR "can inline main.func20"
    177 			return x
    178 		}(); y != 42 { // ERROR "inlining call to main.func20"
    179 			panic("y != 42")
    180 		}
    181 		if y := func() int { // ERROR "can inline main.func21" "func literal does not escape"
    182 			return x
    183 		}; y() != 42 { // ERROR "inlining call to main.func21"
    184 			panic("y() != 42")
    185 		}
    186 	}
    187 
    188 	{
    189 		x := 42
    190 		if z := func(y int) int { // ERROR "func literal does not escape"
    191 			return func() int { // ERROR "can inline main.func22.1"
    192 				return x + y
    193 			}() // ERROR "inlining call to main.func22.1"
    194 		}(1); z != 43 {
    195 			panic("z != 43")
    196 		}
    197 		if z := func(y int) int { // ERROR "func literal does not escape"
    198 			return func() int { // ERROR "can inline main.func23.1"
    199 				return x + y
    200 			}() // ERROR "inlining call to main.func23.1"
    201 		}; z(1) != 43 {
    202 			panic("z(1) != 43")
    203 		}
    204 	}
    205 
    206 	{
    207 		a := 1
    208 		func() { // ERROR "func literal does not escape"
    209 			func() { // ERROR "can inline main.func24"
    210 				a = 2
    211 			}() // ERROR "inlining call to main.func24" "&a does not escape"
    212 		}()
    213 		if a != 2 {
    214 			panic("a != 2")
    215 		}
    216 	}
    217 
    218 	{
    219 		b := 2
    220 		func(b int) { // ERROR "func literal does not escape"
    221 			func() { // ERROR "can inline main.func25.1"
    222 				b = 3
    223 			}() // ERROR "inlining call to main.func25.1" "&b does not escape"
    224 			if b != 3 {
    225 				panic("b != 3")
    226 			}
    227 		}(b)
    228 		if b != 2 {
    229 			panic("b != 2")
    230 		}
    231 	}
    232 
    233 	{
    234 		c := 3
    235 		func() { // ERROR "func literal does not escape"
    236 			c = 4
    237 			func() { // ERROR "func literal does not escape"
    238 				if c != 4 {
    239 					panic("c != 4")
    240 				}
    241 			}()
    242 		}()
    243 		if c != 4 {
    244 			panic("c != 4")
    245 		}
    246 	}
    247 
    248 	{
    249 		a := 2
    250 		if r := func(x int) int { // ERROR "func literal does not escape"
    251 			b := 3
    252 			return func(y int) int { // ERROR "func literal does not escape"
    253 				c := 5
    254 				return func(z int) int { // ERROR "can inline main.func27.1.1"
    255 					return a*x + b*y + c*z
    256 				}(10) // ERROR "inlining call to main.func27.1.1"
    257 			}(100)
    258 		}(1000); r != 2350 {
    259 			panic("r != 2350")
    260 		}
    261 	}
    262 
    263 	{
    264 		a := 2
    265 		if r := func(x int) int { // ERROR "func literal does not escape"
    266 			b := 3
    267 			return func(y int) int { // ERROR "func literal does not escape"
    268 				c := 5
    269 				func(z int) { // ERROR "can inline main.func28.1.1"
    270 					a = a * x
    271 					b = b * y
    272 					c = c * z
    273 				}(10) // ERROR "inlining call to main.func28.1.1" "&a does not escape" "&b does not escape" "&c does not escape"
    274 				return a + c
    275 			}(100) + b
    276 		}(1000); r != 2350 {
    277 			panic("r != 2350")
    278 		}
    279 		if a != 2000 {
    280 			panic("a != 2000")
    281 		}
    282 	}
    283 }
    284