]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: better error messages for expression switches
authorRobert Griesemer <gri@golang.org>
Wed, 2 Feb 2022 05:43:00 +0000 (21:43 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 4 Feb 2022 23:42:29 +0000 (23:42 +0000)
Fixes #50965.

Change-Id: I61a74bdb46cf5e72ab94dbe8bd114704282b6211
Reviewed-on: https://go-review.googlesource.com/c/go/+/382354
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/testdata/check/stmt0.src
src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.src
src/cmd/compile/internal/types2/testdata/fixedbugs/issue50965.go [new file with mode: 0644]
src/go/types/expr.go
src/go/types/testdata/check/stmt0.src
src/go/types/testdata/fixedbugs/issue43110.src
src/go/types/testdata/fixedbugs/issue50965.go [new file with mode: 0644]

index 442e7121e5e73b1ef013b5cb35ef171df8254c6a..f1696bbe51085179b7240f38d14be9429994d945 100644 (file)
@@ -878,15 +878,14 @@ Error:
                        cause = check.sprintf("operator %s not defined on %s", op, check.kindString(errOp.typ)) // catch-all
                }
        }
-       // For switches, report errors on the first (case) operand.
-       // TODO(gri) adjust error message in that case
        if switchCase {
-               errOp = x
-       }
-       if check.conf.CompilerErrorMessages {
-               check.errorf(errOp, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
+               check.errorf(x, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
        } else {
-               check.errorf(errOp, invalidOp+"cannot compare %s %s %s (%s)", x.expr, op, y.expr, cause)
+               if check.conf.CompilerErrorMessages {
+                       check.errorf(errOp, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
+               } else {
+                       check.errorf(errOp, invalidOp+"cannot compare %s %s %s (%s)", x.expr, op, y.expr, cause)
+               }
        }
        x.mode = invalid
 }
index ed7ce053274b7497ca0cbd41ade90374ae3fb5e6..90ef09511f7bcb098781cf6f469e413334bee323 100644 (file)
@@ -429,7 +429,7 @@ func switches0() {
 
        switch int32(x) {
        case 1, 2:
-       case x /* ERROR "cannot compare" */ :
+       case x /* ERROR "invalid case x in switch on int32\(x\) \(mismatched types int and int32\)" */ :
        }
 
        switch x {
index 4a469452392b5ca503bb5734e5adf8f0f4e6844e..8d5c983fd507aa8690ebcdc2ee3a4d363166628e 100644 (file)
@@ -30,7 +30,7 @@ func _() {
        }
 
        switch (func())(nil) {
-       case f /* ERROR cannot compare */ :
+       case f /* ERROR invalid case f in switch on .* \(func can only be compared to nil\) */ :
        }
 
        switch nil /* ERROR use of untyped nil in switch expression */ {
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50965.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50965.go
new file mode 100644 (file)
index 0000000..bf2dcc9
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2022 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 p
+
+func _(x int, c string) {
+       switch x {
+       case c /* ERROR invalid case c in switch on x \(mismatched types string and int\) */ :
+       }
+}
+
+func _(x, c []int) {
+       switch x {
+       case c /* ERROR invalid case c in switch on x \(slice can only be compared to nil\) */ :
+       }
+}
index c5b27e84b8634f2425d469aa060280d4073eb643..88a8901b07e38ccee1c9e502e1751c4b82074007 100644 (file)
@@ -838,15 +838,14 @@ Error:
                        cause = check.sprintf("operator %s not defined on %s", op, check.kindString(errOp.typ)) // catch-all
                }
        }
-       // For switches, report errors on the first (case) operand.
-       // TODO(gri) adjust error message in that case
        if switchCase {
-               errOp = x
-       }
-       if compilerErrorMessages {
-               check.invalidOp(errOp, code, "%s %s %s (%s)", x.expr, op, y.expr, cause)
+               check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
        } else {
-               check.invalidOp(errOp, code, "cannot compare %s %s %s (%s)", x.expr, op, y.expr, cause)
+               if compilerErrorMessages {
+                       check.invalidOp(errOp, code, "%s %s %s (%s)", x.expr, op, y.expr, cause)
+               } else {
+                       check.invalidOp(errOp, code, "cannot compare %s %s %s (%s)", x.expr, op, y.expr, cause)
+               }
        }
        x.mode = invalid
 }
index ec8bf71013e7770bad0645ed1270f68f7490364a..7795a442aae73d8bc1b80bb2846f9b4de97f22d4 100644 (file)
@@ -429,7 +429,7 @@ func switches0() {
 
        switch int32(x) {
        case 1, 2:
-       case x /* ERROR "cannot compare" */ :
+       case x /* ERROR "invalid case x in switch on int32\(x\) \(mismatched types int and int32\)" */ :
        }
 
        switch x {
index 4a469452392b5ca503bb5734e5adf8f0f4e6844e..8d5c983fd507aa8690ebcdc2ee3a4d363166628e 100644 (file)
@@ -30,7 +30,7 @@ func _() {
        }
 
        switch (func())(nil) {
-       case f /* ERROR cannot compare */ :
+       case f /* ERROR invalid case f in switch on .* \(func can only be compared to nil\) */ :
        }
 
        switch nil /* ERROR use of untyped nil in switch expression */ {
diff --git a/src/go/types/testdata/fixedbugs/issue50965.go b/src/go/types/testdata/fixedbugs/issue50965.go
new file mode 100644 (file)
index 0000000..bf2dcc9
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2022 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 p
+
+func _(x int, c string) {
+       switch x {
+       case c /* ERROR invalid case c in switch on x \(mismatched types string and int\) */ :
+       }
+}
+
+func _(x, c []int) {
+       switch x {
+       case c /* ERROR invalid case c in switch on x \(slice can only be compared to nil\) */ :
+       }
+}