diff options
author | Rob Findley <rfindley@google.com> | 2021-04-28 16:32:38 -0400 |
---|---|---|
committer | Robert Findley <rfindley@google.com> | 2021-04-29 13:24:00 +0000 |
commit | eb3fe28d7079692a1545887a2c609b325ec7f087 (patch) | |
tree | d0a7ed853dbefe733c251b86cf2ea662e6926b6f /src/go/types/index.go | |
parent | c8a92d454c74d89f172f6d534395a0553eff8f20 (diff) | |
download | go-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.go | 42 |
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. |