//
// list = [ f { sep f } [sep] ] close .
//
-func (p *parser) list(sep, close token, f func() bool) Pos {
+func (p *parser) list(context string, sep, close token, f func() bool) Pos {
if debug && (sep != _Comma && sep != _Semi || close != _Rparen && close != _Rbrace && close != _Rbrack) {
panic("invalid sep or close argument for list")
}
done = f()
// sep is optional before close
if !p.got(sep) && p.tok != close {
- p.syntaxError(fmt.Sprintf("expecting %s or %s", tokstring(sep), tokstring(close)))
+ p.syntaxError(fmt.Sprintf("in %s; possibly missing %s or %s", context, tokstring(sep), tokstring(close)))
p.advance(_Rparen, _Rbrack, _Rbrace)
if p.tok != close {
// position could be better but we had an error so we don't care
g := new(Group)
p.clearPragma()
p.next() // must consume "(" after calling clearPragma!
- p.list(_Semi, _Rparen, func() bool {
+ p.list("grouped declaration", _Semi, _Rparen, func() bool {
if x := f(g); x != nil {
list = append(list, x)
}
p.xnest++
p.want(_Lbrace)
- x.Rbrace = p.list(_Comma, _Rbrace, func() bool {
+ x.Rbrace = p.list("composite literal", _Comma, _Rbrace, func() bool {
// value
e := p.bare_complitexpr()
if p.tok == _Colon {
p.want(_Struct)
p.want(_Lbrace)
- p.list(_Semi, _Rbrace, func() bool {
+ p.list("struct type", _Semi, _Rbrace, func() bool {
p.fieldDecl(typ)
return false
})
p.want(_Interface)
p.want(_Lbrace)
- p.list(_Semi, _Rbrace, func() bool {
+ p.list("interface type", _Semi, _Rbrace, func() bool {
switch p.tok {
case _Name:
f := p.methodDecl()
var named int // number of parameters that have an explicit name and type
var typed int // number of parameters that have an explicit type
- end := p.list(_Comma, close, func() bool {
+ end := p.list("parameter list", _Comma, close, func() bool {
var par *Field
if typ != nil {
if debug && name == nil {
}
p.xnest++
- p.list(_Comma, _Rparen, func() bool {
+ p.list("argument list", _Comma, _Rparen, func() bool {
list = append(list, p.expr())
hasDots = p.got(_DotDotDot)
return hasDots
--- /dev/null
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// test case from issue
+
+type _ interface{
+ m /* ERROR unexpected int in interface type; possibly missing semicolon or newline or } */ int
+}
+
+// other cases where the fix for this issue affects the error message
+
+const (
+ x int = 10 /* ERROR unexpected literal "foo" in grouped declaration; possibly missing semicolon or newline or \) */ "foo"
+)
+
+var _ = []int{1, 2, 3 /* ERROR unexpected int in composite literal; possibly missing comma or } */ int }
+
+type _ struct {
+ x y /* ERROR syntax error: unexpected comma in struct type; possibly missing semicolon or newline or } */ ,
+}
+
+func f(a, b c /* ERROR unexpected d in parameter list; possibly missing comma or \) */ d) {
+ f(a, b, c /* ERROR unexpected d in argument list; possibly missing comma or \) */ d)
+}