go/types, types2: operand.convertibleTo must consider Alias types

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>
This commit is contained in:
Robert Griesemer 2024-05-21 15:48:06 -07:00 committed by Gopher Robot
parent 2bf686dfe9
commit 5ab8f90745
3 changed files with 54 additions and 8 deletions

View 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

View 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

View 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)
}