Skip to content

Commit 72ba5b1

Browse files
committed
Support copy() built-in for type params.
1 parent c0dc298 commit 72ba5b1

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

compiler/expressions.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,10 +1112,8 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
11121112
)
11131113
case "copy":
11141114
args = fc.expandTupleArgs(args)
1115-
if basic, isBasic := fc.pkgCtx.TypeOf(args[1]).Underlying().(*types.Basic); isBasic && isString(basic) {
1116-
return fc.formatExpr("$copyString(%e, %e)", args[0], args[1])
1117-
}
1118-
return fc.formatExpr("$copySlice(%e, %e)", args[0], args[1])
1115+
dst, src := args[0], args[1]
1116+
return fc.formatExpr("%s.$copy(%e, %e)", fc.typeName(fc.pkgCtx.TypeOf(src)), dst, src)
11191117
case "print":
11201118
args = fc.expandTupleArgs(args)
11211119
return fc.formatExpr("$print(%s)", strings.Join(fc.translateExprSlice(args, nil), ", "))

compiler/prelude/types.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
9494
typ.wrap = (v) => new typ(v);
9595
typ.keyFor = x => { return "$" + x; };
9696
typ.$len = (v) => v.length;
97+
typ.$copy = (dst, src) => $copyString(dst, src);
9798
break;
9899

99100
case $kindFloat32:
@@ -267,6 +268,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
267268
typ.$make = (size, capacity) => $makeSlice(typ, size, capacity);
268269
typ.$len = (v) => v.$length;
269270
typ.$cap = (v) => v.$capacity;
271+
typ.$copy = (dst, src) => $copySlice(dst, src);
270272
break;
271273

272274
case $kindStruct:

compiler/utils.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ func toJavaScriptType(t *types.Basic) string {
704704
return "Int32"
705705
case types.UnsafePointer:
706706
return "UnsafePointer"
707+
case types.UntypedString:
708+
return "String"
707709
default:
708710
name := t.String()
709711
return strings.ToUpper(name[:1]) + name[1:]

tests/typeparams/builtins_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,34 @@ func TestDelete(t *testing.T) {
225225
t.Errorf("Got: delete(...) = %#v. Want: %#v", got, want)
226226
}
227227
}
228+
229+
func _copy[D []byte, S []byte | string](dst D, src S) int {
230+
return copy(dst, src)
231+
}
232+
233+
func TestCopy(t *testing.T) {
234+
t.Run("string", func(t *testing.T) {
235+
src := "abc"
236+
got := make([]byte, 3)
237+
n := _copy(got, src)
238+
want := []byte{'a', 'b', 'c'}
239+
if !reflect.DeepEqual(want, got) {
240+
t.Errorf("Got: copy result: %v. Want: %v", got, want)
241+
}
242+
if n != 3 {
243+
t.Errorf("Got: copied %d elements. Want: 3", n)
244+
}
245+
})
246+
t.Run("slice", func(t *testing.T) {
247+
src := []byte{'a', 'b', 'c', 'd'}
248+
got := make([]byte, 3)
249+
n := _copy(got, src)
250+
want := []byte{'a', 'b', 'c'}
251+
if !reflect.DeepEqual(want, got) {
252+
t.Errorf("Got: copy result: %v. Want: %v", got, want)
253+
}
254+
if n != 3 {
255+
t.Errorf("Got: copied %d elements. Want: 3", n)
256+
}
257+
})
258+
}

0 commit comments

Comments
 (0)