diff --git a/src/cmd/compile/internal/types2/conversions.go b/src/cmd/compile/internal/types2/conversions.go index 05d0d37192..43208c3d9b 100644 --- a/src/cmd/compile/internal/types2/conversions.go +++ b/src/cmd/compile/internal/types2/conversions.go @@ -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 diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go index f548e177de..d28c2294a7 100644 --- a/src/go/types/conversions.go +++ b/src/go/types/conversions.go @@ -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 diff --git a/src/internal/types/testdata/fixedbugs/issue67547.go b/src/internal/types/testdata/fixedbugs/issue67547.go index 930692aa57..1ae01fa264 100644 --- a/src/internal/types/testdata/fixedbugs/issue67547.go +++ b/src/internal/types/testdata/fixedbugs/issue67547.go @@ -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) +}