]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fix unsymmetric test when typechecking comparisons
authorRobert Griesemer <gri@golang.org>
Fri, 19 Oct 2018 00:39:35 +0000 (17:39 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 19 Oct 2018 17:48:06 +0000 (17:48 +0000)
The existing code assumed that comparability and orderedness
was implied for the 2nd operand if the 1st operand satisfied
these predicates.

Fixes #28164.

Change-Id: I61d4e5eedb3297731a20a14acb3645d11b36fcc5
Reviewed-on: https://go-review.googlesource.com/c/143277
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/go/types/expr.go
src/go/types/testdata/expr2.src

index 87769d1db0868f32c2c1c9ee0a617dde99d309a1..35e9b36f31c63372c51d892b438b082ff943d96b 100644 (file)
@@ -590,10 +590,10 @@ func (check *Checker) comparison(x, y *operand, op token.Token) {
                switch op {
                case token.EQL, token.NEQ:
                        // spec: "The equality operators == and != apply to operands that are comparable."
-                       defined = Comparable(x.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ)
+                       defined = Comparable(x.typ) && Comparable(y.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ)
                case token.LSS, token.LEQ, token.GTR, token.GEQ:
                        // spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
-                       defined = isOrdered(x.typ)
+                       defined = isOrdered(x.typ) && isOrdered(y.typ)
                default:
                        unreachable()
                }
index 31dc5f021c029f47654cdb7ad3cd777b829a7f80..0c959e8011944f0ce42b89bc193e448628bc762f 100644 (file)
@@ -208,6 +208,19 @@ func interfaces() {
 
        _ = i /* ERROR mismatched types */ == s2
        _ = i /* ERROR mismatched types */ == &s2
+
+       // issue #28164
+       // testcase from issue
+       _ = interface /* ERROR cannot compare */ {}(nil) == []int(nil)
+
+       // related cases
+       var e interface{}
+       var s []int
+       var x int
+       _ = e /* ERROR cannot compare */ == s
+       _ = s /* ERROR cannot compare */ == e
+       _ = e /* ERROR cannot compare */ < x
+       _ = x /* ERROR cannot compare */ < e
 }
 
 func slices() {