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