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 switch statements.
8
9package main
10
11import "os"
12
13func assert(cond bool, msg string) {
14	if !cond {
15		print("assertion fail: ", msg, "\n")
16		panic(1)
17	}
18}
19
20func main() {
21	i5 := 5
22	i7 := 7
23	hello := "hello"
24
25	switch true {
26	case i5 < 5:
27		assert(false, "<")
28	case i5 == 5:
29		assert(true, "!")
30	case i5 > 5:
31		assert(false, ">")
32	}
33
34	switch {
35	case i5 < 5:
36		assert(false, "<")
37	case i5 == 5:
38		assert(true, "!")
39	case i5 > 5:
40		assert(false, ">")
41	}
42
43	switch x := 5; true {
44	case i5 < x:
45		assert(false, "<")
46	case i5 == x:
47		assert(true, "!")
48	case i5 > x:
49		assert(false, ">")
50	}
51
52	switch x := 5; true {
53	case i5 < x:
54		assert(false, "<")
55	case i5 == x:
56		assert(true, "!")
57	case i5 > x:
58		assert(false, ">")
59	}
60
61	switch i5 {
62	case 0:
63		assert(false, "0")
64	case 1:
65		assert(false, "1")
66	case 2:
67		assert(false, "2")
68	case 3:
69		assert(false, "3")
70	case 4:
71		assert(false, "4")
72	case 5:
73		assert(true, "5")
74	case 6:
75		assert(false, "6")
76	case 7:
77		assert(false, "7")
78	case 8:
79		assert(false, "8")
80	case 9:
81		assert(false, "9")
82	default:
83		assert(false, "default")
84	}
85
86	switch i5 {
87	case 0, 1, 2, 3, 4:
88		assert(false, "4")
89	case 5:
90		assert(true, "5")
91	case 6, 7, 8, 9:
92		assert(false, "9")
93	default:
94		assert(false, "default")
95	}
96
97	switch i5 {
98	case 0:
99	case 1:
100	case 2:
101	case 3:
102	case 4:
103		assert(false, "4")
104	case 5:
105		assert(true, "5")
106	case 6:
107	case 7:
108	case 8:
109	case 9:
110	default:
111		assert(i5 == 5, "good")
112	}
113
114	switch i5 {
115	case 0:
116		dummy := 0
117		_ = dummy
118		fallthrough
119	case 1:
120		dummy := 0
121		_ = dummy
122		fallthrough
123	case 2:
124		dummy := 0
125		_ = dummy
126		fallthrough
127	case 3:
128		dummy := 0
129		_ = dummy
130		fallthrough
131	case 4:
132		dummy := 0
133		_ = dummy
134		assert(false, "4")
135	case 5:
136		dummy := 0
137		_ = dummy
138		fallthrough
139	case 6:
140		dummy := 0
141		_ = dummy
142		fallthrough
143	case 7:
144		dummy := 0
145		_ = dummy
146		fallthrough
147	case 8:
148		dummy := 0
149		_ = dummy
150		fallthrough
151	case 9:
152		dummy := 0
153		_ = dummy
154		fallthrough
155	default:
156		dummy := 0
157		_ = dummy
158		assert(i5 == 5, "good")
159	}
160
161	fired := false
162	switch i5 {
163	case 0:
164		dummy := 0
165		_ = dummy
166		fallthrough // tests scoping of cases
167	case 1:
168		dummy := 0
169		_ = dummy
170		fallthrough
171	case 2:
172		dummy := 0
173		_ = dummy
174		fallthrough
175	case 3:
176		dummy := 0
177		_ = dummy
178		fallthrough
179	case 4:
180		dummy := 0
181		_ = dummy
182		assert(false, "4")
183	case 5:
184		dummy := 0
185		_ = dummy
186		fallthrough
187	case 6:
188		dummy := 0
189		_ = dummy
190		fallthrough
191	case 7:
192		dummy := 0
193		_ = dummy
194		fallthrough
195	case 8:
196		dummy := 0
197		_ = dummy
198		fallthrough
199	case 9:
200		dummy := 0
201		_ = dummy
202		fallthrough
203	default:
204		dummy := 0
205		_ = dummy
206		fired = !fired
207		assert(i5 == 5, "good")
208	}
209	assert(fired, "fired")
210
211	count := 0
212	switch i5 {
213	case 0:
214		count = count + 1
215		fallthrough
216	case 1:
217		count = count + 1
218		fallthrough
219	case 2:
220		count = count + 1
221		fallthrough
222	case 3:
223		count = count + 1
224		fallthrough
225	case 4:
226		count = count + 1
227		assert(false, "4")
228	case 5:
229		count = count + 1
230		fallthrough
231	case 6:
232		count = count + 1
233		fallthrough
234	case 7:
235		count = count + 1
236		fallthrough
237	case 8:
238		count = count + 1
239		fallthrough
240	case 9:
241		count = count + 1
242		fallthrough
243	default:
244		assert(i5 == count, "good")
245	}
246	assert(fired, "fired")
247
248	switch hello {
249	case "wowie":
250		assert(false, "wowie")
251	case "hello":
252		assert(true, "hello")
253	case "jumpn":
254		assert(false, "jumpn")
255	default:
256		assert(false, "default")
257	}
258
259	fired = false
260	switch i := i5 + 2; i {
261	case i7:
262		fired = true
263	default:
264		assert(false, "fail")
265	}
266	assert(fired, "var")
267
268	// switch on nil-only comparison types
269	switch f := func() {}; f {
270	case nil:
271		assert(false, "f should not be nil")
272	default:
273	}
274
275	switch m := make(map[int]int); m {
276	case nil:
277		assert(false, "m should not be nil")
278	default:
279	}
280
281	switch a := make([]int, 1); a {
282	case nil:
283		assert(false, "m should not be nil")
284	default:
285	}
286
287	// switch on interface.
288	switch i := interface{}("hello"); i {
289	case 42:
290		assert(false, `i should be "hello"`)
291	case "hello":
292		assert(true, "hello")
293	default:
294		assert(false, `i should be "hello"`)
295	}
296
297	// switch on implicit bool converted to interface
298	// was broken: see issue 3980
299	switch i := interface{}(true); {
300	case i:
301		assert(true, "true")
302	case false:
303		assert(false, "i should be true")
304	default:
305		assert(false, "i should be true")
306	}
307
308	// switch on interface with constant cases differing by type.
309	// was rejected by compiler: see issue 4781
310	type T int
311	type B bool
312	type F float64
313	type S string
314	switch i := interface{}(float64(1.0)); i {
315	case nil:
316		assert(false, "i should be float64(1.0)")
317	case (*int)(nil):
318		assert(false, "i should be float64(1.0)")
319	case 1:
320		assert(false, "i should be float64(1.0)")
321	case T(1):
322		assert(false, "i should be float64(1.0)")
323	case F(1.0):
324		assert(false, "i should be float64(1.0)")
325	case 1.0:
326		assert(true, "true")
327	case "hello":
328		assert(false, "i should be float64(1.0)")
329	case S("hello"):
330		assert(false, "i should be float64(1.0)")
331	case true, B(false):
332		assert(false, "i should be float64(1.0)")
333	case false, B(true):
334		assert(false, "i should be float64(1.0)")
335	}
336
337	// switch on array.
338	switch ar := [3]int{1, 2, 3}; ar {
339	case [3]int{1, 2, 3}:
340		assert(true, "[1 2 3]")
341	case [3]int{4, 5, 6}:
342		assert(false, "ar should be [1 2 3]")
343	default:
344		assert(false, "ar should be [1 2 3]")
345	}
346
347	// switch on channel
348	switch c1, c2 := make(chan int), make(chan int); c1 {
349	case nil:
350		assert(false, "c1 did not match itself")
351	case c2:
352		assert(false, "c1 did not match itself")
353	case c1:
354		assert(true, "chan")
355	default:
356		assert(false, "c1 did not match itself")
357	}
358
359	// empty switch
360	switch {
361	}
362
363	// empty switch with default case.
364	fired = false
365	switch {
366	default:
367		fired = true
368	}
369	assert(fired, "fail")
370
371	// Default and fallthrough.
372	count = 0
373	switch {
374	default:
375		count++
376		fallthrough
377	case false:
378		count++
379	}
380	assert(count == 2, "fail")
381
382	// fallthrough to default, which is not at end.
383	count = 0
384	switch i5 {
385	case 5:
386		count++
387		fallthrough
388	default:
389		count++
390	case 6:
391		count++
392	}
393	assert(count == 2, "fail")
394
395	i := 0
396	switch x := 5; {
397	case i < x:
398		os.Exit(0)
399	case i == x:
400	case i > x:
401		os.Exit(1)
402	}
403}
404