default:
if typeparams.IsListExpr(e) {
- check.errorf(e, _Todo, "invalid multi-index expression")
+ // catch-all for unexpected expression lists
+ check.errorf(e, _Todo, "unexpected list of expressions")
} else {
panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
}
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
// 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
return
}
- if e.Index == nil {
- check.invalidAST(e, "missing index for %s", x)
+ index := check.singleIndex(e)
+ if index == nil {
x.mode = invalid
return
}
x.typ = Typ[Invalid]
}
- check.index(e.Index, length)
+ check.index(index, length)
return false
}
}
}
+// 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.
type map[int]int, []int
}
-func _[T I]() {
+func _[T I](i, j int) {
var m map[int]int
- _ = m[1 /* ERROR "multi-index expression" */, 2 /* ERROR "expected type" */ ]
+ _ = m[i, j /* ERROR "more than one index" */ ]
var a [3]int
- _ = a[1 /* ERROR "multi-index expression" */, 2 /* ERROR "expected type" */ ]
+ _ = a[i, j /* ERROR "more than one index" */ ]
var s []int
- _ = s[1 /* ERROR "multi-index expression" */, 2 /* ERROR "expected type" */ ]
+ _ = s[i, j /* ERROR "more than one index" */ ]
var t T
// TODO(rFindley) Fix the duplicate error below.
- _ = t[1 /* ERROR "multi-index expression" */ /* ERROR "multi-index expression" */, 2 /* ERROR "expected type" */ ]
+ _ = t[i, j /* ERROR "more than one index" */ /* ERROR "more than one index" */ ]
}