Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / ssa / interp / testdata / coverage.go
1 // This interpreter test is designed to run very quickly yet provide
2 // some coverage of a broad selection of constructs.
3 //
4 // Validate this file with 'go run' after editing.
5 // TODO(adonovan): break this into small files organized by theme.
6
7 package main
8
9 import (
10         "fmt"
11         "reflect"
12         "strings"
13 )
14
15 func init() {
16         // Call of variadic function with (implicit) empty slice.
17         if x := fmt.Sprint(); x != "" {
18                 panic(x)
19         }
20 }
21
22 type empty interface{}
23
24 type I interface {
25         f() int
26 }
27
28 type T struct{ z int }
29
30 func (t T) f() int { return t.z }
31
32 func use(interface{}) {}
33
34 var counter = 2
35
36 // Test initialization, including init blocks containing 'return'.
37 // Assertion is in main.
38 func init() {
39         counter *= 3
40         return
41         counter *= 3
42 }
43
44 func init() {
45         counter *= 5
46         return
47         counter *= 5
48 }
49
50 // Recursion.
51 func fib(x int) int {
52         if x < 2 {
53                 return x
54         }
55         return fib(x-1) + fib(x-2)
56 }
57
58 func fibgen(ch chan int) {
59         for x := 0; x < 10; x++ {
60                 ch <- fib(x)
61         }
62         close(ch)
63 }
64
65 // Goroutines and channels.
66 func init() {
67         ch := make(chan int)
68         go fibgen(ch)
69         var fibs []int
70         for v := range ch {
71                 fibs = append(fibs, v)
72                 if len(fibs) == 10 {
73                         break
74                 }
75         }
76         if x := fmt.Sprint(fibs); x != "[0 1 1 2 3 5 8 13 21 34]" {
77                 panic(x)
78         }
79 }
80
81 // Test of aliasing.
82 func init() {
83         type S struct {
84                 a, b string
85         }
86
87         s1 := []string{"foo", "bar"}
88         s2 := s1 // creates an alias
89         s2[0] = "wiz"
90         if x := fmt.Sprint(s1, s2); x != "[wiz bar] [wiz bar]" {
91                 panic(x)
92         }
93
94         pa1 := &[2]string{"foo", "bar"}
95         pa2 := pa1 // creates an alias
96         pa2[0] = "wiz"
97         if x := fmt.Sprint(*pa1, *pa2); x != "[wiz bar] [wiz bar]" {
98                 panic(x)
99         }
100
101         a1 := [2]string{"foo", "bar"}
102         a2 := a1 // creates a copy
103         a2[0] = "wiz"
104         if x := fmt.Sprint(a1, a2); x != "[foo bar] [wiz bar]" {
105                 panic(x)
106         }
107
108         t1 := S{"foo", "bar"}
109         t2 := t1 // copy
110         t2.a = "wiz"
111         if x := fmt.Sprint(t1, t2); x != "{foo bar} {wiz bar}" {
112                 panic(x)
113         }
114 }
115
116 func main() {
117         print() // legal
118
119         if counter != 2*3*5 {
120                 panic(counter)
121         }
122
123         // Test builtins (e.g. complex) preserve named argument types.
124         type N complex128
125         var n N
126         n = complex(1.0, 2.0)
127         if n != complex(1.0, 2.0) {
128                 panic(n)
129         }
130         if x := reflect.TypeOf(n).String(); x != "main.N" {
131                 panic(x)
132         }
133         if real(n) != 1.0 || imag(n) != 2.0 {
134                 panic(n)
135         }
136
137         // Channel + select.
138         ch := make(chan int, 1)
139         select {
140         case ch <- 1:
141                 // ok
142         default:
143                 panic("couldn't send")
144         }
145         if <-ch != 1 {
146                 panic("couldn't receive")
147         }
148         // A "receive" select-case that doesn't declare its vars.  (regression test)
149         anint := 0
150         ok := false
151         select {
152         case anint, ok = <-ch:
153         case anint = <-ch:
154         default:
155         }
156         _ = anint
157         _ = ok
158
159         // Anon structs with methods.
160         anon := struct{ T }{T: T{z: 1}}
161         if x := anon.f(); x != 1 {
162                 panic(x)
163         }
164         var i I = anon
165         if x := i.f(); x != 1 {
166                 panic(x)
167         }
168         // NB. precise output of reflect.Type.String is undefined.
169         if x := reflect.TypeOf(i).String(); x != "struct { main.T }" && x != "struct{main.T}" {
170                 panic(x)
171         }
172
173         // fmt.
174         const message = "Hello, World!"
175         if fmt.Sprint("Hello", ", ", "World", "!") != message {
176                 panic("oops")
177         }
178
179         // Type assertion.
180         type S struct {
181                 f int
182         }
183         var e empty = S{f: 42}
184         switch v := e.(type) {
185         case S:
186                 if v.f != 42 {
187                         panic(v.f)
188                 }
189         default:
190                 panic(reflect.TypeOf(v))
191         }
192         if i, ok := e.(I); ok {
193                 panic(i)
194         }
195
196         // Switch.
197         var x int
198         switch x {
199         case 1:
200                 panic(x)
201                 fallthrough
202         case 2, 3:
203                 panic(x)
204         default:
205                 // ok
206         }
207         // empty switch
208         switch {
209         }
210         // empty switch
211         switch {
212         default:
213         }
214         // empty switch
215         switch {
216         default:
217                 fallthrough
218         case false:
219         }
220
221         // string -> []rune conversion.
222         use([]rune("foo"))
223
224         // Calls of form x.f().
225         type S2 struct {
226                 f func() int
227         }
228         S2{f: func() int { return 1 }}.f() // field is a func value
229         T{}.f()                            // method call
230         i.f()                              // interface method invocation
231         (interface {
232                 f() int
233         }(T{})).f() // anon interface method invocation
234
235         // Map lookup.
236         if v, ok := map[string]string{}["foo5"]; v != "" || ok {
237                 panic("oops")
238         }
239
240         // Regression test: implicit address-taken struct literal
241         // inside literal map element.
242         _ = map[int]*struct{}{0: {}}
243 }
244
245 type mybool bool
246
247 func (mybool) f() {}
248
249 func init() {
250         type mybool bool
251         var b mybool
252         var i interface{} = b || b // result preserves types of operands
253         _ = i.(mybool)
254
255         i = false && b // result preserves type of "typed" operand
256         _ = i.(mybool)
257
258         i = b || true // result preserves type of "typed" operand
259         _ = i.(mybool)
260 }
261
262 func init() {
263         var x, y int
264         var b mybool = x == y // x==y is an untyped bool
265         b.f()
266 }
267
268 // Simple closures.
269 func init() {
270         b := 3
271         f := func(a int) int {
272                 return a + b
273         }
274         b++
275         if x := f(1); x != 5 { // 1+4 == 5
276                 panic(x)
277         }
278         b++
279         if x := f(2); x != 7 { // 2+5 == 7
280                 panic(x)
281         }
282         if b := f(1) < 16 || f(2) < 17; !b {
283                 panic("oops")
284         }
285 }
286
287 // Shifts.
288 func init() {
289         var i int64 = 1
290         var u uint64 = 1 << 32
291         if x := i << uint32(u); x != 1 {
292                 panic(x)
293         }
294         if x := i << uint64(u); x != 0 {
295                 panic(x)
296         }
297 }
298
299 // Implicit conversion of delete() key operand.
300 func init() {
301         type I interface{}
302         m := make(map[I]bool)
303         m[1] = true
304         m[I(2)] = true
305         if len(m) != 2 {
306                 panic(m)
307         }
308         delete(m, I(1))
309         delete(m, 2)
310         if len(m) != 0 {
311                 panic(m)
312         }
313 }
314
315 // An I->I conversion always succeeds.
316 func init() {
317         var x I
318         if I(x) != I(nil) {
319                 panic("I->I conversion failed")
320         }
321 }
322
323 // An I->I type-assert fails iff the value is nil.
324 func init() {
325         defer func() {
326                 r := fmt.Sprint(recover())
327                 // Exact error varies by toolchain.
328                 if r != "runtime error: interface conversion: interface is nil, not main.I" &&
329                         r != "interface conversion: interface is nil, not main.I" {
330                         panic("I->I type assertion succeeded for nil value")
331                 }
332         }()
333         var x I
334         _ = x.(I)
335 }
336
337 //////////////////////////////////////////////////////////////////////
338 // Variadic bridge methods and interface thunks.
339
340 type VT int
341
342 var vcount = 0
343
344 func (VT) f(x int, y ...string) {
345         vcount++
346         if x != 1 {
347                 panic(x)
348         }
349         if len(y) != 2 || y[0] != "foo" || y[1] != "bar" {
350                 panic(y)
351         }
352 }
353
354 type VS struct {
355         VT
356 }
357
358 type VI interface {
359         f(x int, y ...string)
360 }
361
362 func init() {
363         foobar := []string{"foo", "bar"}
364         var s VS
365         s.f(1, "foo", "bar")
366         s.f(1, foobar...)
367         if vcount != 2 {
368                 panic("s.f not called twice")
369         }
370
371         fn := VI.f
372         fn(s, 1, "foo", "bar")
373         fn(s, 1, foobar...)
374         if vcount != 4 {
375                 panic("I.f not called twice")
376         }
377 }
378
379 // Multiple labels on same statement.
380 func multipleLabels() {
381         var trace []int
382         i := 0
383 one:
384 two:
385         for ; i < 3; i++ {
386                 trace = append(trace, i)
387                 switch i {
388                 case 0:
389                         continue two
390                 case 1:
391                         i++
392                         goto one
393                 case 2:
394                         break two
395                 }
396         }
397         if x := fmt.Sprint(trace); x != "[0 1 2]" {
398                 panic(x)
399         }
400 }
401
402 func init() {
403         multipleLabels()
404 }
405
406 func init() {
407         // Struct equivalence ignores blank fields.
408         type s struct{ x, _, z int }
409         s1 := s{x: 1, z: 3}
410         s2 := s{x: 1, z: 3}
411         if s1 != s2 {
412                 panic("not equal")
413         }
414 }
415
416 func init() {
417         // A slice var can be compared to const []T nil.
418         var i interface{} = []string{"foo"}
419         var j interface{} = []string(nil)
420         if i.([]string) == nil {
421                 panic("expected i non-nil")
422         }
423         if j.([]string) != nil {
424                 panic("expected j nil")
425         }
426         // But two slices cannot be compared, even if one is nil.
427         defer func() {
428                 r := fmt.Sprint(recover())
429                 if !(strings.Contains(r, "compar") && strings.Contains(r, "[]string")) {
430                         panic("want panic from slice comparison, got " + r)
431                 }
432         }()
433         _ = i == j // interface comparison recurses on types
434 }
435
436 func init() {
437         // Regression test for SSA renaming bug.
438         var ints []int
439         for range "foo" {
440                 var x int
441                 x++
442                 ints = append(ints, x)
443         }
444         if fmt.Sprint(ints) != "[1 1 1]" {
445                 panic(ints)
446         }
447 }
448
449 // Regression test for issue 6949:
450 // []byte("foo") is not a constant since it allocates memory.
451 func init() {
452         var r string
453         for i, b := range "ABC" {
454                 x := []byte("abc")
455                 x[i] = byte(b)
456                 r += string(x)
457         }
458         if r != "AbcaBcabC" {
459                 panic(r)
460         }
461 }
462
463 // Test of 3-operand x[lo:hi:max] slice.
464 func init() {
465         s := []int{0, 1, 2, 3}
466         lenCapLoHi := func(x []int) [4]int { return [4]int{len(x), cap(x), x[0], x[len(x)-1]} }
467         if got := lenCapLoHi(s[1:3]); got != [4]int{2, 3, 1, 2} {
468                 panic(got)
469         }
470         if got := lenCapLoHi(s[1:3:3]); got != [4]int{2, 2, 1, 2} {
471                 panic(got)
472         }
473         max := 3
474         if "a"[0] == 'a' {
475                 max = 2 // max is non-constant, even in SSA form
476         }
477         if got := lenCapLoHi(s[1:2:max]); got != [4]int{1, 1, 1, 1} {
478                 panic(got)
479         }
480 }
481
482 var one = 1 // not a constant
483
484 // Test makeslice.
485 func init() {
486         check := func(s []string, wantLen, wantCap int) {
487                 if len(s) != wantLen {
488                         panic(len(s))
489                 }
490                 if cap(s) != wantCap {
491                         panic(cap(s))
492                 }
493         }
494         //                                       SSA form:
495         check(make([]string, 10), 10, 10)     // new([10]string)[:10]
496         check(make([]string, one), 1, 1)      // make([]string, one, one)
497         check(make([]string, 0, 10), 0, 10)   // new([10]string)[:0]
498         check(make([]string, 0, one), 0, 1)   // make([]string, 0, one)
499         check(make([]string, one, 10), 1, 10) // new([10]string)[:one]
500         check(make([]string, one, one), 1, 1) // make([]string, one, one)
501 }
502
503 // Test that a nice error is issued by indirection wrappers.
504 func init() {
505         var ptr *T
506         var i I = ptr
507
508         defer func() {
509                 r := fmt.Sprint(recover())
510                 // Exact error varies by toolchain:
511                 if r != "runtime error: value method (main.T).f called using nil *main.T pointer" &&
512                         r != "value method (main.T).f called using nil *main.T pointer" {
513                         panic("want panic from call with nil receiver, got " + r)
514                 }
515         }()
516         i.f()
517         panic("unreachable")
518 }
519
520 // Regression test for a subtle bug in which copying values would causes
521 // subcomponents of aggregate variables to change address, breaking
522 // aliases.
523 func init() {
524         type T struct{ f int }
525         var x T
526         p := &x.f
527         x = T{}
528         *p = 1
529         if x.f != 1 {
530                 panic("lost store")
531         }
532         if p != &x.f {
533                 panic("unstable address")
534         }
535 }