gc: implement new comparison rule
The new comparison rule was added to the spec by
changeset: 5605:33abb649cb63
user: Robert Griesemer <gri@golang.org>
date: Thu Jun 03 16:55:50 2010 -0700
files: doc/go_spec.html
description:
go spec: Base comparison compatibility on assignment compatibility.
Specifically:
- Simplified definition of comparison compatibility and folded into
section on comparison operators since it's only used there.
This is a small language change/cleanup. As a consequence:
- An interface value may now be compared against a non-interface value.
- Channels with opposite directions cannot be compared directly anymore
(per discussion with rsc).
R=rsc, r, iant, ken2
CC=golang-dev
https://golang.org/cl/1462041
but never implemented.
Fixes #1070.
R=ken2
CC=golang-dev
https://golang.org/cl/2116047
diff --git a/test/cmp1.go b/test/cmp1.go
index db0a486..698544c 100644
--- a/test/cmp1.go
+++ b/test/cmp1.go
@@ -26,6 +26,8 @@
}
}
+type T *int
+
func main() {
var a []int
var b map[string]int
@@ -55,6 +57,24 @@
isfalse(ib == id)
istrue(ic == id)
istrue(ie == ie)
+
+ // these are okay because one side of the
+ // comparison need only be assignable to the other.
+ isfalse(a == ib)
+ isfalse(a == ic)
+ isfalse(a == id)
+ isfalse(b == ic)
+ isfalse(b == id)
+ istrue(c == id)
+ istrue(e == ie)
+
+ isfalse(ia == b)
+ isfalse(ia == c)
+ isfalse(ia == d)
+ isfalse(ib == c)
+ isfalse(ib == d)
+ istrue(ic == d)
+ istrue(ie == e)
// 6g used to let this go through as true.
var g uint64 = 123
@@ -73,4 +93,38 @@
println("m[ic] = ", m[ic])
panic("bad m[ic]")
}
+
+ // non-interface comparisons
+ {
+ c := make(chan int)
+ c1 := (<-chan int)(c)
+ c2 := (chan<- int)(c)
+ istrue(c == c1)
+ istrue(c == c2)
+ istrue(c1 == c)
+ istrue(c2 == c)
+
+ d := make(chan int)
+ isfalse(c == d)
+ isfalse(d == c)
+ isfalse(d == c1)
+ isfalse(d == c2)
+ isfalse(c1 == d)
+ isfalse(c2 == d)
+ }
+
+ // named types vs not
+ {
+ var x = new(int)
+ var y T
+ var z T = x
+
+ isfalse(x == y)
+ istrue(x == z)
+ isfalse(y == z)
+
+ isfalse(y == x)
+ istrue(z == x)
+ isfalse(z == y)
+ }
}
diff --git a/test/cmp6.go b/test/cmp6.go
new file mode 100644
index 0000000..981a859
--- /dev/null
+++ b/test/cmp6.go
@@ -0,0 +1,42 @@
+// errchk $G -e $D/$F.go
+
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func use(bool) {}
+
+type T1 *int
+type T2 *int
+
+func main() {
+ // Arguments to comparison must be
+ // assignable one to the other (or vice versa)
+ // so chan int can be compared against
+ // directional channels but channel of different
+ // direction cannot be compared against each other.
+ var c1 chan <-int
+ var c2 <-chan int
+ var c3 chan int
+
+ use(c1 == c2) // ERROR "invalid operation"
+ use(c2 == c1) // ERROR "invalid operation"
+ use(c1 == c3)
+ use(c2 == c2)
+ use(c3 == c1)
+ use(c3 == c2)
+
+ // Same applies to named types.
+ var p1 T1
+ var p2 T2
+ var p3 *int
+
+ use(p1 == p2) // ERROR "invalid operation"
+ use(p2 == p1) // ERROR "invalid operation"
+ use(p1 == p3)
+ use(p2 == p2)
+ use(p3 == p1)
+ use(p3 == p2)
+}