]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: make types2 report better error for invalid untyped...
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 16 Jun 2021 09:23:44 +0000 (16:23 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 17 Jun 2021 02:30:22 +0000 (02:30 +0000)
This ports the fix in CL 328050 for typecheck to types2.

The fix is not identical, due to code structure differences between
typecheck and types2, but the idea is the same. We only do the untyped
conversion when both operands can be mixed.

Updates #46749

Change-Id: Ib2c63ba0d5dd8bf02318b1bfdfe51dcaeeeb7f82
Reviewed-on: https://go-review.googlesource.com/c/go/+/328053
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 Griesemer <gri@golang.org>
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/testdata/check/const0.src
src/cmd/compile/internal/types2/testdata/check/decls1.src
src/cmd/compile/internal/types2/testdata/check/expr1.src
src/cmd/compile/internal/types2/testdata/check/expr2.src
src/cmd/compile/internal/types2/testdata/check/expr3.src
src/cmd/compile/internal/types2/testdata/check/stmt0.src
test/fixedbugs/issue41500.go
test/fixedbugs/issue43762.go
test/fixedbugs/issue46749.go
test/run.go

index b223387f18e2c97ed3ee6a7bbb109dee74383537..d1cb27de1604ef1b18653fd187baaadb49077295 100644 (file)
@@ -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) {
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 e6beb7835897bc12ae90eed4c1007b956ac33a21..1167ced366e2bff73453c5bf09559c54c8f0ece4 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..85ad234bbbf46833d33c6328b38192c5a9bd88d4 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 + 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 }
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 eab3f72c4d5ff0d323151f3c3b9feff11cf29de3..fd28421dc89bebb56bd26d3dbafeee77613ba768 100644 (file)
@@ -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]
index bedcbe5fce3573f8aea5c8c8b2fb73786c0a9b17..d744f2ba814d593f0df5fb200b069bef1ab45cae 100644 (file)
@@ -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<<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
        }
 }
 
index 3ec23a0dfe08ba973230b633a1e59058127d6e35..b0ae7cfd59f575326239970c1e48978078134f3a 100644 (file)
@@ -13,8 +13,8 @@ type s struct {
 func f() {
        var x *s
 
-       _ = x == nil || len(x.slice) // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)|incompatible types|cannot convert"
-       _ = len(x.slice) || x == nil // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)|incompatible types|cannot convert"
-       _ = x == nil && len(x.slice) // ERROR "invalid operation: .+ \(operator && not defined on int\)|incompatible types|cannot convert"
-       _ = len(x.slice) && x == nil // ERROR "invalid operation: .+ \(operator && not defined on int\)|incompatible types|cannot convert"
+       _ = x == nil || len(x.slice) // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)|incompatible types|mismatched types untyped bool and int"
+       _ = len(x.slice) || x == nil // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)|incompatible types|mismatched types int and untyped bool"
+       _ = x == nil && len(x.slice) // ERROR "invalid operation: .+ \(operator && not defined on int\)|incompatible types|mismatched types untyped bool and int"
+       _ = len(x.slice) && x == nil // ERROR "invalid operation: .+ \(operator && not defined on int\)|incompatible types|mismatched types int and untyped bool"
 }
index 9f7682ad6ac50b013a0e513b25bf55e9395a9c9b..bf950c8f524d58266ccdaaefdb1cf4bf21bea7e0 100644 (file)
@@ -6,6 +6,6 @@
 
 package p
 
-var _ = true == '\\' // ERROR "invalid operation: true == '\\\\'|cannot convert true"
-var _ = true == '\'' // ERROR "invalid operation: true == '\\''|cannot convert true"
-var _ = true == '\n' // ERROR "invalid operation: true == '\\n'|cannot convert true"
+var _ = true == '\\' // ERROR "invalid operation: (cannot compare true)|(true) == '\\\\' \(mismatched types untyped bool and untyped rune\)"
+var _ = true == '\'' // ERROR "invalid operation: (cannot compare true)|(true) == '\\'' \(mismatched types untyped bool and untyped rune\)"
+var _ = true == '\n' // ERROR "invalid operation: (cannot compare true)|(true) == '\\n' \(mismatched types untyped bool and untyped rune\)"
index 63ed19795e5fc7ccde39515d9a34ac1fed0a63de..faf1f884a6b40cde9d83a606b77a25314091315f 100644 (file)
@@ -14,13 +14,13 @@ var iface interface{}
 var (
        _ = "" + b   // ERROR "invalid operation.*mismatched types.*untyped string and bool"
        _ = "" + i   // ERROR "invalid operation.*mismatched types.*untyped string and int"
-       _ = "" + nil // ERROR "invalid operation.*mismatched types.*untyped string and nil"
+       _ = "" + nil // ERROR "invalid operation.*mismatched types.*untyped string and nil|(untyped nil)"
 )
 
 var (
        _ = s + false // ERROR "invalid operation.*mismatched types.*string and untyped bool"
        _ = s + 1     // ERROR "invalid operation.*mismatched types.*string and untyped int"
-       _ = s + nil   // ERROR "invalid operation.*mismatched types.*string and nil"
+       _ = s + nil   // ERROR "invalid operation.*mismatched types.*string and nil|(untyped nil)"
 )
 
 var (
@@ -31,7 +31,7 @@ var (
 var (
        _ = b + 1         // ERROR "invalid operation.*mismatched types.*bool and untyped int"
        _ = i + false     // ERROR "invalid operation.*mismatched types.*int and untyped bool"
-       _ = iface + 1     // ERROR "invalid operation.*mismatched types.*interface {} and int"
-       _ = iface + 1.0   // ERROR "invalid operation.*mismatched types.*interface {} and float64"
-       _ = iface + false // ERROR "invalid operation.*mismatched types.*interface {} and bool"
+       _ = iface + 1     // ERROR "invalid operation.*mismatched types.*interface *{} and int"
+       _ = iface + 1.0   // ERROR "invalid operation.*mismatched types.*interface *{} and float64"
+       _ = iface + false // ERROR "invalid operation.*mismatched types.*interface *{} and bool"
 )
index 1273b8edd6b843b1a8394ea64892d49576cf23a0..656519e301722c9ed4c1e089d78775e43f83756b 100644 (file)
@@ -2089,7 +2089,6 @@ var excludedFiles = map[string]bool{
        "fixedbugs/issue7525d.go":  true, // types2 reports init cycle error on different line - ok otherwise
        "fixedbugs/issue7525e.go":  true, // types2 reports init cycle error on different line - ok otherwise
        "fixedbugs/issue7525.go":   true, // types2 reports init cycle error on different line - ok otherwise
-       "fixedbugs/issue46749.go":  true, // types2 reports can not convert error instead of type mismatched
        "fixedbugs/issue9691.go":   true, // "cannot assign to int(.autotmp_4)" (probably irgen's fault)
 
        // tests that rely on -m diagnostics, which currently differ with -G=3