]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: report better error for invalid untyped operation
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 17 Jun 2021 03:14:07 +0000 (10:14 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 18 Jun 2021 02:07:04 +0000 (02:07 +0000)
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>
src/go/types/errorcodes.go
src/go/types/expr.go
src/go/types/testdata/check/const0.src
src/go/types/testdata/check/decls1.src
src/go/types/testdata/check/expr1.src
src/go/types/testdata/check/expr2.src
src/go/types/testdata/check/expr3.src
src/go/types/testdata/check/stmt0.src

index 2afb6a383c949f9caf72ccf9ba90ef854fc652c2..bcc850f75381f32bd6ca3f7c88b708195c5d8e04 100644 (file)
@@ -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
index b7cc6e8ae7b83124f1a05d5614eecff30a15a20d..402d96f66a4d44044561102edb13f55b02fd5417 100644 (file)
@@ -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) {
index 5608b1549ba8d7774c2463fa9faab3702673f061..3cffdf904c87feb265ee5b1293d07be185e17372 100644 (file)
@@ -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
index f4d2eaba91150a5c82780e536716e21ab09f43ef..6fe349b0b2fda71f7c6369ed4f139b6bc4737496 100644 (file)
@@ -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
index 4ead815158f61e2dbbb91dec8e7feabef4a3923c..42b95fbb37bec2810aaff3a75b73d2e2ca79b8fc 100644 (file)
@@ -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 }
index 0c959e8011944f0ce42b89bc193e448628bc762f..f9726b5de53202c301757e36ea5bde812cd3db24 100644 (file)
@@ -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
index 0525a5a33ae09012954ff7aa7c8b0d1e89733356..3ab367810f5172bf5354c9835b144e0ed1ff4b8b 100644 (file)
@@ -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]
index 76b6e70d63bacd703871aedfc02778196a7b5e6a..15df37703c1cb052175b2f810103a74eddf88e03 100644 (file)
@@ -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
        }
 }