mirror of
https://github.com/golang/go
synced 2024-11-26 06:17:57 -07:00
[dev.typeparams] go/types: report better error for invalid untyped operation
This is port of CL 328053 for types2 to go/type. The change is identical, but for some tweaks to the error positions in tests. Updates #46749 Change-Id: I8d34c5b1669e59e4ec7d91f81dcf655b2bfd89a5 Reviewed-on: https://go-review.googlesource.com/c/go/+/328869 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
90096f445e
commit
2a7900762c
@ -875,7 +875,7 @@ const (
|
||||
// context in which it is used.
|
||||
//
|
||||
// Example:
|
||||
// var _ = 1 + ""
|
||||
// var _ = 1 + nil
|
||||
_InvalidUntypedConversion
|
||||
|
||||
// _BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
|
||||
|
@ -927,14 +927,28 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token
|
||||
return
|
||||
}
|
||||
|
||||
check.convertUntyped(x, y.typ)
|
||||
if x.mode == invalid {
|
||||
return
|
||||
canMix := func(x, y *operand) bool {
|
||||
if IsInterface(x.typ) || IsInterface(y.typ) {
|
||||
return true
|
||||
}
|
||||
if isBoolean(x.typ) != isBoolean(y.typ) {
|
||||
return false
|
||||
}
|
||||
if isString(x.typ) != isString(y.typ) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
check.convertUntyped(&y, x.typ)
|
||||
if y.mode == invalid {
|
||||
x.mode = invalid
|
||||
return
|
||||
if canMix(x, &y) {
|
||||
check.convertUntyped(x, y.typ)
|
||||
if x.mode == invalid {
|
||||
return
|
||||
}
|
||||
check.convertUntyped(&y, x.typ)
|
||||
if y.mode == invalid {
|
||||
x.mode = invalid
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if isComparison(op) {
|
||||
|
2
src/go/types/testdata/check/const0.src
vendored
2
src/go/types/testdata/check/const0.src
vendored
@ -27,7 +27,7 @@ const (
|
||||
ub1 = true
|
||||
ub2 = 2 < 1
|
||||
ub3 = ui1 == uf1
|
||||
ub4 = true /* ERROR "cannot convert" */ == 0
|
||||
ub4 = true /* ERROR "mismatched types untyped bool and untyped int" */ == 0
|
||||
|
||||
// integer values
|
||||
ui0 = 0
|
||||
|
2
src/go/types/testdata/check/decls1.src
vendored
2
src/go/types/testdata/check/decls1.src
vendored
@ -83,7 +83,7 @@ var (
|
||||
|
||||
// Constant expression initializations
|
||||
var (
|
||||
v1 = 1 /* ERROR "cannot convert" */ + "foo"
|
||||
v1 = 1 /* ERROR "mismatched types untyped int and untyped string" */ + "foo"
|
||||
v2 = c + 255
|
||||
v3 = c + 256 /* ERROR "overflows" */
|
||||
v4 = r + 2147483647
|
||||
|
4
src/go/types/testdata/check/expr1.src
vendored
4
src/go/types/testdata/check/expr1.src
vendored
@ -111,10 +111,10 @@ type mystring string
|
||||
func _(x, y string, z mystring) {
|
||||
x = x + "foo"
|
||||
x = x /* ERROR not defined */ - "foo"
|
||||
x = x + 1 // ERROR cannot convert
|
||||
x = x /* ERROR mismatched types string and untyped int */ + 1
|
||||
x = x + y
|
||||
x = x /* ERROR not defined */ - y
|
||||
x = x * 10 // ERROR cannot convert
|
||||
x = x /* ERROR mismatched types string and untyped int */* 10
|
||||
}
|
||||
|
||||
func f() (a, b int) { return }
|
||||
|
2
src/go/types/testdata/check/expr2.src
vendored
2
src/go/types/testdata/check/expr2.src
vendored
@ -10,7 +10,7 @@ func _bool() {
|
||||
const t = true == true
|
||||
const f = true == false
|
||||
_ = t /* ERROR "cannot compare" */ < f
|
||||
_ = 0 /* ERROR "cannot convert" */ == t
|
||||
_ = 0 /* ERROR "mismatched types untyped int and untyped bool" */ == t
|
||||
var b bool
|
||||
var x, y float32
|
||||
b = x < y
|
||||
|
2
src/go/types/testdata/check/expr3.src
vendored
2
src/go/types/testdata/check/expr3.src
vendored
@ -103,7 +103,7 @@ func indexes() {
|
||||
var ok mybool
|
||||
_, ok = m["bar"]
|
||||
_ = ok
|
||||
_ = m[0 /* ERROR "cannot use 0" */ ] + "foo" // ERROR "cannot convert"
|
||||
_ = m/* ERROR "mismatched types int and untyped string" */[0 /* ERROR "cannot use 0" */ ] + "foo"
|
||||
|
||||
var t string
|
||||
_ = t[- /* ERROR "negative" */ 1]
|
||||
|
12
src/go/types/testdata/check/stmt0.src
vendored
12
src/go/types/testdata/check/stmt0.src
vendored
@ -49,18 +49,18 @@ func assignments1() {
|
||||
b = true
|
||||
|
||||
i += 1
|
||||
i += "foo" /* ERROR "cannot convert.*int" */
|
||||
i /* ERROR "mismatched types int and untyped string" */+= "foo"
|
||||
|
||||
f -= 1
|
||||
f /= 0
|
||||
f = float32(0)/0 /* ERROR "division by zero" */
|
||||
f -= "foo" /* ERROR "cannot convert.*float64" */
|
||||
f /* ERROR "mismatched types float64 and untyped string" */-= "foo"
|
||||
|
||||
c *= 1
|
||||
c /= 0
|
||||
|
||||
s += "bar"
|
||||
s += 1 /* ERROR "cannot convert.*string" */
|
||||
s /* ERROR "mismatched types string and untyped int" */+= 1
|
||||
|
||||
var u64 uint64
|
||||
u64 += 1<<u64
|
||||
@ -937,13 +937,13 @@ func issue6766b() {
|
||||
// errors reported).
|
||||
func issue10148() {
|
||||
for y /* ERROR declared but not used */ := range "" {
|
||||
_ = "" /* ERROR cannot convert */ + 1
|
||||
_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
|
||||
}
|
||||
for range 1 /* ERROR cannot range over 1 */ {
|
||||
_ = "" /* ERROR cannot convert */ + 1
|
||||
_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
|
||||
}
|
||||
for y := range 1 /* ERROR cannot range over 1 */ {
|
||||
_ = "" /* ERROR cannot convert */ + 1
|
||||
_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user