mirror of https://github.com/golang/go.git
go/types: implement indexing of generic types
Change-Id: I88a488d9d279b1029dd8086ea1befaa7b5733df6
This commit is contained in:
parent
d2fce6bc64
commit
1a2a175a8e
|
|
@ -1361,6 +1361,43 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||
x.typ = typ.elem
|
||||
x.expr = e
|
||||
return expression
|
||||
|
||||
case *TypeParam:
|
||||
if types := typ.Interface().allTypes; len(types) > 0 {
|
||||
// A generic variable can be indexed if all types
|
||||
// in its type bound support indexing and have the
|
||||
// same element type.
|
||||
var elem Type
|
||||
for _, t := range types {
|
||||
var e Type
|
||||
switch t := t.(type) {
|
||||
case *Basic:
|
||||
if isString(t) {
|
||||
e = universeByte
|
||||
}
|
||||
case *Array:
|
||||
e = t.elem
|
||||
case *Pointer:
|
||||
if t, _ := t.base.Underlying().(*Array); t != nil {
|
||||
e = t.elem
|
||||
}
|
||||
case *Slice:
|
||||
e = t.elem
|
||||
case *Map:
|
||||
e = t.elem
|
||||
}
|
||||
if e == nil || elem != nil && e != elem {
|
||||
elem = nil
|
||||
break
|
||||
}
|
||||
elem = e
|
||||
}
|
||||
if elem != nil {
|
||||
valid = true
|
||||
x.mode = variable
|
||||
x.typ = elem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !valid {
|
||||
|
|
@ -1422,6 +1459,10 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||
case *Slice:
|
||||
valid = true
|
||||
// x.typ doesn't change
|
||||
|
||||
case *TypeParam:
|
||||
check.errorf(x.pos(), "generic slice expressions not yet implemented")
|
||||
goto Error
|
||||
}
|
||||
|
||||
if !valid {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,22 @@ func f3(type A, B, C)(A, struct{x B}, func(A, struct{x B}, *C)) int
|
|||
|
||||
var _ = f3(int, rune, bool)(1, struct{x rune}{}, nil)
|
||||
|
||||
// indexing
|
||||
|
||||
func _(type T) (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
||||
func _(type T interface{ type int }) (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
||||
func _(type T interface{ type string }) (x T, i int) { _ = x[i] }
|
||||
func _(type T interface{ type []int }) (x T, i int) { _ = x[i] }
|
||||
func _(type T interface{ type [10]int, *[20]int, map[string]int }) (x T, i int) { _ = x[i] }
|
||||
func _(type T interface{ type string, []byte }) (x T, i int) { _ = x[i] }
|
||||
func _(type T interface{ type []int, [1]rune }) (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
||||
func _(type T interface{ type string, []rune }) (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
||||
|
||||
// slicing
|
||||
// TODO(gri) implement this
|
||||
|
||||
func _(type T interface{ type string }) (x T, i, j, k int) { _ = x /* ERROR not yet implemented */ [i:j:k] }
|
||||
|
||||
// len/cap built-ins
|
||||
|
||||
func _(type T)(x T) { _ = len(x /* ERROR invalid argument */ ) }
|
||||
|
|
|
|||
Loading…
Reference in New Issue