From: Robert Griesemer Date: Wed, 2 Feb 2022 05:43:00 +0000 (-0800) Subject: go/types, types2: better error messages for expression switches X-Git-Tag: go1.18rc1~99 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=63e833154c230e9f46b41f913b12d3c72912cabc;p=gostls13.git go/types, types2: better error messages for expression switches Fixes #50965. Change-Id: I61a74bdb46cf5e72ab94dbe8bd114704282b6211 Reviewed-on: https://go-review.googlesource.com/c/go/+/382354 Trust: Robert Griesemer Reviewed-by: Robert Findley --- diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go index 442e7121e5..f1696bbe51 100644 --- a/src/cmd/compile/internal/types2/expr.go +++ b/src/cmd/compile/internal/types2/expr.go @@ -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 } diff --git a/src/cmd/compile/internal/types2/testdata/check/stmt0.src b/src/cmd/compile/internal/types2/testdata/check/stmt0.src index ed7ce05327..90ef09511f 100644 --- a/src/cmd/compile/internal/types2/testdata/check/stmt0.src +++ b/src/cmd/compile/internal/types2/testdata/check/stmt0.src @@ -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 { diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.src index 4a46945239..8d5c983fd5 100644 --- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.src +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.src @@ -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 index 0000000000..bf2dcc93d0 --- /dev/null +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50965.go @@ -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\) */ : + } +} diff --git a/src/go/types/expr.go b/src/go/types/expr.go index c5b27e84b8..88a8901b07 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -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 } diff --git a/src/go/types/testdata/check/stmt0.src b/src/go/types/testdata/check/stmt0.src index ec8bf71013..7795a442aa 100644 --- a/src/go/types/testdata/check/stmt0.src +++ b/src/go/types/testdata/check/stmt0.src @@ -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 { diff --git a/src/go/types/testdata/fixedbugs/issue43110.src b/src/go/types/testdata/fixedbugs/issue43110.src index 4a46945239..8d5c983fd5 100644 --- a/src/go/types/testdata/fixedbugs/issue43110.src +++ b/src/go/types/testdata/fixedbugs/issue43110.src @@ -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 index 0000000000..bf2dcc93d0 --- /dev/null +++ b/src/go/types/testdata/fixedbugs/issue50965.go @@ -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\) */ : + } +}