Skip to content

Commit

Permalink
go/ssa/interp: support conversions to slices of named bytes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
timothy-king authored and gopherbot committed Jul 3, 2023
1 parent 14ec3c0 commit ad52c1c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
1 change: 1 addition & 0 deletions go/ssa/interp/interp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ var testdataTests = []string{
"width32.go",

"fixedbugs/issue52342.go",
"fixedbugs/issue55115.go",
}

func init() {
Expand Down
7 changes: 2 additions & 5 deletions go/ssa/interp/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -1211,8 +1211,7 @@ func conv(t_dst, t_src types.Type, x value) value {

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))
Expand All @@ -1234,7 +1233,6 @@ func conv(t_dst, t_src types.Type, x value) value {
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)
Expand All @@ -1246,8 +1244,7 @@ func conv(t_dst, t_src types.Type, x value) value {
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)
Expand Down
38 changes: 38 additions & 0 deletions go/ssa/interp/testdata/fixedbugs/issue55115.go
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit ad52c1c

Please sign in to comment.