]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: slice exprs to accept type sets with single underlying...
authorRobert Griesemer <gri@golang.org>
Thu, 21 Oct 2021 23:17:07 +0000 (16:17 -0700)
committerRobert Griesemer <gri@golang.org>
Sat, 23 Oct 2021 16:18:15 +0000 (16:18 +0000)
Change-Id: Ib9bd08ab6153129aaf8b77b41fc6ea302d0c1589
Reviewed-on: https://go-review.googlesource.com/c/go/+/357779
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/index.go
src/cmd/compile/internal/types2/testdata/check/typeparams.go2

index 47a5e50f6275bfec3eacf91fbfe82adce0cae117..62f49b95dabdd67e29610dffddd0feb7d2b36020 100644 (file)
@@ -207,9 +207,14 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
 
        valid := false
        length := int64(-1) // valid if >= 0
-       switch typ := optype(x.typ).(type) {
+       switch u := singleUnder(x.typ).(type) {
+       case nil:
+               check.errorf(x, invalidOp+"cannot slice %s: type set has no single underlying type", x)
+               x.mode = invalid
+               return
+
        case *Basic:
-               if isString(typ) {
+               if isString(u) {
                        if e.Full {
                                check.error(x, invalidOp+"3-index slice of string")
                                x.mode = invalid
@@ -221,26 +226,26 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
                        }
                        // spec: "For untyped string operands the result
                        // is a non-constant value of type string."
-                       if typ.kind == UntypedString {
+                       if u.kind == UntypedString {
                                x.typ = Typ[String]
                        }
                }
 
        case *Array:
                valid = true
-               length = typ.len
+               length = u.len
                if x.mode != variable {
                        check.errorf(x, invalidOp+"%s (slice of unaddressable value)", x)
                        x.mode = invalid
                        return
                }
-               x.typ = &Slice{elem: typ.elem}
+               x.typ = &Slice{elem: u.elem}
 
        case *Pointer:
-               if typ := asArray(typ.base); typ != nil {
+               if u := asArray(u.base); u != nil {
                        valid = true
-                       length = typ.len
-                       x.typ = &Slice{elem: typ.elem}
+                       length = u.len
+                       x.typ = &Slice{elem: u.elem}
                }
 
        case *Slice:
index d1f07a20d4f2d89aaa965ee7b0b78dfde724cd87..1200a6e8741c0fe4874f1a23180c42dde9d5b2ad 100644 (file)
@@ -123,6 +123,11 @@ func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j:k] }
 func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j] }
 func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x /* ERROR 3-index slice of string */ [i:j:k] }
 
+type myByte1 []byte
+type myByte2 []byte
+func _[T interface{ []byte | myByte1 | myByte2 }] (x T, i, j, k int) { var _ T = x[i:j:k] }
+func _[T interface{ []byte | myByte1 | []int }] (x T, i, j, k int) { var _ T = x[ /* ERROR no single underlying type */ i:j:k] }
+
 // len/cap built-ins
 
 func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }