if n.X.Op() == ir.OLITERAL {
return stringtoruneslit(n)
}
+
+ case ir.OBYTES2STR:
+ assert(t.IsSlice())
+ assert(t.Elem().Kind() == types.TUINT8)
+ if t.Elem() != types.ByteType && t.Elem() != types.Types[types.TUINT8] {
+ // If t is a slice of a user-defined byte type B (not uint8
+ // or byte), then add an extra CONVNOP from []B to []byte, so
+ // that the call to slicebytetostring() added in walk will
+ // typecheck correctly.
+ n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.ByteType), n.X)
+ n.X.SetTypecheck(1)
+ }
+
+ case ir.ORUNES2STR:
+ assert(t.IsSlice())
+ assert(t.Elem().Kind() == types.TINT32)
+ if t.Elem() != types.RuneType && t.Elem() != types.Types[types.TINT32] {
+ // If t is a slice of a user-defined rune type B (not uint32
+ // or rune), then add an extra CONVNOP from []B to []rune, so
+ // that the call to slicerunetostring() added in walk will
+ // typecheck correctly.
+ n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.RuneType), n.X)
+ n.X.SetTypecheck(1)
+ }
+
}
return n
}
if n.X.Op() == ir.OLITERAL {
return stringtoruneslit(n)
}
+
+ case ir.OBYTES2STR:
+ if t.Elem() != types.ByteType && t.Elem() != types.Types[types.TUINT8] {
+ // If t is a slice of a user-defined byte type B (not uint8
+ // or byte), then add an extra CONVNOP from []B to []byte, so
+ // that the call to slicebytetostring() added in walk will
+ // typecheck correctly.
+ n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.ByteType), n.X)
+ n.X.SetTypecheck(1)
+ }
+
+ case ir.ORUNES2STR:
+ if t.Elem() != types.RuneType && t.Elem() != types.Types[types.TINT32] {
+ // If t is a slice of a user-defined rune type B (not uint32
+ // or rune), then add an extra CONVNOP from []B to []rune, so
+ // that the call to slicerunetostring() added in walk will
+ // typecheck correctly.
+ n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.RuneType), n.X)
+ n.X.SetTypecheck(1)
+ }
+
}
return n
}
--- /dev/null
+// run
+
+// 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.
+
+// Test case where a slice of a user-defined byte type (not uint8 or byte) is
+// converted to a string. Same for slice of runes.
+
+package main
+
+type MyByte byte
+
+type MyRune rune
+
+func main() {
+ var y []MyByte
+ _ = string(y)
+
+ var z []MyRune
+ _ = string(z)
+}
--- /dev/null
+// 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.
+
+// Test case where a slice of a user-defined byte type (not uint8 or byte) is
+// converted to a string. Same for slice of runes.
+
+package main
+
+type MyByte byte
+
+type MyRune rune
+
+func f[T []MyByte](x T) string {
+ return string(x)
+}
+
+func g[T []MyRune](x T) string {
+ return string(x)
+}
+
+func main() {
+ var y []MyByte
+ _ = f(y)
+ _ = string(y)
+
+ var z []MyRune
+ _ = g(z)
+ _ = string(z)
+}