mirror of
https://github.com/golang/go
synced 2024-11-24 14:30:17 -07:00
cmd/compile/internal/types2: slice exprs to accept type sets with single underlying types
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>
This commit is contained in:
parent
c526cf8c1e
commit
12e4404a0a
@ -207,9 +207,14 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
|
|||||||
|
|
||||||
valid := false
|
valid := false
|
||||||
length := int64(-1) // valid if >= 0
|
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:
|
case *Basic:
|
||||||
if isString(typ) {
|
if isString(u) {
|
||||||
if e.Full {
|
if e.Full {
|
||||||
check.error(x, invalidOp+"3-index slice of string")
|
check.error(x, invalidOp+"3-index slice of string")
|
||||||
x.mode = invalid
|
x.mode = invalid
|
||||||
@ -221,26 +226,26 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
|
|||||||
}
|
}
|
||||||
// spec: "For untyped string operands the result
|
// spec: "For untyped string operands the result
|
||||||
// is a non-constant value of type string."
|
// is a non-constant value of type string."
|
||||||
if typ.kind == UntypedString {
|
if u.kind == UntypedString {
|
||||||
x.typ = Typ[String]
|
x.typ = Typ[String]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case *Array:
|
case *Array:
|
||||||
valid = true
|
valid = true
|
||||||
length = typ.len
|
length = u.len
|
||||||
if x.mode != variable {
|
if x.mode != variable {
|
||||||
check.errorf(x, invalidOp+"%s (slice of unaddressable value)", x)
|
check.errorf(x, invalidOp+"%s (slice of unaddressable value)", x)
|
||||||
x.mode = invalid
|
x.mode = invalid
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
x.typ = &Slice{elem: typ.elem}
|
x.typ = &Slice{elem: u.elem}
|
||||||
|
|
||||||
case *Pointer:
|
case *Pointer:
|
||||||
if typ := asArray(typ.base); typ != nil {
|
if u := asArray(u.base); u != nil {
|
||||||
valid = true
|
valid = true
|
||||||
length = typ.len
|
length = u.len
|
||||||
x.typ = &Slice{elem: typ.elem}
|
x.typ = &Slice{elem: u.elem}
|
||||||
}
|
}
|
||||||
|
|
||||||
case *Slice:
|
case *Slice:
|
||||||
|
@ -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[i:j] }
|
||||||
func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x /* ERROR 3-index slice of string */ [i:j:k] }
|
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
|
// len/cap built-ins
|
||||||
|
|
||||||
func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
|
func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
|
||||||
|
Loading…
Reference in New Issue
Block a user