go/ssa/interp: support conversions to slices of named bytes
Support for conversions from string to slices of named byte and rune
types and vice versa.
Fixes golang/go#55115
Change-Id: Ie0fb94385f1bc89789fe299cc0c39063db676c21
Reviewed-on: https://go-review.googlesource.com/c/tools/+/501301
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Tim King <taking@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Tim King <taking@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/go/ssa/interp/interp_test.go b/go/ssa/interp/interp_test.go
index 64ede78..b3edc99 100644
--- a/go/ssa/interp/interp_test.go
+++ b/go/ssa/interp/interp_test.go
@@ -129,6 +129,7 @@
"width32.go",
"fixedbugs/issue52342.go",
+ "fixedbugs/issue55115.go",
}
func init() {
diff --git a/go/ssa/interp/ops.go b/go/ssa/interp/ops.go
index dd309bf..65d6452 100644
--- a/go/ssa/interp/ops.go
+++ b/go/ssa/interp/ops.go
@@ -1211,8 +1211,7 @@
case *types.Slice:
// []byte or []rune -> string
- // TODO(adonovan): fix: type B byte; conv([]B -> string).
- switch ut_src.Elem().(*types.Basic).Kind() {
+ switch ut_src.Elem().Underlying().(*types.Basic).Kind() {
case types.Byte:
x := x.([]value)
b := make([]byte, 0, len(x))
@@ -1234,7 +1233,6 @@
x = widen(x)
// integer -> string?
- // TODO(adonovan): fix: test integer -> named alias of string.
if ut_src.Info()&types.IsInteger != 0 {
if ut_dst, ok := ut_dst.(*types.Basic); ok && ut_dst.Kind() == types.String {
return fmt.Sprintf("%c", x)
@@ -1246,8 +1244,7 @@
switch ut_dst := ut_dst.(type) {
case *types.Slice:
var res []value
- // TODO(adonovan): fix: test named alias of rune, byte.
- switch ut_dst.Elem().(*types.Basic).Kind() {
+ switch ut_dst.Elem().Underlying().(*types.Basic).Kind() {
case types.Rune:
for _, r := range []rune(s) {
res = append(res, r)
diff --git a/go/ssa/interp/testdata/fixedbugs/issue55115.go b/go/ssa/interp/testdata/fixedbugs/issue55115.go
new file mode 100644
index 0000000..0f856ae
--- /dev/null
+++ b/go/ssa/interp/testdata/fixedbugs/issue55115.go
@@ -0,0 +1,38 @@
+// Copyright 2023 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
+
+import "reflect"
+
+func main() {
+ type MyByte byte
+ type MyRune rune
+ type MyString string
+
+ a := []MyByte{'a', 'b', 'c'}
+ if s := string(a); s != "abc" {
+ panic(s)
+ }
+
+ b := []MyRune{'五', '五'}
+ if s := string(b); s != "五五" {
+ panic(s)
+ }
+
+ c := []MyByte{'l', 'o', 'r', 'e', 'm'}
+ if s := MyString(c); s != MyString("lorem") {
+ panic(s)
+ }
+
+ d := "lorem"
+ if a := []MyByte(d); !reflect.DeepEqual(a, []MyByte{'l', 'o', 'r', 'e', 'm'}) {
+ panic(a)
+ }
+
+ e := 42
+ if s := MyString(e); s != "*" {
+ panic(s)
+ }
+}