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:
parent
aff951c80f
commit
60c505c95c
|
@ -88,13 +88,9 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
||||||
}
|
}
|
||||||
if isString(x.typ) {
|
if isString(x.typ) {
|
||||||
if check.Types != nil {
|
if check.Types != nil {
|
||||||
// TODO(gri, adonovan) change this to:
|
sig := makeSig(S, S, NewSlice(Typ[Byte]))
|
||||||
//
|
sig.isVariadic = true
|
||||||
// sig := makeSig(S, S, NewSlice(Typ[Byte]))
|
check.recordBuiltinType(call.Fun, sig)
|
||||||
// sig.isVariadic = true
|
|
||||||
//
|
|
||||||
// once ssa has been adjusted
|
|
||||||
check.recordBuiltinType(call.Fun, makeSig(S, S, x.typ))
|
|
||||||
}
|
}
|
||||||
x.mode = value
|
x.mode = value
|
||||||
x.typ = S
|
x.typ = S
|
||||||
|
@ -420,7 +416,6 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
||||||
|
|
||||||
x.mode = novalue
|
x.mode = novalue
|
||||||
if check.Types != nil {
|
if check.Types != nil {
|
||||||
// TODO(gri) we need a global empty interface somewhere
|
|
||||||
check.recordBuiltinType(call.Fun, makeSig(nil, new(Interface)))
|
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:
|
case _Recover:
|
||||||
// recover() interface{}
|
// recover() interface{}
|
||||||
x.mode = value
|
x.mode = value
|
||||||
x.typ = new(Interface) // TODO(gri) we need a global empty interface somewhere
|
x.typ = new(Interface)
|
||||||
if check.Types != nil {
|
if check.Types != nil {
|
||||||
check.recordBuiltinType(call.Fun, makeSig(x.typ))
|
check.recordBuiltinType(call.Fun, makeSig(x.typ))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 []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, 0)`, `func([]byte, ...byte) []byte`},
|
||||||
{_Append, `var s []byte; _ = append(s, "foo"...)`, `func([]byte, string) []byte`},
|
// Note that ...uint8 (instead of ..byte) appears below because that is the type
|
||||||
{_Append, `type T []byte; var s T; _ = append(s, "foo"...)`, `func(p.T, string) p.T`},
|
// 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
|
||||||
{_Cap, `var s [10]int; _ = cap(&s)`, `invalid type`}, // constant
|
{_Cap, `var s [10]int; _ = cap(&s)`, `invalid type`}, // constant
|
||||||
|
|
Loading…
Reference in New Issue