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
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/ssa/interp/testdata/boundmeth.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/ssa/interp/testdata/boundmeth.go
new file mode 100644 (file)
index 0000000..69937f9
--- /dev/null
@@ -0,0 +1,147 @@
+// Tests of bound method closures.
+
+package main
+
+import (
+       "errors"
+       "fmt"
+)
+
+func assert(b bool) {
+       if !b {
+               panic("oops")
+       }
+}
+
+type I int
+
+func (i I) add(x int) int {
+       return int(i) + x
+}
+
+func valueReceiver() {
+       var three I = 3
+       assert(three.add(5) == 8)
+       var add3 func(int) int = three.add
+       assert(add3(5) == 8)
+}
+
+type S struct{ x int }
+
+func (s *S) incr() {
+       s.x++
+}
+
+func (s *S) get() int {
+       return s.x
+}
+
+func pointerReceiver() {
+       ps := new(S)
+       incr := ps.incr
+       get := ps.get
+       assert(get() == 0)
+       incr()
+       incr()
+       incr()
+       assert(get() == 3)
+}
+
+func addressibleValuePointerReceiver() {
+       var s S
+       incr := s.incr
+       get := s.get
+       assert(get() == 0)
+       incr()
+       incr()
+       incr()
+       assert(get() == 3)
+}
+
+type S2 struct {
+       S
+}
+
+func promotedReceiver() {
+       var s2 S2
+       incr := s2.incr
+       get := s2.get
+       assert(get() == 0)
+       incr()
+       incr()
+       incr()
+       assert(get() == 3)
+}
+
+func anonStruct() {
+       var s struct{ S }
+       incr := s.incr
+       get := s.get
+       assert(get() == 0)
+       incr()
+       incr()
+       incr()
+       assert(get() == 3)
+}
+
+func typeCheck() {
+       var i interface{}
+       i = (*S).incr
+       _ = i.(func(*S)) // type assertion: receiver type prepended to params
+
+       var s S
+       i = s.incr
+       _ = i.(func()) // type assertion: receiver type disappears
+}
+
+type errString string
+
+func (err errString) Error() string {
+       return string(err)
+}
+
+// Regression test for a builder crash.
+func regress1(x error) func() string {
+       return x.Error
+}
+
+// Regression test for b/7269:
+// taking the value of an interface method performs a nil check.
+func nilInterfaceMethodValue() {
+       err := errors.New("ok")
+       f := err.Error
+       if got := f(); got != "ok" {
+               panic(got)
+       }
+
+       err = nil
+       if got := f(); got != "ok" {
+               panic(got)
+       }
+
+       defer func() {
+               r := fmt.Sprint(recover())
+               // runtime panic string varies across toolchains
+               if r != "interface conversion: interface is nil, not error" &&
+                       r != "runtime error: invalid memory address or nil pointer dereference" {
+                       panic("want runtime panic from nil interface method value, got " + r)
+               }
+       }()
+       f = err.Error // runtime panic: err is nil
+       panic("unreachable")
+}
+
+func main() {
+       valueReceiver()
+       pointerReceiver()
+       addressibleValuePointerReceiver()
+       promotedReceiver()
+       anonStruct()
+       typeCheck()
+
+       if e := regress1(errString("hi"))(); e != "hi" {
+               panic(e)
+       }
+
+       nilInterfaceMethodValue()
+}