mirror of
https://github.com/golang/go
synced 2024-11-17 20:04:47 -07:00
go/types: slice exprs to accept type sets with single underlying types
This is a port of CL 357779 to go/types. A test error message was repositioned on the sliced operand. Change-Id: Ie775c128f70d9cb08a2eba54b8bc082134ec3200 Reviewed-on: https://go-review.googlesource.com/c/go/+/359876 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
02bd226b8a
commit
71e6ab8f95
@ -207,9 +207,14 @@ func (check *Checker) sliceExpr(x *operand, e *ast.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, _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
|
||||
@ -221,26 +226,26 @@ func (check *Checker) sliceExpr(x *operand, e *ast.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.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:
|
||||
|
5
src/go/types/testdata/check/typeparams.go2
vendored
5
src/go/types/testdata/check/typeparams.go2
vendored
@ -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 */ ) }
|
||||
|
Loading…
Reference in New Issue
Block a user