diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go index b223387f18..d1cb27de16 100644 --- a/src/cmd/compile/internal/types2/expr.go +++ b/src/cmd/compile/internal/types2/expr.go @@ -972,14 +972,28 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op 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) { diff --git a/src/cmd/compile/internal/types2/testdata/check/const0.src b/src/cmd/compile/internal/types2/testdata/check/const0.src index 5608b1549b..3cffdf904c 100644 --- a/src/cmd/compile/internal/types2/testdata/check/const0.src +++ b/src/cmd/compile/internal/types2/testdata/check/const0.src @@ -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 diff --git a/src/cmd/compile/internal/types2/testdata/check/decls1.src b/src/cmd/compile/internal/types2/testdata/check/decls1.src index e6beb78358..1167ced366 100644 --- a/src/cmd/compile/internal/types2/testdata/check/decls1.src +++ b/src/cmd/compile/internal/types2/testdata/check/decls1.src @@ -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 diff --git a/src/cmd/compile/internal/types2/testdata/check/expr1.src b/src/cmd/compile/internal/types2/testdata/check/expr1.src index 4ead815158..85ad234bbb 100644 --- a/src/cmd/compile/internal/types2/testdata/check/expr1.src +++ b/src/cmd/compile/internal/types2/testdata/check/expr1.src @@ -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 + 1 // ERROR mismatched types string and untyped int x = x + y x = x /* ERROR not defined */ - y - x = x * 10 // ERROR cannot convert + x = x * 10 // ERROR mismatched types string and untyped int } func f() (a, b int) { return } diff --git a/src/cmd/compile/internal/types2/testdata/check/expr2.src b/src/cmd/compile/internal/types2/testdata/check/expr2.src index 0c959e8011..f9726b5de5 100644 --- a/src/cmd/compile/internal/types2/testdata/check/expr2.src +++ b/src/cmd/compile/internal/types2/testdata/check/expr2.src @@ -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 diff --git a/src/cmd/compile/internal/types2/testdata/check/expr3.src b/src/cmd/compile/internal/types2/testdata/check/expr3.src index eab3f72c4d..fd28421dc8 100644 --- a/src/cmd/compile/internal/types2/testdata/check/expr3.src +++ b/src/cmd/compile/internal/types2/testdata/check/expr3.src @@ -104,7 +104,7 @@ func indexes() { var ok mybool _, ok = m["bar"] _ = ok - _ = m[0 /* ERROR "cannot use 0" */ ] + "foo" // ERROR "cannot convert" + _ = m[0 /* ERROR "cannot use 0" */ ] + "foo" // ERROR "mismatched types int and untyped string" var t string _ = t[- /* ERROR "negative" */ 1] diff --git a/src/cmd/compile/internal/types2/testdata/check/stmt0.src b/src/cmd/compile/internal/types2/testdata/check/stmt0.src index bedcbe5fce..d744f2ba81 100644 --- a/src/cmd/compile/internal/types2/testdata/check/stmt0.src +++ b/src/cmd/compile/internal/types2/testdata/check/stmt0.src @@ -49,18 +49,18 @@ func assignments1() { b = true i += 1 - i += "foo" /* ERROR "cannot convert.*int" */ + i += "foo" /* ERROR "mismatched types int and untyped string" */ f -= 1 f /= 0 f = float32(0)/0 /* ERROR "division by zero" */ - f -= "foo" /* ERROR "cannot convert.*float64" */ + f -= "foo" /* ERROR "mismatched types float64 and untyped string" */ c *= 1 c /= 0 s += "bar" - s += 1 /* ERROR "cannot convert.*string" */ + s += 1 /* ERROR "mismatched types string and untyped int" */ var u64 uint64 u64 += 1<