From: Keith Randall Date: Tue, 27 Jan 2026 19:06:18 +0000 (-0800) Subject: reflect: allow conversions between slices of named {byte,rune} and string X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a0796d8af67e147f54e06952272745aa3410c291;p=gostls13.git reflect: allow conversions between slices of named {byte,rune} and string So the reflect behavior matches that of the language. These conversions are allowed: []myByte <-> string []myRune <-> string []myByte <-> myString []myRune <-> myString And even if the left-hand-side is named, e.g. myBytes([]myByte) <-> string Fixes #53523 Change-Id: I6562e72bc233a45dc7b02f75f68020831ad399ea Reviewed-on: https://go-review.googlesource.com/c/go/+/739680 Auto-Submit: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Robert Griesemer LUCI-TryBot-Result: Go LUCI --- diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 54a80e98c7..c15b5882ed 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -4177,6 +4177,9 @@ type MyBytesArray [4]byte type MyRunes []int32 type MyFunc func() type MyByte byte +type MyRune rune +type MyBytes2 []MyByte +type MyRunes2 []MyRune type IntChan chan int type IntChanRecv <-chan int @@ -4480,6 +4483,38 @@ var convertTests = []struct { {V(MyString("runes♝")), V(MyRunes("runes♝"))}, {V(MyRunes("runes♕")), V(MyString("runes♕"))}, + // []namedByte + {V(string("namedByte1")), V([]MyByte("namedByte1"))}, + {V(MyString("namedByte2")), V([]MyByte("namedByte2"))}, + {V([]MyByte("namedByte3")), V(string("namedByte3"))}, + {V([]MyByte("namedByte4")), V(MyString("namedByte4"))}, + + // []namedRune + {V(string("namedRune1")), V([]MyRune("namedRune1"))}, + {V(MyString("namedRune2")), V([]MyRune("namedRune2"))}, + {V([]MyRune("namedRune3")), V(string("namedRune3"))}, + {V([]MyRune("namedRune4")), V(MyString("namedRune4"))}, + + // named []namedByte + {V(string("namedByte5")), V(MyBytes2("namedByte5"))}, + {V(MyString("namedByte6")), V(MyBytes2("namedByte6"))}, + {V(MyBytes2("namedByte7")), V(string("namedByte7"))}, + {V(MyBytes2("namedByte8")), V(MyString("namedByte8"))}, + + // named []namedRune + {V(string("namedRune5")), V(MyRunes2("namedRune5"))}, + {V(MyString("namedRune6")), V(MyRunes2("namedRune6"))}, + {V(MyRunes2("namedRune7")), V(string("namedRune7"))}, + {V(MyRunes2("namedRune8")), V(MyString("namedRune8"))}, + + // random ok conversions of the above types + {V(MyBytes2("")), V([0]MyByte{})}, + {V(MyBytes2("AA")), V([2]MyByte{65, 65})}, + {V(MyBytes2("")), V([]MyByte{})}, + {V([]MyByte{}), V(MyBytes2(""))}, + {V([]MyRune("namedRuneA")), V(MyRunes2("namedRuneA"))}, + {V(MyRunes2("namedRuneB")), V([]MyRune("namedRuneB"))}, + // slice to array {V([]byte(nil)), V([0]byte{})}, {V([]byte{}), V([0]byte{})}, diff --git a/src/reflect/value.go b/src/reflect/value.go index 8c8acbaa9a..6fba1e751f 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -3404,7 +3404,7 @@ func convertOp(dst, src *abi.Type) func(Value, Type) Value { } case String: - if dst.Kind() == abi.Slice && pkgPathFor(dst.Elem()) == "" { + if dst.Kind() == abi.Slice { switch Kind(dst.Elem().Kind()) { case Uint8: return cvtStringBytes @@ -3414,7 +3414,7 @@ func convertOp(dst, src *abi.Type) func(Value, Type) Value { } case Slice: - if dst.Kind() == abi.String && pkgPathFor(src.Elem()) == "" { + if dst.Kind() == abi.String { switch Kind(src.Elem().Kind()) { case Uint8: return cvtBytesString