summaryrefslogtreecommitdiff
path: root/src/go/types/index.go
diff options
context:
space:
mode:
authorRob Findley <rfindley@google.com>2021-04-28 16:32:38 -0400
committerRobert Findley <rfindley@google.com>2021-04-29 13:24:00 +0000
commiteb3fe28d7079692a1545887a2c609b325ec7f087 (patch)
treed0a7ed853dbefe733c251b86cf2ea662e6926b6f /src/go/types/index.go
parentc8a92d454c74d89f172f6d534395a0553eff8f20 (diff)
downloadgo-git-eb3fe28d7079692a1545887a2c609b325ec7f087.tar.gz
go/types: improve error messages for unexpected ListExprs
This CL is a mix of CL 312149 and CL 314409, adding the Checker.singleIndex method to provide better error messages when an unexpected ListExpr is encountered. Change-Id: I45d6de9b4dfc299dc2d356ca14d05c9191de818d Reviewed-on: https://go-review.googlesource.com/c/go/+/314869 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/go/types/index.go')
-rw-r--r--src/go/types/index.go42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/go/types/index.go b/src/go/types/index.go
index f51c3f6acf..2ba3475f89 100644
--- a/src/go/types/index.go
+++ b/src/go/types/index.go
@@ -77,8 +77,13 @@ func (check *Checker) indexExpr(x *operand, e *ast.IndexExpr) (isFuncInst bool)
x.typ = typ.elem
case *Map:
+ index := check.singleIndex(e)
+ if index == nil {
+ x.mode = invalid
+ return
+ }
var key operand
- check.expr(&key, e.Index)
+ check.expr(&key, index)
check.assignment(&key, typ.key, "map index")
// ok to continue even if indexing failed - map element type is known
x.mode = mapindex
@@ -132,8 +137,13 @@ func (check *Checker) indexExpr(x *operand, e *ast.IndexExpr) (isFuncInst bool)
// If there are maps, the index expression must be assignable
// to the map key type (as for simple map index expressions).
if nmaps > 0 {
+ index := check.singleIndex(e)
+ if index == nil {
+ x.mode = invalid
+ return
+ }
var key operand
- check.expr(&key, e.Index)
+ check.expr(&key, index)
check.assignment(&key, tkey, "map index")
// ok to continue even if indexing failed - map element type is known
@@ -170,8 +180,8 @@ func (check *Checker) indexExpr(x *operand, e *ast.IndexExpr) (isFuncInst bool)
return
}
- if e.Index == nil {
- check.invalidAST(e, "missing index for %s", x)
+ index := check.singleIndex(e)
+ if index == nil {
x.mode = invalid
return
}
@@ -183,7 +193,7 @@ func (check *Checker) indexExpr(x *operand, e *ast.IndexExpr) (isFuncInst bool)
x.typ = Typ[Invalid]
}
- check.index(e.Index, length)
+ check.index(index, length)
return false
}
@@ -298,6 +308,28 @@ L:
}
}
+// singleIndex returns the (single) index from the index expression e.
+// If the index is missing, or if there are multiple indices, an error
+// is reported and the result is nil.
+func (check *Checker) singleIndex(e *ast.IndexExpr) ast.Expr {
+ index := e.Index
+ if index == nil {
+ check.invalidAST(e, "missing index for %s", e)
+ return nil
+ }
+
+ indexes := typeparams.UnpackExpr(index)
+ if len(indexes) == 0 {
+ check.invalidAST(index, "index expression %v with 0 indices", index)
+ return nil
+ }
+ if len(indexes) > 1 {
+ // TODO(rFindley) should this get a distinct error code?
+ check.invalidOp(indexes[1], _InvalidIndex, "more than one index")
+ }
+ return indexes[0]
+}
+
// index checks an index expression for validity.
// If max >= 0, it is the upper bound for index.
// If the result typ is != Typ[Invalid], index is valid and typ is its (possibly named) integer type.