From aea9f6881139192ada389c3c7b1c93b48a217bb1 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 28 Jan 2014 09:40:12 -0800 Subject: [PATCH] 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 --- go/types/testdata/const0.src | 2 +- go/types/typexpr.go | 41 +++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/go/types/testdata/const0.src b/go/types/testdata/const0.src index 7dd58c02..1a0dd42d 100644 --- a/go/types/testdata/const0.src +++ b/go/types/testdata/const0.src @@ -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 diff --git a/go/types/typexpr.go b/go/types/typexpr.go index a861d4bd..f55842c1 100644 --- a/go/types/typexpr.go +++ b/go/types/typexpr.go @@ -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