aboutsummaryrefslogtreecommitdiff
path: root/src/go/types/typexpr.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/go/types/typexpr.go')
-rw-r--r--src/go/types/typexpr.go12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index af56297144..0143f53009 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -258,7 +258,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
check.errorf(&x, _NotAType, "%s is not a type", &x)
}
- case *ast.IndexExpr, *ast.MultiIndexExpr:
+ case *ast.IndexExpr, *ast.IndexListExpr:
ix := typeparams.UnpackIndexExpr(e)
if !check.allowVersion(check.pkg, 1, 18) {
check.softErrorf(inNode(e, ix.Lbrack), _Todo, "type instantiation requires go1.18 or later")
@@ -412,6 +412,14 @@ func (check *Checker) instantiatedType(x ast.Expr, targsx []ast.Expr, def *Named
// and returns the constant length >= 0, or a value < 0
// to indicate an error (and thus an unknown length).
func (check *Checker) arrayLength(e ast.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.(*ast.Ident); name != nil && check.lookup(name.Name) == nil {
+ check.errorf(name, _InvalidArrayLen, "undeclared name %s for array length", name.Name)
+ return -1
+ }
+
var x operand
check.expr(&x, e)
if x.mode != constant_ {
@@ -420,6 +428,7 @@ func (check *Checker) arrayLength(e ast.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) {
@@ -431,6 +440,7 @@ func (check *Checker) arrayLength(e ast.Expr) int64 {
}
}
}
+
check.errorf(&x, _InvalidArrayLen, "array length %s must be integer", &x)
return -1
}