From 39bbf08e7139d0e041b0633945a42d0621d2897e Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 6 Oct 2021 18:23:06 -0700 Subject: [PATCH] cmd/compile/internal/types2: implement copy for generic argument types For now, the underlying types of the the argument types' constraints must be a single type that is a slice (the source operand may also be a string). Change-Id: I9e705e3349c9242f126b9c3e0af65e9ffb25fe6e Reviewed-on: https://go-review.googlesource.com/c/go/+/354432 Trust: Robert Griesemer Run-TryBot: Robert Griesemer Reviewed-by: Ian Lance Taylor --- src/cmd/compile/internal/types2/builtins.go | 4 +- .../types2/testdata/check/builtins.go2 | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go index 3b8d85859a..cb4d93c6c4 100644 --- a/src/cmd/compile/internal/types2/builtins.go +++ b/src/cmd/compile/internal/types2/builtins.go @@ -336,15 +336,13 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) ( return } var src Type - switch t := under(y.typ).(type) { + switch t := optype(y.typ).(type) { case *Basic: if isString(y.typ) { src = universeByte } case *Slice: src = t.elem - case *TypeParam: - check.error(x, "copy on generic operands not yet implemented") } if dst == nil || src == nil { diff --git a/src/cmd/compile/internal/types2/testdata/check/builtins.go2 b/src/cmd/compile/internal/types2/testdata/check/builtins.go2 index 0cfea93bf6..243e888ff7 100644 --- a/src/cmd/compile/internal/types2/testdata/check/builtins.go2 +++ b/src/cmd/compile/internal/types2/testdata/check/builtins.go2 @@ -45,6 +45,43 @@ func _[T C5[X], X any](ch T) { close(ch) } +// copy + +func _[T any](x, y T) { + copy(x /* ERROR copy expects slice arguments */ , y) +} + +func _[T ~[]byte](x, y T) { + copy(x, y) + copy(x, "foo") + copy("foo" /* ERROR expects slice arguments */ , y) + + var x2 []byte + copy(x2, y) // element types are identical + copy(y, x2) // element types are identical + + type myByte byte + var x3 []myByte + copy(x3 /* ERROR different element types */ , y) + copy(y, x3 /* ERROR different element types */ ) +} + +func _[T ~[]E, E any](x T, y []E) { + copy(x, y) + copy(x /* ERROR different element types */ , "foo") +} + +func _[T ~string](x []byte, y T) { + copy(x, y) + copy(y /* ERROR expects slice arguments */ , x) +} + +func _[T ~[]byte|~string](x T, y []byte) { + copy(x /* ERROR expects slice arguments */ , y) + // TODO(gri) should this be valid? + copy(y /* ERROR expects slice arguments */ , x) +} + // delete type M0 interface{ int }