mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <gri@google.com> Reviewed-by: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Reviewed-by: Brett Howell <devbrett90@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
a0eb4548cf
commit
cdf64106f6
3 changed files with 39 additions and 14 deletions
|
|
@ -91,6 +91,17 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
|
|||
// to type []byte with a second argument of string type followed by ... .
|
||||
// This form appends the bytes of the string."
|
||||
|
||||
// In either case, the first argument must be a slice; in particular it
|
||||
// cannot be the predeclared nil value. Note that nil is not excluded by
|
||||
// the assignability requirement alone for the special case (go.dev/issue/76220).
|
||||
// spec: "If S is a type parameter, all types in its type set
|
||||
// must have the same underlying slice type []E."
|
||||
E, err := sliceElem(x)
|
||||
if err != nil {
|
||||
check.errorf(x, InvalidAppend, "invalid append: %s", err.format(check))
|
||||
return
|
||||
}
|
||||
|
||||
// Handle append(bytes, y...) special case, where
|
||||
// the type set of y is {string} or {string, []byte}.
|
||||
var sig *Signature
|
||||
|
|
@ -119,13 +130,6 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
|
|||
|
||||
// general case
|
||||
if sig == nil {
|
||||
// spec: "If S is a type parameter, all types in its type set
|
||||
// must have the same underlying slice type []E."
|
||||
E, err := sliceElem(x)
|
||||
if err != nil {
|
||||
check.errorf(x, InvalidAppend, "invalid append: %s", err.format(check))
|
||||
return
|
||||
}
|
||||
// check arguments by creating custom signature
|
||||
sig = makeSig(x.typ, x.typ, NewSlice(E)) // []E required for variadic signature
|
||||
sig.variadic = true
|
||||
|
|
|
|||
|
|
@ -94,6 +94,17 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
// to type []byte with a second argument of string type followed by ... .
|
||||
// This form appends the bytes of the string."
|
||||
|
||||
// In either case, the first argument must be a slice; in particular it
|
||||
// cannot be the predeclared nil value. Note that nil is not excluded by
|
||||
// the assignability requirement alone for the special case (go.dev/issue/76220).
|
||||
// spec: "If S is a type parameter, all types in its type set
|
||||
// must have the same underlying slice type []E."
|
||||
E, err := sliceElem(x)
|
||||
if err != nil {
|
||||
check.errorf(x, InvalidAppend, "invalid append: %s", err.format(check))
|
||||
return
|
||||
}
|
||||
|
||||
// Handle append(bytes, y...) special case, where
|
||||
// the type set of y is {string} or {string, []byte}.
|
||||
var sig *Signature
|
||||
|
|
@ -122,13 +133,6 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
|
||||
// general case
|
||||
if sig == nil {
|
||||
// spec: "If S is a type parameter, all types in its type set
|
||||
// must have the same underlying slice type []E."
|
||||
E, err := sliceElem(x)
|
||||
if err != nil {
|
||||
check.errorf(x, InvalidAppend, "invalid append: %s", err.format(check))
|
||||
return
|
||||
}
|
||||
// check arguments by creating custom signature
|
||||
sig = makeSig(x.typ, x.typ, NewSlice(E)) // []E required for variadic signature
|
||||
sig.variadic = true
|
||||
|
|
|
|||
17
src/internal/types/testdata/fixedbugs/issue76220.go
vendored
Normal file
17
src/internal/types/testdata/fixedbugs/issue76220.go
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2025 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
func _() {
|
||||
append(nil /* ERROR "argument must be a slice; have untyped nil" */, ""...)
|
||||
}
|
||||
|
||||
// test case from issue
|
||||
|
||||
func main() {
|
||||
s := "hello"
|
||||
msg := append(nil /* ERROR "argument must be a slice; have untyped nil" */, s...)
|
||||
print(msg)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue