Russ Cox | 57eb06f | 2012-02-16 23:51:04 -0500 | [diff] [blame] | 1 | // run |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 2 | |
| 3 | // Copyright 2009 The Go Authors. All rights reserved. |
| 4 | // Use of this source code is governed by a BSD-style |
| 5 | // license that can be found in the LICENSE file. |
| 6 | |
Rob Pike | 501f0b5 | 2012-02-23 18:47:26 +1100 | [diff] [blame] | 7 | // Test simple methods of various types, with pointer and |
| 8 | // value receivers. |
| 9 | |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 10 | package main |
| 11 | |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 12 | type S string |
| 13 | type S1 string |
| 14 | type I int |
| 15 | type I1 int |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 16 | type T struct { |
| 17 | x int |
| 18 | } |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 19 | type T1 T |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 20 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 21 | func (s S) val() int { return 1 } |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 22 | func (s *S1) val() int { return 2 } |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 23 | func (i I) val() int { return 3 } |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 24 | func (i *I1) val() int { return 4 } |
Russ Cox | 00ffd59 | 2010-09-28 13:43:50 -0400 | [diff] [blame] | 25 | func (t T) val() int { return 7 } |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 26 | func (t *T1) val() int { return 8 } |
| 27 | |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 28 | type Val interface { |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 29 | val() int |
| 30 | } |
| 31 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 32 | func val(v Val) int { return v.val() } |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 33 | |
| 34 | func main() { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 35 | var s S |
| 36 | var ps *S1 |
| 37 | var i I |
| 38 | var pi *I1 |
| 39 | var pt *T1 |
Russ Cox | 00ffd59 | 2010-09-28 13:43:50 -0400 | [diff] [blame] | 40 | var t T |
| 41 | var v Val |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 42 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 43 | if s.val() != 1 { |
| 44 | println("s.val:", s.val()) |
| 45 | panic("fail") |
| 46 | } |
| 47 | if S.val(s) != 1 { |
| 48 | println("S.val(s):", S.val(s)) |
| 49 | panic("fail") |
| 50 | } |
| 51 | if (*S).val(&s) != 1 { |
| 52 | println("(*S).val(s):", (*S).val(&s)) |
| 53 | panic("fail") |
| 54 | } |
| 55 | if ps.val() != 2 { |
| 56 | println("ps.val:", ps.val()) |
| 57 | panic("fail") |
| 58 | } |
| 59 | if (*S1).val(ps) != 2 { |
| 60 | println("(*S1).val(ps):", (*S1).val(ps)) |
| 61 | panic("fail") |
| 62 | } |
| 63 | if i.val() != 3 { |
| 64 | println("i.val:", i.val()) |
| 65 | panic("fail") |
| 66 | } |
| 67 | if I.val(i) != 3 { |
| 68 | println("I.val(i):", I.val(i)) |
| 69 | panic("fail") |
| 70 | } |
| 71 | if (*I).val(&i) != 3 { |
| 72 | println("(*I).val(&i):", (*I).val(&i)) |
| 73 | panic("fail") |
| 74 | } |
| 75 | if pi.val() != 4 { |
| 76 | println("pi.val:", pi.val()) |
| 77 | panic("fail") |
| 78 | } |
| 79 | if (*I1).val(pi) != 4 { |
| 80 | println("(*I1).val(pi):", (*I1).val(pi)) |
| 81 | panic("fail") |
| 82 | } |
Russ Cox | 00ffd59 | 2010-09-28 13:43:50 -0400 | [diff] [blame] | 83 | if t.val() != 7 { |
| 84 | println("t.val:", t.val()) |
| 85 | panic("fail") |
| 86 | } |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 87 | if pt.val() != 8 { |
| 88 | println("pt.val:", pt.val()) |
| 89 | panic("fail") |
| 90 | } |
| 91 | if (*T1).val(pt) != 8 { |
| 92 | println("(*T1).val(pt):", (*T1).val(pt)) |
| 93 | panic("fail") |
| 94 | } |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 95 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 96 | if val(s) != 1 { |
Russ Cox | 4267974 | 2012-03-07 02:27:15 -0500 | [diff] [blame] | 97 | println("val(s):", val(s)) |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 98 | panic("fail") |
| 99 | } |
| 100 | if val(ps) != 2 { |
Russ Cox | 4267974 | 2012-03-07 02:27:15 -0500 | [diff] [blame] | 101 | println("val(ps):", val(ps)) |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 102 | panic("fail") |
| 103 | } |
| 104 | if val(i) != 3 { |
Russ Cox | 4267974 | 2012-03-07 02:27:15 -0500 | [diff] [blame] | 105 | println("val(i):", val(i)) |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 106 | panic("fail") |
| 107 | } |
| 108 | if val(pi) != 4 { |
Russ Cox | 4267974 | 2012-03-07 02:27:15 -0500 | [diff] [blame] | 109 | println("val(pi):", val(pi)) |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 110 | panic("fail") |
| 111 | } |
Russ Cox | 00ffd59 | 2010-09-28 13:43:50 -0400 | [diff] [blame] | 112 | if val(t) != 7 { |
Russ Cox | 4267974 | 2012-03-07 02:27:15 -0500 | [diff] [blame] | 113 | println("val(t):", val(t)) |
Russ Cox | 00ffd59 | 2010-09-28 13:43:50 -0400 | [diff] [blame] | 114 | panic("fail") |
| 115 | } |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 116 | if val(pt) != 8 { |
Russ Cox | 4267974 | 2012-03-07 02:27:15 -0500 | [diff] [blame] | 117 | println("val(pt):", val(pt)) |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 118 | panic("fail") |
| 119 | } |
| 120 | |
Russ Cox | 00ffd59 | 2010-09-28 13:43:50 -0400 | [diff] [blame] | 121 | if Val.val(i) != 3 { |
| 122 | println("Val.val(i):", Val.val(i)) |
| 123 | panic("fail") |
| 124 | } |
| 125 | v = i |
| 126 | if Val.val(v) != 3 { |
| 127 | println("Val.val(v):", Val.val(v)) |
| 128 | panic("fail") |
| 129 | } |
Russ Cox | 4267974 | 2012-03-07 02:27:15 -0500 | [diff] [blame] | 130 | |
Alan Donovan | 1c1096e | 2013-02-11 18:20:52 -0500 | [diff] [blame] | 131 | var zs struct{ S } |
| 132 | var zps struct{ *S1 } |
| 133 | var zi struct{ I } |
| 134 | var zpi struct{ *I1 } |
| 135 | var zpt struct{ *T1 } |
| 136 | var zt struct{ T } |
| 137 | var zv struct{ Val } |
Russ Cox | 4267974 | 2012-03-07 02:27:15 -0500 | [diff] [blame] | 138 | |
| 139 | if zs.val() != 1 { |
| 140 | println("zs.val:", zs.val()) |
| 141 | panic("fail") |
| 142 | } |
| 143 | if zps.val() != 2 { |
| 144 | println("zps.val:", zps.val()) |
| 145 | panic("fail") |
| 146 | } |
| 147 | if zi.val() != 3 { |
| 148 | println("zi.val:", zi.val()) |
| 149 | panic("fail") |
| 150 | } |
| 151 | if zpi.val() != 4 { |
| 152 | println("zpi.val:", zpi.val()) |
| 153 | panic("fail") |
| 154 | } |
| 155 | if zt.val() != 7 { |
| 156 | println("zt.val:", zt.val()) |
| 157 | panic("fail") |
| 158 | } |
| 159 | if zpt.val() != 8 { |
| 160 | println("zpt.val:", zpt.val()) |
| 161 | panic("fail") |
| 162 | } |
| 163 | |
| 164 | if val(zs) != 1 { |
| 165 | println("val(zs):", val(zs)) |
| 166 | panic("fail") |
| 167 | } |
| 168 | if val(zps) != 2 { |
| 169 | println("val(zps):", val(zps)) |
| 170 | panic("fail") |
| 171 | } |
| 172 | if val(zi) != 3 { |
| 173 | println("val(zi):", val(zi)) |
| 174 | panic("fail") |
| 175 | } |
| 176 | if val(zpi) != 4 { |
| 177 | println("val(zpi):", val(zpi)) |
| 178 | panic("fail") |
| 179 | } |
| 180 | if val(zt) != 7 { |
| 181 | println("val(zt):", val(zt)) |
| 182 | panic("fail") |
| 183 | } |
| 184 | if val(zpt) != 8 { |
| 185 | println("val(zpt):", val(zpt)) |
| 186 | panic("fail") |
| 187 | } |
| 188 | |
| 189 | zv.Val = zi |
| 190 | if zv.val() != 3 { |
| 191 | println("zv.val():", zv.val()) |
| 192 | panic("fail") |
| 193 | } |
| 194 | |
| 195 | if (&zs).val() != 1 { |
| 196 | println("(&zs).val:", (&zs).val()) |
| 197 | panic("fail") |
| 198 | } |
| 199 | if (&zps).val() != 2 { |
| 200 | println("(&zps).val:", (&zps).val()) |
| 201 | panic("fail") |
| 202 | } |
| 203 | if (&zi).val() != 3 { |
| 204 | println("(&zi).val:", (&zi).val()) |
| 205 | panic("fail") |
| 206 | } |
| 207 | if (&zpi).val() != 4 { |
| 208 | println("(&zpi).val:", (&zpi).val()) |
| 209 | panic("fail") |
| 210 | } |
| 211 | if (&zt).val() != 7 { |
| 212 | println("(&zt).val:", (&zt).val()) |
| 213 | panic("fail") |
| 214 | } |
| 215 | if (&zpt).val() != 8 { |
| 216 | println("(&zpt).val:", (&zpt).val()) |
| 217 | panic("fail") |
| 218 | } |
| 219 | |
| 220 | if val(&zs) != 1 { |
| 221 | println("val(&zs):", val(&zs)) |
| 222 | panic("fail") |
| 223 | } |
| 224 | if val(&zps) != 2 { |
| 225 | println("val(&zps):", val(&zps)) |
| 226 | panic("fail") |
| 227 | } |
| 228 | if val(&zi) != 3 { |
| 229 | println("val(&zi):", val(&zi)) |
| 230 | panic("fail") |
| 231 | } |
| 232 | if val(&zpi) != 4 { |
| 233 | println("val(&zpi):", val(&zpi)) |
| 234 | panic("fail") |
| 235 | } |
| 236 | if val(&zt) != 7 { |
| 237 | println("val(&zt):", val(&zt)) |
| 238 | panic("fail") |
| 239 | } |
| 240 | if val(&zpt) != 8 { |
| 241 | println("val(&zpt):", val(&zpt)) |
| 242 | panic("fail") |
| 243 | } |
| 244 | |
| 245 | zv.Val = &zi |
| 246 | if zv.val() != 3 { |
| 247 | println("zv.val():", zv.val()) |
| 248 | panic("fail") |
| 249 | } |
Alan Donovan | 1c1096e | 2013-02-11 18:20:52 -0500 | [diff] [blame] | 250 | |
| 251 | promotion() |
| 252 | } |
| 253 | |
| 254 | type A struct{ B } |
| 255 | type B struct { |
| 256 | C |
| 257 | *D |
| 258 | } |
| 259 | type C int |
| 260 | |
| 261 | func (C) f() {} // value receiver, direct field of A |
| 262 | func (*C) g() {} // pointer receiver |
| 263 | |
| 264 | type D int |
| 265 | |
| 266 | func (D) h() {} // value receiver, indirect field of A |
| 267 | func (*D) i() {} // pointer receiver |
| 268 | |
| 269 | func expectPanic() { |
| 270 | if r := recover(); r == nil { |
| 271 | panic("expected nil dereference") |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | func promotion() { |
| 276 | var a A |
| 277 | // Addressable value receiver. |
| 278 | a.f() |
| 279 | a.g() |
| 280 | func() { |
| 281 | defer expectPanic() |
| 282 | a.h() // dynamic error: nil dereference in a.B.D->f() |
| 283 | }() |
| 284 | a.i() |
| 285 | |
| 286 | // Non-addressable value receiver. |
| 287 | A(a).f() |
| 288 | // A(a).g() // static error: cannot call pointer method on A literal.B.C |
| 289 | func() { |
| 290 | defer expectPanic() |
| 291 | A(a).h() // dynamic error: nil dereference in A().B.D->f() |
| 292 | }() |
| 293 | A(a).i() |
| 294 | |
| 295 | // Pointer receiver. |
| 296 | (&a).f() |
| 297 | (&a).g() |
| 298 | func() { |
| 299 | defer expectPanic() |
| 300 | (&a).h() // dynamic error: nil deref: nil dereference in (&a).B.D->f() |
| 301 | }() |
| 302 | (&a).i() |
| 303 | |
| 304 | c := new(C) |
| 305 | c.f() // makes a copy |
| 306 | c.g() |
Russ Cox | 2e1bb4a | 2008-10-04 02:51:03 -0700 | [diff] [blame] | 307 | } |