@@ -140,6 +140,8 @@ func TestEvalBuiltin(t *testing.T) {
|
||||
{src: `string(append([]byte("hello "), "world"...))`, res: "hello world"},
|
||||
{src: `e := "world"; string(append([]byte("hello "), e...))`, res: "hello world"},
|
||||
{src: `b := []int{1}; b = append(1, 2, 3); b`, err: "1:54: first argument to append must be slice; have int"},
|
||||
{src: `a1 := []int{0,1,2}; append(a1)`, res: "[0 1 2]"},
|
||||
{src: `append(nil)`, err: "first argument to append must be slice; have nil"},
|
||||
{src: `g := len(a)`, res: "1"},
|
||||
{src: `g := cap(a)`, res: "1"},
|
||||
{src: `g := len("test")`, res: "4"},
|
||||
|
||||
@@ -2928,7 +2928,13 @@ func _append(n *node) {
|
||||
value := genValue(n.child[1])
|
||||
next := getExec(n.tnext)
|
||||
|
||||
if len(n.child) > 3 {
|
||||
switch l := len(n.child); {
|
||||
case l == 2:
|
||||
n.exec = func(f *frame) bltn {
|
||||
dest(f).Set(value(f))
|
||||
return next
|
||||
}
|
||||
case l > 3:
|
||||
args := n.child[2:]
|
||||
l := len(args)
|
||||
values := make([]func(*frame) reflect.Value, l)
|
||||
@@ -2957,7 +2963,7 @@ func _append(n *node) {
|
||||
dest(f).Set(reflect.Append(value(f), sl...))
|
||||
return next
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
var value0 func(*frame) reflect.Value
|
||||
switch elem := n.typ.elem(); {
|
||||
case isEmptyInterface(elem):
|
||||
|
||||
@@ -735,10 +735,13 @@ func (check typecheck) builtin(name string, n *node, child []*node, ellipsis boo
|
||||
case bltnAppend:
|
||||
typ := params[0].Type()
|
||||
t := typ.TypeOf()
|
||||
if t.Kind() != reflect.Slice {
|
||||
if t == nil || t.Kind() != reflect.Slice {
|
||||
return params[0].nod.cfgErrorf("first argument to append must be slice; have %s", typ.id())
|
||||
}
|
||||
|
||||
if nparams == 1 {
|
||||
return nil
|
||||
}
|
||||
// Special case append([]byte, "test"...) is allowed.
|
||||
t1 := params[1].Type()
|
||||
if nparams == 2 && ellipsis && t.Elem().Kind() == reflect.Uint8 && t1.TypeOf().Kind() == reflect.String {
|
||||
|
||||
Reference in New Issue
Block a user