From 8d464e4ae36c09acfd73a5e3b6dc5a34b6f0202b Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 21 May 2024 16:22:51 -0700 Subject: [PATCH] go/types, types2: operand.AssignableTo must consider Alias types 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 Reviewed-by: Robert Findley Reviewed-by: Robert Griesemer Auto-Submit: Robert Griesemer LUCI-TryBot-Result: Go LUCI --- src/cmd/compile/internal/types2/operand.go | 6 +++-- src/go/types/operand.go | 6 +++-- .../types/testdata/fixedbugs/issue67547.go | 23 ++++++++++++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/cmd/compile/internal/types2/operand.go b/src/cmd/compile/internal/types2/operand.go index 15ec86fb5e..66002aa6c5 100644 --- a/src/cmd/compile/internal/types2/operand.go +++ b/src/cmd/compile/internal/types2/operand.go @@ -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 diff --git a/src/go/types/operand.go b/src/go/types/operand.go index e1ec376a5c..fb91e7e612 100644 --- a/src/go/types/operand.go +++ b/src/go/types/operand.go @@ -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 diff --git a/src/internal/types/testdata/fixedbugs/issue67547.go b/src/internal/types/testdata/fixedbugs/issue67547.go index 1ae01fa264..791d5d5e90 100644 --- a/src/internal/types/testdata/fixedbugs/issue67547.go +++ b/src/internal/types/testdata/fixedbugs/issue67547.go @@ -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.