diff --git a/src/cmd/compile/internal/types2/literals.go b/src/cmd/compile/internal/types2/literals.go
index 43149ec9b9b4c7..fbb139be8f04c7 100644
--- a/src/cmd/compile/internal/types2/literals.go
+++ b/src/cmd/compile/internal/types2/literals.go
@@ -20,7 +20,7 @@ func (check *Checker) compositeLit(T *target, x *operand, e *syntax.CompositeLit
// composite literal type present - use it
// [...]T array types may only appear with composite literals.
// Check for them here so we don't have to handle ... in general.
- if atyp, _ := e.Type.(*syntax.ArrayType); atyp != nil && atyp.Len == nil {
+ if atyp, _ := e.Type.(*syntax.ArrayType); atyp != nil && isdddArray(atyp) {
// We have an "open" [...]T array type.
// Create a new ArrayType with unknown length (-1)
// and finish setting it up after analyzing the literal.
@@ -124,7 +124,7 @@ func (check *Checker) compositeLit(T *target, x *operand, e *syntax.CompositeLit
check.assignment(x, etyp, "struct literal")
}
if len(e.ElemList) < len(fields) {
- check.errorf(e.Rbrace, InvalidStructLit, "too few values in struct literal of type %s", base)
+ check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s", base)
// ok to continue
}
}
diff --git a/src/cmd/compile/internal/types2/util.go b/src/cmd/compile/internal/types2/util.go
index db0a3e70badb43..26c6d4eaea9452 100644
--- a/src/cmd/compile/internal/types2/util.go
+++ b/src/cmd/compile/internal/types2/util.go
@@ -36,6 +36,9 @@ func dddErrPos(call *syntax.CallExpr) *syntax.CallExpr {
return call
}
+// isdddArray reports whether atyp is of the form [...]E.
+func isdddArray(atyp *syntax.ArrayType) bool { return atyp.Len == nil }
+
// argErrPos returns the node (poser) for reporting an invalid argument count.
func argErrPos(call *syntax.CallExpr) *syntax.CallExpr { return call }
@@ -48,6 +51,9 @@ func startPos(n syntax.Node) syntax.Pos { return syntax.StartPos(n) }
// endPos returns the position of the first character immediately after node n.
func endPos(n syntax.Node) syntax.Pos { return syntax.EndPos(n) }
+// inNode is a dummy function returning pos.
+func inNode(_ syntax.Node, pos syntax.Pos) syntax.Pos { return pos }
+
// makeFromLiteral returns the constant value for the given literal string and kind.
func makeFromLiteral(lit string, kind syntax.LitKind) constant.Value {
return constant.MakeFromLiteral(lit, kind2tok[kind], 0)
diff --git a/src/go/types/literals.go b/src/go/types/literals.go
index f35df424752611..d2bd7b5d15c5a1 100644
--- a/src/go/types/literals.go
+++ b/src/go/types/literals.go
@@ -20,15 +20,13 @@ func (check *Checker) compositeLit(T *target, x *operand, e *ast.CompositeLit, h
// composite literal type present - use it
// [...]T array types may only appear with composite literals.
// Check for them here so we don't have to handle ... in general.
- if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && atyp.Len != nil {
- if ellip, _ := atyp.Len.(*ast.Ellipsis); ellip != nil && ellip.Elt == nil {
- // We have an "open" [...]T array type.
- // Create a new ArrayType with unknown length (-1)
- // and finish setting it up after analyzing the literal.
- typ = &Array{len: -1, elem: check.varType(atyp.Elt)}
- base = typ
- break
- }
+ if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && isdddArray(atyp) {
+ // We have an "open" [...]T array type.
+ // Create a new ArrayType with unknown length (-1)
+ // and finish setting it up after analyzing the literal.
+ typ = &Array{len: -1, elem: check.varType(atyp.Elt)}
+ base = typ
+ break
}
typ = check.typ(e.Type)
base = typ
diff --git a/src/go/types/util.go b/src/go/types/util.go
index 5d4ccc6f1ff15e..c01a4da479cc63 100644
--- a/src/go/types/util.go
+++ b/src/go/types/util.go
@@ -33,6 +33,16 @@ func hasDots(call *ast.CallExpr) bool { return call.Ellipsis.IsValid() }
// dddErrPos returns the positioner for reporting an invalid ... use in a call.
func dddErrPos(call *ast.CallExpr) positioner { return atPos(call.Ellipsis) }
+// isdddArray reports whether atyp is of the form [...]E.
+func isdddArray(atyp *ast.ArrayType) bool {
+ if atyp.Len != nil {
+ if ddd, _ := atyp.Len.(*ast.Ellipsis); ddd != nil && ddd.Elt == nil {
+ return true
+ }
+ }
+ return false
+}
+
// argErrPos returns positioner for reporting an invalid argument count.
func argErrPos(call *ast.CallExpr) positioner { return inNode(call, call.Rparen) }