go.tools/go/types: correctly type the copy([]byte, string) builtin

LGTM=gri
R=gri, adonovan
CC=golang-codereviews
https://golang.org/cl/104340046
This commit is contained in:
Peter Collingbourne 2014-06-26 16:50:12 -07:00 committed by Robert Griesemer
parent f38fc6a97a
commit 969a226d69
3 changed files with 13 additions and 9 deletions

View File

@ -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))

View File

@ -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)

View File

@ -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)`},