cmd/compile: accept string|[]byte-constrained 2nd argument in append

Similarly to what we do for the built-in function `copy`,
where we allow a string as 2nd argument to append, also
permit a type parameter constrained by string|[]byte.

While at it, change date in the manual.go2 test files so
that we don't need to constantly correct it when copying
a test case from that file into a proper test file.

Fixes #50281.

Change-Id: I23fed66736aa07bb3c481fe97313e828425ac448
Reviewed-on: https://go-review.googlesource.com/c/go/+/376214
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2022-01-06 18:02:30 -08:00
parent be26ca972d
commit c74be77e63
7 changed files with 76 additions and 4 deletions

View file

@ -101,7 +101,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
if x.mode == invalid {
return
}
if allString(x.typ) {
if t := structuralString(x.typ); t != nil && isString(t) {
if check.Types != nil {
sig := makeSig(S, S, x.typ)
sig.variadic = true

View file

@ -0,0 +1,26 @@
// Copyright 2022 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 _[S string | []byte](s S) {
var buf []byte
_ = append(buf, s...)
}
func _[S ~string | ~[]byte](s S) {
var buf []byte
_ = append(buf, s...)
}
// test case from issue
type byteseq interface {
string | []byte
}
// This should allow to eliminate the two functions above.
func AppendByteString[source byteseq](buf []byte, s source) []byte {
return append(buf, s[1:6]...)
}

View file

@ -1,4 +1,4 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Copyright 2022 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.

View file

@ -102,7 +102,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
if x.mode == invalid {
return
}
if allString(x.typ) {
if t := structuralString(x.typ); t != nil && isString(t) {
if check.Types != nil {
sig := makeSig(S, S, x.typ)
sig.variadic = true

View file

@ -0,0 +1,26 @@
// Copyright 2022 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 _[S string | []byte](s S) {
var buf []byte
_ = append(buf, s...)
}
func _[S ~string | ~[]byte](s S) {
var buf []byte
_ = append(buf, s...)
}
// test case from issue
type byteseq interface {
string | []byte
}
// This should allow to eliminate the two functions above.
func AppendByteString[source byteseq](buf []byte, s source) []byte {
return append(buf, s[1:6]...)
}

View file

@ -1,4 +1,4 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Copyright 2022 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.

View file

@ -0,0 +1,20 @@
// run -gcflags=-G=3
// Copyright 2022 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 main
func add[S ~string | ~[]byte](buf *[]byte, s S) {
*buf = append(*buf, s...)
}
func main() {
var buf []byte
add(&buf, "foo")
add(&buf, []byte("bar"))
if string(buf) != "foobar" {
panic("got " + string(buf))
}
}