]> Cypherpunks.ru repositories - gostls13.git/blob - test/closure3.dir/main.go
cmd/compile/internal/noder: remove inlined closure naming hack
[gostls13.git] / test / closure3.dir / main.go
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
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                         ppanic("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                         ppanic("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                         ppanic("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                         ppanic("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                         ppanic("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                                 ppanic("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                         ppanic("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                                 ppanic("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 "can inline main.func12"
97                         return func(x int) int { // ERROR "can inline main.func12"
98                                 return x + 1
99                         }, 42
100                 }() // ERROR "func literal does not escape" "inlining call to main.func12"
101                 if y(40) != 41 {
102                         ppanic("y(40) != 41")
103                 }
104         }
105
106         {
107                 func() { // ERROR "func literal does not escape"
108                         y := func(x int) int { // ERROR "func literal does not escape" "can inline main.func13.1"
109                                 return x + 2
110                         }
111                         y, sink = func() (func(int) int, int) { // ERROR "can inline main.func13.2"
112                                 return func(x int) int { // ERROR   "can inline main.func13.2"
113                                         return x + 1
114                                 }, 42
115                         }() // ERROR "func literal does not escape" "inlining call to main.func13.2"
116                         if y(40) != 41 {
117                                 ppanic("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                         ppanic("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                                 ppanic("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                         ppanic("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                                 ppanic("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                         ppanic("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                         ppanic("y() != 42")
185                 }
186         }
187
188         {
189                 x := 42
190                 if z := func(y int) int { // ERROR "can inline main.func22"
191                         return func() int { // ERROR "can inline main.func22.1" "can inline main.main.func22.func30"
192                                 return x + y
193                         }() // ERROR "inlining call to main.func22.1"
194                 }(1); z != 43 { // ERROR "inlining call to main.func22" "inlining call to main.main.func22.func30"
195                         ppanic("z != 43")
196                 }
197                 if z := func(y int) int { // ERROR "func literal does not escape" "can inline main.func23"
198                         return func() int { // ERROR "can inline main.func23.1" "can inline main.main.func23.func31"
199                                 return x + y
200                         }() // ERROR "inlining call to main.func23.1"
201                 }; z(1) != 43 { // ERROR "inlining call to main.func23" "inlining call to main.main.func23.func31"
202                         ppanic("z(1) != 43")
203                 }
204         }
205
206         {
207                 a := 1
208                 func() { // ERROR "can inline main.func24"
209                         func() { // ERROR "can inline main.func24" "can inline main.main.func24.func32"
210                                 a = 2
211                         }() // ERROR "inlining call to main.func24"
212                 }() // ERROR "inlining call to main.func24" "inlining call to main.main.func24.func32"
213                 if a != 2 {
214                         ppanic("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"
224                         if b != 3 {
225                                 ppanic("b != 3")
226                         }
227                 }(b)
228                 if b != 2 {
229                         ppanic("b != 2")
230                 }
231         }
232
233         {
234                 c := 3
235                 func() { // ERROR "can inline main.func26"
236                         c = 4
237                         func() {
238                                 if c != 4 {
239                                         ppanic("c != 4")
240                                 }
241                                 recover() // prevent inlining
242                         }()
243                 }() // ERROR "inlining call to main.func26" "func literal does not escape"
244                 if c != 4 {
245                         ppanic("c != 4")
246                 }
247         }
248
249         {
250                 a := 2
251                 // This has an unfortunate exponential growth, where as we visit each
252                 // function, we inline the inner closure, and that constructs a new
253                 // function for any closures inside the inner function, and then we
254                 // revisit those. E.g., func34 and func36 are constructed by the inliner.
255                 if r := func(x int) int { // ERROR "can inline main.func27"
256                         b := 3
257                         return func(y int) int { // ERROR "can inline main.func27.1" "can inline main.main.func27.func34"
258                                 c := 5
259                                 return func(z int) int { // ERROR "can inline main.func27.1.1" "can inline main.main.func27.func34.1" "can inline main.func27.main.func27.1.2" "can inline main.main.func27.main.main.func27.func34.func36"
260                                         return a*x + b*y + c*z
261                                 }(10) // ERROR "inlining call to main.func27.1.1"
262                         }(100) // ERROR "inlining call to main.func27.1" "inlining call to main.func27.main.func27.1.2"
263                 }(1000); r != 2350 { // ERROR "inlining call to main.func27" "inlining call to main.main.func27.func34" "inlining call to main.main.func27.main.main.func27.func34.func36"
264                         ppanic("r != 2350")
265                 }
266         }
267
268         {
269                 a := 2
270                 if r := func(x int) int { // ERROR "can inline main.func28"
271                         b := 3
272                         return func(y int) int { // ERROR "can inline main.func28.1" "can inline main.main.func28.func35"
273                                 c := 5
274                                 func(z int) { // ERROR "can inline main.func28.1.1" "can inline main.func28.main.func28.1.2" "can inline main.main.func28.func35.1" "can inline main.main.func28.main.main.func28.func35.func37"
275                                         a = a * x
276                                         b = b * y
277                                         c = c * z
278                                 }(10) // ERROR "inlining call to main.func28.1.1"
279                                 return a + c
280                         }(100) + b // ERROR "inlining call to main.func28.1" "inlining call to main.func28.main.func28.1.2"
281                 }(1000); r != 2350 { // ERROR "inlining call to main.func28" "inlining call to main.main.func28.func35" "inlining call to main.main.func28.main.main.func28.func35.func37"
282                         ppanic("r != 2350")
283                 }
284                 if a != 2000 {
285                         ppanic("a != 2000")
286                 }
287         }
288 }
289
290 //go:noinline
291 func ppanic(s string) { // ERROR "leaking param: s"
292         panic(s) // ERROR "s escapes to heap"
293 }