From 969a226d692c9ee3ba6439be5ea898596fd396a2 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 26 Jun 2014 16:50:12 -0700 Subject: [PATCH] go.tools/go/types: correctly type the copy([]byte, string) builtin LGTM=gri R=gri, adonovan CC=golang-codereviews https://golang.org/cl/104340046 --- go/ssa/interp/ops.go | 10 ++++++---- go/types/builtins.go | 7 +++---- go/types/builtins_test.go | 5 ++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/go/ssa/interp/ops.go b/go/ssa/interp/ops.go index 86aaee0e..b1fca002 100644 --- a/go/ssa/interp/ops.go +++ b/go/ssa/interp/ops.go @@ -952,11 +952,13 @@ func callBuiltin(caller *frame, callpos token.Pos, fn *ssa.Builtin, args []value // append([]T, ...[]T) []T return append(args[0].([]value), args[1].([]value)...) - case "copy": // copy([]T, []T) int - if _, ok := args[1].(string); ok { - panic("copy([]byte, string) not yet implemented") + case "copy": // copy([]T, []T) int or copy([]byte, string) int + src := args[1] + if _, ok := src.(string); ok { + params := fn.Type().(*types.Signature).Params() + src = conv(params.At(0).Type(), params.At(1).Type(), src) } - return copy(args[0].([]value), args[1].([]value)) + return copy(args[0].([]value), src.([]value)) case "close": // close(chan T) close(args[0].(chan value)) diff --git a/go/types/builtins.go b/go/types/builtins.go index aca43225..cc048e3a 100644 --- a/go/types/builtins.go +++ b/go/types/builtins.go @@ -302,12 +302,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b return } + if check.Types != nil { + check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ)) + } x.mode = value x.typ = Typ[Int] - if check.Types != nil { - S := NewSlice(dst) - check.recordBuiltinType(call.Fun, makeSig(x.typ, S, S)) - } case _Delete: // delete(m, k) diff --git a/go/types/builtins_test.go b/go/types/builtins_test.go index ca3bac88..8afcb6ba 100644 --- a/go/types/builtins_test.go +++ b/go/types/builtins_test.go @@ -50,7 +50,10 @@ var builtinCalls = []struct { {"complex", `type F64 float64; var re, im F64; _ = complex(re, im)`, `func(p.F64, p.F64) complex128`}, {"copy", `var src, dst []byte; copy(dst, src)`, `func([]byte, []byte) int`}, - {"copy", `type T [][]int; var src, dst T; _ = copy(dst, src)`, `func([][]int, [][]int) int`}, + {"copy", `type T [][]int; var src, dst T; _ = copy(dst, src)`, `func(p.T, p.T) int`}, + {"copy", `var src string; var dst []byte; copy(dst, src)`, `func([]byte, string) int`}, + {"copy", `type T string; type U []byte; var src T; var dst U; copy(dst, src)`, `func(p.U, p.T) int`}, + {"copy", `var dst []byte; copy(dst, "hello")`, `func([]byte, string) int`}, {"delete", `var m map[string]bool; delete(m, "foo")`, `func(map[string]bool, string)`}, {"delete", `type (K string; V int); var m map[K]V; delete(m, "foo")`, `func(map[p.K]p.V, p.K)`},