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 embedded fields of structs, including methods.
8
9package main
10
11
12type I interface {
13	test1() int
14	test2() int
15	test3() int
16	test4() int
17	test5() int
18	test6() int
19	test7() int
20}
21
22/******
23 ******
24 ******/
25
26type SubpSubp struct {
27	a7 int
28	a  int
29}
30
31func (p *SubpSubp) test7() int {
32	if p.a != p.a7 {
33		println("SubpSubp", p, p.a7)
34		panic("fail")
35	}
36	return p.a
37}
38func (p *SubpSubp) testx() { println("SubpSubp", p, p.a7) }
39
40/******
41 ******
42 ******/
43
44type SubpSub struct {
45	a6 int
46	SubpSubp
47	a int
48}
49
50func (p *SubpSub) test6() int {
51	if p.a != p.a6 {
52		println("SubpSub", p, p.a6)
53		panic("fail")
54	}
55	return p.a
56}
57func (p *SubpSub) testx() { println("SubpSub", p, p.a6) }
58
59/******
60 ******
61 ******/
62
63type SubSubp struct {
64	a5 int
65	a  int
66}
67
68func (p *SubSubp) test5() int {
69	if p.a != p.a5 {
70		println("SubpSub", p, p.a5)
71		panic("fail")
72	}
73	return p.a
74}
75
76/******
77 ******
78 ******/
79
80type SubSub struct {
81	a4 int
82	a  int
83}
84
85func (p *SubSub) test4() int {
86	if p.a != p.a4 {
87		println("SubpSub", p, p.a4)
88		panic("fail")
89	}
90	return p.a
91}
92
93/******
94 ******
95 ******/
96
97type Subp struct {
98	a3 int
99	*SubpSubp
100	SubpSub
101	a int
102}
103
104func (p *Subp) test3() int {
105	if p.a != p.a3 {
106		println("SubpSub", p, p.a3)
107		panic("fail")
108	}
109	return p.a
110}
111
112/******
113 ******
114 ******/
115
116type Sub struct {
117	a2 int
118	*SubSubp
119	SubSub
120	a int
121}
122
123func (p *Sub) test2() int {
124	if p.a != p.a2 {
125		println("SubpSub", p, p.a2)
126		panic("fail")
127	}
128	return p.a
129}
130
131/******
132 ******
133 ******/
134
135type S struct {
136	a1 int
137	Sub
138	*Subp
139	a int
140}
141
142func (p *S) test1() int {
143	if p.a != p.a1 {
144		println("SubpSub", p, p.a1)
145		panic("fail")
146	}
147	return p.a
148}
149
150/******
151 ******
152 ******/
153
154func main() {
155	var i I
156	var s *S
157
158	// allocate
159	s = new(S)
160	s.Subp = new(Subp)
161	s.Sub.SubSubp = new(SubSubp)
162	s.Subp.SubpSubp = new(SubpSubp)
163
164	// explicit assignment
165	s.a = 1
166	s.Sub.a = 2
167	s.Subp.a = 3
168	s.Sub.SubSub.a = 4
169	s.Sub.SubSubp.a = 5
170	s.Subp.SubpSub.a = 6
171	s.Subp.SubpSubp.a = 7
172
173	// embedded (unique) assignment
174	s.a1 = 1
175	s.a2 = 2
176	s.a3 = 3
177	s.a4 = 4
178	s.a5 = 5
179	s.a6 = 6
180	s.a7 = 7
181
182	// unique calls with explicit &
183	if s.test1() != 1 {
184		println("t1", 1)
185		panic("fail")
186	}
187	if (&s.Sub).test2() != 2 {
188		println("t1", 2)
189		panic("fail")
190	}
191	if s.Subp.test3() != 3 {
192		println("t1", 3)
193		panic("fail")
194	}
195	if (&s.Sub.SubSub).test4() != 4 {
196		println("t1", 4)
197		panic("fail")
198	}
199	if s.Sub.SubSubp.test5() != 5 {
200		println("t1", 5)
201		panic("fail")
202	}
203	if (&s.Subp.SubpSub).test6() != 6 {
204		println("t1", 6)
205		panic("fail")
206	}
207	if s.Subp.SubpSubp.test7() != 7 {
208		println("t1", 7)
209		panic("fail")
210	}
211
212	// automatic &
213	if s.Sub.test2() != 2 {
214		println("t2", 2)
215		panic("fail")
216	}
217	if s.Sub.SubSub.test4() != 4 {
218		println("t2", 4)
219		panic("fail")
220	}
221	if s.Subp.SubpSub.test6() != 6 {
222		println("t2", 6)
223		panic("fail")
224	}
225
226	// embedded calls
227	if s.test1() != s.a1 {
228		println("t3", 1)
229		panic("fail")
230	}
231	if s.test2() != s.a2 {
232		println("t3", 2)
233		panic("fail")
234	}
235	if s.test3() != s.a3 {
236		println("t3", 3)
237		panic("fail")
238	}
239	if s.test4() != s.a4 {
240		println("t3", 4)
241		panic("fail")
242	}
243	if s.test5() != s.a5 {
244		println("t3", 5)
245		panic("fail")
246	}
247	if s.test6() != s.a6 {
248		println("t3", 6)
249		panic("fail")
250	}
251	if s.test7() != s.a7 {
252		println("t3", 7)
253		panic("fail")
254	}
255
256	// run it through an interface
257	i = s
258	s = i.(*S)
259
260	// same as t3
261	if s.test1() != s.a1 {
262		println("t4", 1)
263		panic("fail")
264	}
265	if s.test2() != s.a2 {
266		println("t4", 2)
267		panic("fail")
268	}
269	if s.test3() != s.a3 {
270		println("t4", 3)
271		panic("fail")
272	}
273	if s.test4() != s.a4 {
274		println("t4", 4)
275		panic("fail")
276	}
277	if s.test5() != s.a5 {
278		println("t4", 5)
279		panic("fail")
280	}
281	if s.test6() != s.a6 {
282		println("t4", 6)
283		panic("fail")
284	}
285	if s.test7() != s.a7 {
286		println("t4", 7)
287		panic("fail")
288	}
289
290	// call interface
291	if i.test1() != s.test1() {
292		println("t5", 1)
293		panic("fail")
294	}
295	if i.test2() != s.test2() {
296		println("t5", 2)
297		panic("fail")
298	}
299	if i.test3() != s.test3() {
300		println("t5", 3)
301		panic("fail")
302	}
303	if i.test4() != s.test4() {
304		println("t5", 4)
305		panic("fail")
306	}
307	if i.test5() != s.test5() {
308		println("t5", 5)
309		panic("fail")
310	}
311	if i.test6() != s.test6() {
312		println("t5", 6)
313		panic("fail")
314	}
315	if i.test7() != s.test7() {
316		println("t5", 7)
317		panic("fail")
318	}
319}
320