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 behavior of the blank identifier (_).
8
9package main
10
11import (
12	"os"
13	"unsafe"
14)
15
16import _ "fmt"
17
18var call string
19
20type T struct {
21	_, _, _ int
22}
23
24func (T) _() {
25}
26
27func (T) _() {
28}
29
30type U struct {
31	_ struct{ a, b, c int }
32}
33
34const (
35	c0 = iota
36	_
37	_
38	_
39	c4
40)
41
42var ints = []string{
43	"1",
44	"2",
45	"3",
46}
47
48func f() (int, int) {
49	call += "f"
50	return 1, 2
51}
52
53func g() (float64, float64) {
54	call += "g"
55	return 3, 4
56}
57
58func h(_ int, _ float64) {
59}
60
61func i() int {
62	call += "i"
63	return 23
64}
65
66var _ = i()
67
68func main() {
69	if call != "i" {
70		panic("init did not run")
71	}
72	call = ""
73	_, _ = f()
74	a, _ := f()
75	if a != 1 {
76		panic(a)
77	}
78	b, _ := g()
79	if b != 3 {
80		panic(b)
81	}
82	_, a = f()
83	if a != 2 {
84		panic(a)
85	}
86	_, b = g()
87	if b != 4 {
88		panic(b)
89	}
90	_ = i()
91	if call != "ffgfgi" {
92		panic(call)
93	}
94	if c4 != 4 {
95		panic(c4)
96	}
97
98	out := ""
99	for _, s := range ints {
100		out += s
101	}
102	if out != "123" {
103		panic(out)
104	}
105
106	sum := 0
107	for s := range ints {
108		sum += s
109	}
110	if sum != 3 {
111		panic(sum)
112	}
113
114	// go.tools/ssa/interp cannot support unsafe.Pointer.
115	if os.Getenv("GOSSAINTERP") == "" {
116		type T1 struct{ x, y, z int }
117		t1 := *(*T)(unsafe.Pointer(&T1{1, 2, 3}))
118		t2 := *(*T)(unsafe.Pointer(&T1{4, 5, 6}))
119		if t1 != t2 {
120			panic("T{} != T{}")
121		}
122
123		var u1, u2 interface{}
124		u1 = *(*U)(unsafe.Pointer(&T1{1, 2, 3}))
125		u2 = *(*U)(unsafe.Pointer(&T1{4, 5, 6}))
126		if u1 != u2 {
127			panic("U{} != U{}")
128		}
129	}
130
131	h(a, b)
132
133	m()
134}
135
136type I interface {
137	M(_ int, y int)
138}
139
140type TI struct{}
141
142func (_ TI) M(x int, y int) {
143	if x != y {
144		println("invalid M call:", x, y)
145		panic("bad M")
146	}
147}
148
149var fp = func(_ int, y int) {}
150
151func init() {
152	fp = fp1
153}
154
155func fp1(x, y int) {
156	if x != y {
157		println("invalid fp1 call:", x, y)
158		panic("bad fp1")
159	}
160}
161
162func m() {
163	var i I
164
165	i = TI{}
166	i.M(1, 1)
167	i.M(2, 2)
168
169	fp(1, 1)
170	fp(2, 2)
171}
172
173// useless but legal
174var _ int = 1
175var _ = 2
176var _, _ = 3, 4
177
178const _ = 3
179const _, _ = 4, 5
180
181type _ int
182
183func _() {
184	panic("oops")
185}
186
187func ff() {
188	var _ int = 1
189}
190