Skip to content

Commit cdf6410

Browse files
Robert Griesemergopherbot
authored andcommitted
go/types, types2: first argument to append must never be be nil
The current implementation followed the spec faithfully for the special case for append. Per the spec: As a special case, append also accepts a first argument assignable to type []byte with a second argument of string type followed by ... . As it happens, nil is assignable to []byte, so append(nil, ""...) didn't get an error message but a subsequent assertion failed. This CL ensures that the first argument to append is never nil and always a slice. We should make the spec more precise (separate CL). Fixes #76220. Change-Id: I581d11827a75afbb257077814beea813d4fe2441 Reviewed-on: https://go-review.googlesource.com/c/go/+/718860 Auto-Submit: Robert Griesemer <[email protected]> Reviewed-by: Alan Donovan <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> Reviewed-by: Brett Howell <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent a0eb454 commit cdf6410

File tree

3 files changed

+39
-14
lines changed

3 files changed

+39
-14
lines changed

src/cmd/compile/internal/types2/builtins.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
9191
// to type []byte with a second argument of string type followed by ... .
9292
// This form appends the bytes of the string."
9393

94+
// In either case, the first argument must be a slice; in particular it
95+
// cannot be the predeclared nil value. Note that nil is not excluded by
96+
// the assignability requirement alone for the special case (go.dev/issue/76220).
97+
// spec: "If S is a type parameter, all types in its type set
98+
// must have the same underlying slice type []E."
99+
E, err := sliceElem(x)
100+
if err != nil {
101+
check.errorf(x, InvalidAppend, "invalid append: %s", err.format(check))
102+
return
103+
}
104+
94105
// Handle append(bytes, y...) special case, where
95106
// the type set of y is {string} or {string, []byte}.
96107
var sig *Signature
@@ -119,13 +130,6 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
119130

120131
// general case
121132
if sig == nil {
122-
// spec: "If S is a type parameter, all types in its type set
123-
// must have the same underlying slice type []E."
124-
E, err := sliceElem(x)
125-
if err != nil {
126-
check.errorf(x, InvalidAppend, "invalid append: %s", err.format(check))
127-
return
128-
}
129133
// check arguments by creating custom signature
130134
sig = makeSig(x.typ, x.typ, NewSlice(E)) // []E required for variadic signature
131135
sig.variadic = true

src/go/types/builtins.go

Lines changed: 11 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
func _() {
8+
append(nil /* ERROR "argument must be a slice; have untyped nil" */, ""...)
9+
}
10+
11+
// test case from issue
12+
13+
func main() {
14+
s := "hello"
15+
msg := append(nil /* ERROR "argument must be a slice; have untyped nil" */, s...)
16+
print(msg)
17+
}

0 commit comments

Comments
 (0)