]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: operand.convertibleTo must consider Alias types
authorRobert Griesemer <gri@golang.org>
Tue, 21 May 2024 22:48:06 +0000 (15:48 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 22 May 2024 18:51:00 +0000 (18:51 +0000)
Fixes regression from Go 1.22.

Fixes #67540.
For #67547.

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

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

index 05d0d37192480ec532ba9d278544249fdf9393f5..43208c3d9b9aae390241f3c7fdf8ea8f9f38a103 100644 (file)
@@ -139,13 +139,16 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
                return true
        }
 
-       // "V and T have identical underlying types if tags are ignored
-       // and V and T are not type parameters"
-       V := x.typ
+       origT := T
+       V := Unalias(x.typ)
+       T = Unalias(T)
        Vu := under(V)
        Tu := under(T)
        Vp, _ := V.(*TypeParam)
        Tp, _ := T.(*TypeParam)
+
+       // "V and T have identical underlying types if tags are ignored
+       // and V and T are not type parameters"
        if IdenticalIgnoreTags(Vu, Tu) && Vp == nil && Tp == nil {
                return true
        }
@@ -267,7 +270,7 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
                        }
                        x.typ = V.typ
                        if !x.convertibleTo(check, T, cause) {
-                               errorf("cannot convert %s (in %s) to type %s", V.typ, Vp, T)
+                               errorf("cannot convert %s (in %s) to type %s", V.typ, Vp, origT)
                                return false
                        }
                        return true
index f548e177de33bedf46355e7f129a2c216d1e6964..d28c2294a7e3dbdafed4516f9bb45b1be2564e1d 100644 (file)
@@ -142,13 +142,16 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
                return true
        }
 
-       // "V and T have identical underlying types if tags are ignored
-       // and V and T are not type parameters"
-       V := x.typ
+       origT := T
+       V := Unalias(x.typ)
+       T = Unalias(T)
        Vu := under(V)
        Tu := under(T)
        Vp, _ := V.(*TypeParam)
        Tp, _ := T.(*TypeParam)
+
+       // "V and T have identical underlying types if tags are ignored
+       // and V and T are not type parameters"
        if IdenticalIgnoreTags(Vu, Tu) && Vp == nil && Tp == nil {
                return true
        }
@@ -270,7 +273,7 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
                        }
                        x.typ = V.typ
                        if !x.convertibleTo(check, T, cause) {
-                               errorf("cannot convert %s (in %s) to type %s", V.typ, Vp, T)
+                               errorf("cannot convert %s (in %s) to type %s", V.typ, Vp, origT)
                                return false
                        }
                        return true
index 930692aa57ae11c931e686ff5cf56a93daed0fa8..1ae01fa2642355c1ba8794ece0473bafc0143e14 100644 (file)
@@ -26,3 +26,43 @@ func _[P map[int]int]() {
        var m A
        clear(m) // don't report an error for m
 }
+
+type S1 struct {
+       x int "S1.x"
+}
+
+type S2 struct {
+       x int "S2.x"
+}
+
+func _[P1 S1, P2 S2]() {
+       type A = P1
+       var p A
+       _ = P2(p) // conversion must be valid
+}
+
+func _[P1 S1, P2 S2]() {
+       var p P1
+       type A = P2
+       _ = A(p) // conversion must be valid
+}
+
+func _[P int | string]() {
+       var p P
+       type A = int
+       // 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)" */)
+}
+
+// Test case for go.dev/issue/67540.
+func _() {
+       type (
+               S struct{}
+               A = *S
+               T S
+       )
+       var p A
+       _ = (*T)(p)
+}