mirror of https://github.com/golang/go.git
go/types: implement len/cap for arguments of type paramater type
Change-Id: Ieeaa41573e5ec10df46ab25ec0a3563e3ae5b32b
This commit is contained in:
parent
c49fde5b11
commit
d2fce6bc64
|
|
@ -23,6 +23,8 @@ KNOWN ISSUES
|
|||
----------------------------------------------------------------------------------------------------
|
||||
OPEN QUESTIONS
|
||||
|
||||
- for len/cap(x) where x is of type parameter type and the bound contains arrays only, should the
|
||||
result be a constant? (right now it is not)
|
||||
- confirm that it's ok to use inference in missingMethod to compare parameterized methods
|
||||
- now that we allow parenthesized embedded interfaces, should we allow parenthesized embedded fields?
|
||||
(probably yes, for symmetry and consistency).
|
||||
|
|
|
|||
|
|
@ -174,6 +174,31 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
if id == _Len {
|
||||
mode = value
|
||||
}
|
||||
|
||||
case *TypeParam:
|
||||
if types := t.Interface().allTypes; len(types) > 0 {
|
||||
mode = value // assume we're ok
|
||||
L:
|
||||
for _, t := range types {
|
||||
switch t.(type) {
|
||||
case *Basic:
|
||||
if !isString(t) || id != _Len {
|
||||
mode = invalid
|
||||
break L
|
||||
}
|
||||
case *Array, *Slice, *Chan:
|
||||
// ok
|
||||
case *Map:
|
||||
if id != _Len {
|
||||
mode = invalid
|
||||
break L
|
||||
}
|
||||
default:
|
||||
mode = invalid
|
||||
break L
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if mode == invalid && typ != Typ[Invalid] {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,28 @@ 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)
|
||||
|
||||
// len/cap built-ins
|
||||
|
||||
func _(type T)(x T) { _ = len(x /* ERROR invalid argument */ ) }
|
||||
func _(type T interface{ type int })(x T) { _ = len(x /* ERROR invalid argument */ ) }
|
||||
func _(type T interface{ type string, []byte, int })(x T) { _ = len(x /* ERROR invalid argument */ ) }
|
||||
func _(type T interface{ type string })(x T) { _ = len(x) }
|
||||
func _(type T interface{ type [10]int })(x T) { _ = len(x) }
|
||||
func _(type T interface{ type []byte })(x T) { _ = len(x) }
|
||||
func _(type T interface{ type map[int]int })(x T) { _ = len(x) }
|
||||
func _(type T interface{ type chan int })(x T) { _ = len(x) }
|
||||
func _(type T interface{ type string, []byte, chan int })(x T) { _ = len(x) }
|
||||
|
||||
func _(type T)(x T) { _ = cap(x /* ERROR invalid argument */ ) }
|
||||
func _(type T interface{ type int })(x T) { _ = cap(x /* ERROR invalid argument */ ) }
|
||||
func _(type T interface{ type string, []byte, int })(x T) { _ = cap(x /* ERROR invalid argument */ ) }
|
||||
func _(type T interface{ type string })(x T) { _ = cap(x /* ERROR invalid argument */ ) }
|
||||
func _(type T interface{ type [10]int })(x T) { _ = cap(x) }
|
||||
func _(type T interface{ type []byte })(x T) { _ = cap(x) }
|
||||
func _(type T interface{ type map[int]int })(x T) { _ = cap(x /* ERROR invalid argument */ ) }
|
||||
func _(type T interface{ type chan int })(x T) { _ = cap(x) }
|
||||
func _(type T interface{ type []byte, chan int })(x T) { _ = cap(x) }
|
||||
|
||||
// type inference checks
|
||||
|
||||
var _ = new() /* ERROR cannot infer T */
|
||||
|
|
|
|||
Loading…
Reference in New Issue