go.tools/go/types: fix recorded type for append(s, "foo"...)

R=adonovan
CC=golang-dev
https://golang.org/cl/14512057
This commit is contained in:
Robert Griesemer 2013-10-11 14:27:44 -07:00
parent aff951c80f
commit 60c505c95c
2 changed files with 9 additions and 11 deletions

View File

@ -88,13 +88,9 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
if isString(x.typ) {
if check.Types != nil {
// TODO(gri, adonovan) change this to:
//
// sig := makeSig(S, S, NewSlice(Typ[Byte]))
// sig.isVariadic = true
//
// once ssa has been adjusted
check.recordBuiltinType(call.Fun, makeSig(S, S, x.typ))
sig := makeSig(S, S, NewSlice(Typ[Byte]))
sig.isVariadic = true
check.recordBuiltinType(call.Fun, sig)
}
x.mode = value
x.typ = S
@ -420,7 +416,6 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode = novalue
if check.Types != nil {
// TODO(gri) we need a global empty interface somewhere
check.recordBuiltinType(call.Fun, makeSig(nil, new(Interface)))
}
@ -449,7 +444,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
case _Recover:
// recover() interface{}
x.mode = value
x.typ = new(Interface) // TODO(gri) we need a global empty interface somewhere
x.typ = new(Interface)
if check.Types != nil {
check.recordBuiltinType(call.Fun, makeSig(x.typ))
}

View File

@ -20,8 +20,11 @@ var builtinCalls = []struct {
{_Append, `var s []int; _ = append(s, 0)`, `func([]int, ...int) []int`},
{_Append, `var s []int; _ = (append)(s, 0)`, `func([]int, ...int) []int`},
{_Append, `var s []byte; _ = ((append))(s, 0)`, `func([]byte, ...byte) []byte`},
{_Append, `var s []byte; _ = append(s, "foo"...)`, `func([]byte, string) []byte`},
{_Append, `type T []byte; var s T; _ = append(s, "foo"...)`, `func(p.T, string) p.T`},
// Note that ...uint8 (instead of ..byte) appears below because that is the type
// that corresponds to Typ[byte] (an alias) - in the other cases, the type name
// is chosen by the source. Either way, byte and uint8 denote identical types.
{_Append, `var s []byte; _ = append(s, "foo"...)`, `func([]byte, ...uint8) []byte`},
{_Append, `type T []byte; var s T; _ = append(s, "foo"...)`, `func(p.T, ...uint8) p.T`},
{_Cap, `var s [10]int; _ = cap(s)`, `invalid type`}, // constant
{_Cap, `var s [10]int; _ = cap(&s)`, `invalid type`}, // constant