Skip to content

Commit c74be77

Browse files
committed
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 <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent be26ca9 commit c74be77

File tree

7 files changed

+76
-4
lines changed

7 files changed

+76
-4
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
101101
if x.mode == invalid {
102102
return
103103
}
104-
if allString(x.typ) {
104+
if t := structuralString(x.typ); t != nil && isString(t) {
105105
if check.Types != nil {
106106
sig := makeSig(S, S, x.typ)
107107
sig.variadic = true
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2022 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 _[S string | []byte](s S) {
8+
var buf []byte
9+
_ = append(buf, s...)
10+
}
11+
12+
func _[S ~string | ~[]byte](s S) {
13+
var buf []byte
14+
_ = append(buf, s...)
15+
}
16+
17+
// test case from issue
18+
19+
type byteseq interface {
20+
string | []byte
21+
}
22+
23+
// This should allow to eliminate the two functions above.
24+
func AppendByteString[source byteseq](buf []byte, s source) []byte {
25+
return append(buf, s[1:6]...)
26+
}

src/cmd/compile/internal/types2/testdata/manual.go2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2021 The Go Authors. All rights reserved.
1+
// Copyright 2022 The Go Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

src/go/types/builtins.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
102102
if x.mode == invalid {
103103
return
104104
}
105-
if allString(x.typ) {
105+
if t := structuralString(x.typ); t != nil && isString(t) {
106106
if check.Types != nil {
107107
sig := makeSig(S, S, x.typ)
108108
sig.variadic = true
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2022 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 _[S string | []byte](s S) {
8+
var buf []byte
9+
_ = append(buf, s...)
10+
}
11+
12+
func _[S ~string | ~[]byte](s S) {
13+
var buf []byte
14+
_ = append(buf, s...)
15+
}
16+
17+
// test case from issue
18+
19+
type byteseq interface {
20+
string | []byte
21+
}
22+
23+
// This should allow to eliminate the two functions above.
24+
func AppendByteString[source byteseq](buf []byte, s source) []byte {
25+
return append(buf, s[1:6]...)
26+
}

src/go/types/testdata/manual.go2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2021 The Go Authors. All rights reserved.
1+
// Copyright 2022 The Go Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

test/typeparam/issue376214.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// run -gcflags=-G=3
2+
3+
// Copyright 2022 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
func add[S ~string | ~[]byte](buf *[]byte, s S) {
10+
*buf = append(*buf, s...)
11+
}
12+
13+
func main() {
14+
var buf []byte
15+
add(&buf, "foo")
16+
add(&buf, []byte("bar"))
17+
if string(buf) != "foobar" {
18+
panic("got " + string(buf))
19+
}
20+
}

0 commit comments

Comments
 (0)