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, _NonSliceableOperand, "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.Slice3 {
check.invalidOp(x, _InvalidSliceExpr, "3-index slice of string")
x.mode = invalid
}
// 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.invalidOp(x, _NonSliceableOperand, "cannot slice %s (value not addressable)", 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:
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 */ ) }