From 6f74ed06c5b0e1d69fb70e89f31f002f18554c79 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 6 Oct 2021 19:38:15 -0700 Subject: [PATCH] go/types: implement copy for generic argument types This is a port of CL 354432 from types2 to go/types with minor adjustments: - an error message has a different position - the constraint literals are wrapped in interfaces because the interface-free notation has not been ported yet Change-Id: I167094b57b39027566f2b7ce3aa97a071bae4da5 Reviewed-on: https://go-review.googlesource.com/c/go/+/354489 Trust: Robert Griesemer Run-TryBot: Robert Griesemer Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Ian Lance Taylor --- src/go/types/builtins.go | 4 +-- src/go/types/testdata/check/builtins.go2 | 37 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go index d805e46666..3e2c994b09 100644 --- a/src/go/types/builtins.go +++ b/src/go/types/builtins.go @@ -341,15 +341,13 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b 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, _Todo, "copy on generic operands not yet implemented") } if dst == nil || src == nil { diff --git a/src/go/types/testdata/check/builtins.go2 b/src/go/types/testdata/check/builtins.go2 index 1c773cc70b..fb912a1918 100644 --- a/src/go/types/testdata/check/builtins.go2 +++ b/src/go/types/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 interface{~[]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 /* ERROR different element types */ , x3) +} + +func _[T interface{~[]E}, E any](x T, y []E) { + copy(x, y) + copy(x /* ERROR different element types */ , "foo") +} + +func _[T interface{~string}](x []byte, y T) { + copy(x, y) + copy(y /* ERROR expects slice arguments */ , x) +} + +func _[T interface{~[]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 } -- 2.50.0