Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / ssa / interp / testdata / boundmeth.go
1 // Tests of bound method closures.
2
3 package main
4
5 import (
6         "errors"
7         "fmt"
8 )
9
10 func assert(b bool) {
11         if !b {
12                 panic("oops")
13         }
14 }
15
16 type I int
17
18 func (i I) add(x int) int {
19         return int(i) + x
20 }
21
22 func valueReceiver() {
23         var three I = 3
24         assert(three.add(5) == 8)
25         var add3 func(int) int = three.add
26         assert(add3(5) == 8)
27 }
28
29 type S struct{ x int }
30
31 func (s *S) incr() {
32         s.x++
33 }
34
35 func (s *S) get() int {
36         return s.x
37 }
38
39 func pointerReceiver() {
40         ps := new(S)
41         incr := ps.incr
42         get := ps.get
43         assert(get() == 0)
44         incr()
45         incr()
46         incr()
47         assert(get() == 3)
48 }
49
50 func addressibleValuePointerReceiver() {
51         var s S
52         incr := s.incr
53         get := s.get
54         assert(get() == 0)
55         incr()
56         incr()
57         incr()
58         assert(get() == 3)
59 }
60
61 type S2 struct {
62         S
63 }
64
65 func promotedReceiver() {
66         var s2 S2
67         incr := s2.incr
68         get := s2.get
69         assert(get() == 0)
70         incr()
71         incr()
72         incr()
73         assert(get() == 3)
74 }
75
76 func anonStruct() {
77         var s struct{ S }
78         incr := s.incr
79         get := s.get
80         assert(get() == 0)
81         incr()
82         incr()
83         incr()
84         assert(get() == 3)
85 }
86
87 func typeCheck() {
88         var i interface{}
89         i = (*S).incr
90         _ = i.(func(*S)) // type assertion: receiver type prepended to params
91
92         var s S
93         i = s.incr
94         _ = i.(func()) // type assertion: receiver type disappears
95 }
96
97 type errString string
98
99 func (err errString) Error() string {
100         return string(err)
101 }
102
103 // Regression test for a builder crash.
104 func regress1(x error) func() string {
105         return x.Error
106 }
107
108 // Regression test for b/7269:
109 // taking the value of an interface method performs a nil check.
110 func nilInterfaceMethodValue() {
111         err := errors.New("ok")
112         f := err.Error
113         if got := f(); got != "ok" {
114                 panic(got)
115         }
116
117         err = nil
118         if got := f(); got != "ok" {
119                 panic(got)
120         }
121
122         defer func() {
123                 r := fmt.Sprint(recover())
124                 // runtime panic string varies across toolchains
125                 if r != "interface conversion: interface is nil, not error" &&
126                         r != "runtime error: invalid memory address or nil pointer dereference" {
127                         panic("want runtime panic from nil interface method value, got " + r)
128                 }
129         }()
130         f = err.Error // runtime panic: err is nil
131         panic("unreachable")
132 }
133
134 func main() {
135         valueReceiver()
136         pointerReceiver()
137         addressibleValuePointerReceiver()
138         promotedReceiver()
139         anonStruct()
140         typeCheck()
141
142         if e := regress1(errString("hi"))(); e != "hi" {
143                 panic(e)
144         }
145
146         nilInterfaceMethodValue()
147 }