aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/typexpr.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/types2/typexpr.go')
-rw-r--r--src/cmd/compile/internal/types2/typexpr.go10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
index f3db3bbba93..5aacb94a605 100644
--- a/src/cmd/compile/internal/types2/typexpr.go
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -428,6 +428,14 @@ func (check *Checker) instantiatedType(x syntax.Expr, targsx []syntax.Expr, def
// and returns the constant length >= 0, or a value < 0
// to indicate an error (and thus an unknown length).
func (check *Checker) arrayLength(e syntax.Expr) int64 {
+ // If e is an undeclared identifier, the array declaration might be an
+ // attempt at a parameterized type declaration with missing constraint.
+ // Provide a better error message than just "undeclared name: X".
+ if name, _ := e.(*syntax.Name); name != nil && check.lookup(name.Value) == nil {
+ check.errorf(name, "undeclared name %s for array length", name.Value)
+ return -1
+ }
+
var x operand
check.expr(&x, e)
if x.mode != constant_ {
@@ -436,6 +444,7 @@ func (check *Checker) arrayLength(e syntax.Expr) int64 {
}
return -1
}
+
if isUntyped(x.typ) || isInteger(x.typ) {
if val := constant.ToInt(x.val); val.Kind() == constant.Int {
if representableConst(val, check, Typ[Int], nil) {
@@ -447,6 +456,7 @@ func (check *Checker) arrayLength(e syntax.Expr) int64 {
}
}
}
+
check.errorf(&x, "array length %s must be integer", &x)
return -1
}