1// run
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
7// Test simple methods of various types, with pointer and
8// value receivers.
9
10package main
11
12type S string
13type S1 string
14type I int
15type I1 int
16type T struct {
17	x int
18}
19type T1 T
20
21func (s S) val() int   { return 1 }
22func (s *S1) val() int { return 2 }
23func (i I) val() int   { return 3 }
24func (i *I1) val() int { return 4 }
25func (t T) val() int   { return 7 }
26func (t *T1) val() int { return 8 }
27
28type Val interface {
29	val() int
30}
31
32func val(v Val) int { return v.val() }
33
34func main() {
35	var s S
36	var ps *S1
37	var i I
38	var pi *I1
39	var pt *T1
40	var t T
41	var v Val
42
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	}
83	if t.val() != 7 {
84		println("t.val:", t.val())
85		panic("fail")
86	}
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	}
95
96	if val(s) != 1 {
97		println("val(s):", val(s))
98		panic("fail")
99	}
100	if val(ps) != 2 {
101		println("val(ps):", val(ps))
102		panic("fail")
103	}
104	if val(i) != 3 {
105		println("val(i):", val(i))
106		panic("fail")
107	}
108	if val(pi) != 4 {
109		println("val(pi):", val(pi))
110		panic("fail")
111	}
112	if val(t) != 7 {
113		println("val(t):", val(t))
114		panic("fail")
115	}
116	if val(pt) != 8 {
117		println("val(pt):", val(pt))
118		panic("fail")
119	}
120
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	}
130
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 }
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	}
250
251	promotion()
252}
253
254type A struct{ B }
255type B struct {
256	C
257	*D
258}
259type C int
260
261func (C) f()  {} // value receiver, direct field of A
262func (*C) g() {} // pointer receiver
263
264type D int
265
266func (D) h()  {} // value receiver, indirect field of A
267func (*D) i() {} // pointer receiver
268
269func expectPanic() {
270	if r := recover(); r == nil {
271		panic("expected nil dereference")
272	}
273}
274
275func 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()
307}
308