]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: operand.AssignableTo must consider Alias types
authorRobert Griesemer <gri@golang.org>
Tue, 21 May 2024 23:22:51 +0000 (16:22 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 22 May 2024 19:44:53 +0000 (19:44 +0000)
Fixes regression from Go 1.22.

For #67547.

Change-Id: Id0d07d6b24e1eab6ed1c7476d9d9b82d28aee80a
Reviewed-on: https://go-review.googlesource.com/c/go/+/587161
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/types2/operand.go
src/go/types/operand.go
src/internal/types/testdata/fixedbugs/issue67547.go

index 15ec86fb5eca33c5d5c972ab3591bfc6e503df99..66002aa6c5d1468fad8ee524b2ee0a73bfe7a66f 100644 (file)
@@ -260,7 +260,9 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
                return true, 0 // avoid spurious errors
        }
 
-       V := x.typ
+       origT := T
+       V := Unalias(x.typ)
+       T = Unalias(T)
 
        // x's type is identical to T
        if Identical(V, T) {
@@ -386,7 +388,7 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
                        x.typ = V.typ
                        ok, code = x.assignableTo(check, T, cause)
                        if !ok {
-                               errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
+                               errorf("cannot assign %s (in %s) to %s", V.typ, Vp, origT)
                                return false
                        }
                        return true
index e1ec376a5c5af2fe8b181d477709cede4fe0b574..fb91e7e61284442d038cda1ded056279db3c7428 100644 (file)
@@ -264,7 +264,9 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
                return true, 0 // avoid spurious errors
        }
 
-       V := x.typ
+       origT := T
+       V := Unalias(x.typ)
+       T = Unalias(T)
 
        // x's type is identical to T
        if Identical(V, T) {
@@ -390,7 +392,7 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
                        x.typ = V.typ
                        ok, code = x.assignableTo(check, T, cause)
                        if !ok {
-                               errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
+                               errorf("cannot assign %s (in %s) to %s", V.typ, Vp, origT)
                                return false
                        }
                        return true
index 1ae01fa2642355c1ba8794ece0473bafc0143e14..791d5d5e90dee687a6fe1dc3887bcc1b79eb766b 100644 (file)
@@ -53,7 +53,28 @@ func _[P int | string]() {
        // preserve target type name A in error messages when using Alias types
        // (test are run with and without Alias types enabled, so we need to
        // keep both A and int in the error message)
-       _ = A(p /* ERRORx "cannot convert string .* to type (A|int)" */)
+       _ = A(p /* ERRORx `cannot convert string \(in P\) to type (A|int)` */)
+}
+
+func _[P struct{ x int }]() {
+       var x struct{ x int }
+       type A = P
+       var _ A = x // assignment must be valid
+}
+
+func _[P struct{ x int }]() {
+       type A = P
+       var x A
+       var _ struct{ x int } = x // assignment must be valid
+}
+
+func _[P []int | struct{}]() {
+       type A = []int
+       var a A
+       var p P
+       // preserve target type name A in error messages when using Alias types
+       a = p // ERRORx `cannot assign struct{} \(in P\) to (A|\[\]int)`
+       _ = a
 }
 
 // Test case for go.dev/issue/67540.