From 63e833154c230e9f46b41f913b12d3c72912cabc Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 1 Feb 2022 21:43:00 -0800 Subject: [PATCH] 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 --- src/cmd/compile/internal/types2/expr.go | 13 ++++++------- .../internal/types2/testdata/check/stmt0.src | 2 +- .../types2/testdata/fixedbugs/issue43110.src | 2 +- .../types2/testdata/fixedbugs/issue50965.go | 17 +++++++++++++++++ src/go/types/expr.go | 13 ++++++------- src/go/types/testdata/check/stmt0.src | 2 +- src/go/types/testdata/fixedbugs/issue43110.src | 2 +- src/go/types/testdata/fixedbugs/issue50965.go | 17 +++++++++++++++++ 8 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 src/cmd/compile/internal/types2/testdata/fixedbugs/issue50965.go create mode 100644 src/go/types/testdata/fixedbugs/issue50965.go diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go index 442e7121e5e..f1696bbe510 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 ed7ce053274..90ef09511f7 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 4a469452392..8d5c983fd50 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 00000000000..bf2dcc93d02 --- /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 c5b27e84b86..88a8901b07e 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 ec8bf71013e..7795a442aae 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 4a469452392..8d5c983fd50 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 00000000000..bf2dcc93d02 --- /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\) */ : + } +}