go.tools/go/types: set array type even if length is invalid

This avoids some follow-up errors due to invalid
array declarations.

LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/57640043
This commit is contained in:
Robert Griesemer 2014-01-28 09:40:12 -08:00
parent ffc6416213
commit aea9f68811
2 changed files with 23 additions and 20 deletions

View File

@ -234,7 +234,7 @@ const (
_b1 = assert(iota + iota2 == 5)
_b2 = len([iota]int{}) // iota may appear in a type!
_b3 = assert(_b2 == 2)
_b4 = len(A /* ERROR "invalid composite literal" */ {})
_b4 = len(A{})
)
type A [iota /* ERROR "cannot use iota" */ ]int

View File

@ -245,30 +245,12 @@ func (check *checker) typInternal(e ast.Expr, def *Named, cycleOk bool) Type {
case *ast.ArrayType:
if e.Len != nil {
var x operand
check.expr(&x, e.Len)
if x.mode != constant {
if x.mode != invalid {
check.errorf(x.pos(), "array length %s must be constant", &x)
}
break
}
if !x.isInteger() {
check.errorf(x.pos(), "array length %s must be integer", &x)
break
}
n, ok := exact.Int64Val(x.val)
if !ok || n < 0 {
check.errorf(x.pos(), "invalid array length %s", &x)
break
}
typ := new(Array)
if def != nil {
def.underlying = typ
}
typ.len = n
typ.len = check.arrayLength(e.Len)
typ.elem = check.typ(e.Elt, nil, cycleOk)
return typ
@ -383,6 +365,27 @@ func (check *checker) typOrNil(e ast.Expr) Type {
return Typ[Invalid]
}
func (check *checker) arrayLength(e ast.Expr) int64 {
var x operand
check.expr(&x, e)
if x.mode != constant {
if x.mode != invalid {
check.errorf(x.pos(), "array length %s must be constant", &x)
}
return 0
}
if !x.isInteger() {
check.errorf(x.pos(), "array length %s must be integer", &x)
return 0
}
n, ok := exact.Int64Val(x.val)
if !ok || n < 0 {
check.errorf(x.pos(), "invalid array length %s", &x)
return 0
}
return n
}
func (check *checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, isVariadic bool) {
if list == nil {
return