1// errorcheck
2
3// Copyright 2010 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// Verify that incorrect comparisons are detected.
8// Does not compile.
9
10package main
11
12func use(bool) {}
13
14type T1 *int
15type T2 *int
16
17type T3 struct{ z []int }
18
19var t3 T3
20
21type T4 struct {
22	_ []int
23	a float64
24}
25
26var t4 T4
27
28func main() {
29	// Arguments to comparison must be
30	// assignable one to the other (or vice versa)
31	// so chan int can be compared against
32	// directional channels but channel of different
33	// direction cannot be compared against each other.
34	var c1 chan<- int
35	var c2 <-chan int
36	var c3 chan int
37
38	use(c1 == c2) // ERROR "invalid operation|incompatible"
39	use(c2 == c1) // ERROR "invalid operation|incompatible"
40	use(c1 == c3)
41	use(c2 == c2)
42	use(c3 == c1)
43	use(c3 == c2)
44
45	// Same applies to named types.
46	var p1 T1
47	var p2 T2
48	var p3 *int
49
50	use(p1 == p2) // ERROR "invalid operation|incompatible"
51	use(p2 == p1) // ERROR "invalid operation|incompatible"
52	use(p1 == p3)
53	use(p2 == p2)
54	use(p3 == p1)
55	use(p3 == p2)
56
57	// Arrays are comparable if and only if their element type is comparable.
58	var a1 [1]int
59	var a2 [1]func()
60	var a3 [0]func()
61	use(a1 == a1)
62	use(a2 == a2) // ERROR "invalid operation|invalid comparison"
63	use(a3 == a3) // ERROR "invalid operation|invalid comparison"
64
65	// Comparison of structs should have a good message
66	use(t3 == t3) // ERROR "struct|expected|cannot compare"
67	use(t4 == t4) // ERROR "cannot be compared|non-comparable|cannot compare"
68
69	// Slices, functions, and maps too.
70	var x []int
71	var f func()
72	var m map[int]int
73	use(x == x) // ERROR "slice can only be compared to nil|cannot compare"
74	use(f == f) // ERROR "func can only be compared to nil|cannot compare"
75	use(m == m) // ERROR "map can only be compared to nil|cannot compare"
76
77	// Comparison with interface that cannot return true
78	// (would panic).
79	var i interface{}
80	use(i == x) // ERROR "invalid operation"
81	use(x == i) // ERROR "invalid operation"
82	use(i == f) // ERROR "invalid operation"
83	use(f == i) // ERROR "invalid operation"
84	use(i == m) // ERROR "invalid operation"
85	use(m == i) // ERROR "invalid operation"
86}
87