mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
cmd/compile/internal/parser: improved a couple of error messages
The new syntax tree introduced with 1.8 represents send statements (ch <- x) as statements; the old syntax tree represented them as expressions (and parsed them as such) but complained if they were used in expression context. As a consequence, some of the errors that in the past were of the form "ch <- x used as value" now look like "unexpected <- ..." because a "<-" is not valid according to Go syntax in those situations. Accept the new error message. Also: Fine-tune handling of misformed for loop headers. Also: Minor cleanups/better comments. Fixes #17590. Change-Id: Ia541dea1f2f015c1b21f5b3ae44aacdec60a8aba Reviewed-on: https://go-review.googlesource.com/37386 Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
2fa09a20e5
commit
f8ae30c4a2
3 changed files with 16 additions and 21 deletions
|
@ -663,7 +663,7 @@ func (p *parser) operand(keep_parens bool) Expr {
|
|||
pos := p.pos()
|
||||
p.next()
|
||||
p.xnest++
|
||||
x := p.expr() // expr_or_type
|
||||
x := p.expr()
|
||||
p.xnest--
|
||||
p.want(_Rparen)
|
||||
|
||||
|
@ -719,12 +719,6 @@ func (p *parser) operand(keep_parens bool) Expr {
|
|||
case _Lbrack, _Chan, _Map, _Struct, _Interface:
|
||||
return p.type_() // othertype
|
||||
|
||||
case _Lbrace:
|
||||
// common case: p.header is missing simpleStmt before { in if, for, switch
|
||||
p.syntax_error("missing operand")
|
||||
// '{' will be consumed in pexpr - no need to consume it here
|
||||
return nil
|
||||
|
||||
default:
|
||||
p.syntax_error("expecting expression")
|
||||
p.advance()
|
||||
|
@ -850,12 +844,12 @@ loop:
|
|||
// operand may have returned a parenthesized complit
|
||||
// type; accept it but complain if we have a complit
|
||||
t := unparen(x)
|
||||
// determine if '{' belongs to a complit or a compound_stmt
|
||||
// determine if '{' belongs to a composite literal or a block statement
|
||||
complit_ok := false
|
||||
switch t.(type) {
|
||||
case *Name, *SelectorExpr:
|
||||
if p.xnest >= 0 {
|
||||
// x is considered a comptype
|
||||
// x is considered a composite literal type
|
||||
complit_ok = true
|
||||
}
|
||||
case *ArrayType, *SliceType, *StructType, *MapType:
|
||||
|
@ -1692,6 +1686,7 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS
|
|||
}
|
||||
return
|
||||
}
|
||||
// p.tok != _Lbrace
|
||||
|
||||
outer := p.xnest
|
||||
p.xnest = -1
|
||||
|
@ -1712,7 +1707,7 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS
|
|||
var condStmt SimpleStmt
|
||||
var semi struct {
|
||||
pos src.Pos
|
||||
lit string
|
||||
lit string // valid if pos.IsKnown()
|
||||
}
|
||||
if p.tok == _Semi {
|
||||
semi.pos = p.pos()
|
||||
|
@ -1720,6 +1715,10 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS
|
|||
p.next()
|
||||
if keyword == _For {
|
||||
if p.tok != _Semi {
|
||||
if p.tok == _Lbrace {
|
||||
p.syntax_error("expecting for loop condition")
|
||||
goto done
|
||||
}
|
||||
condStmt = p.simpleStmt(nil, false)
|
||||
}
|
||||
p.want(_Semi)
|
||||
|
@ -1734,10 +1733,11 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS
|
|||
init = nil
|
||||
}
|
||||
|
||||
done:
|
||||
// unpack condStmt
|
||||
switch s := condStmt.(type) {
|
||||
case nil:
|
||||
if keyword == _If {
|
||||
if keyword == _If && semi.pos.IsKnown() {
|
||||
if semi.lit != "semicolon" {
|
||||
p.syntax_error_at(semi.pos, fmt.Sprintf("unexpected %s, expecting { after if clause", semi.lit))
|
||||
} else {
|
||||
|
@ -2037,7 +2037,7 @@ func (p *parser) call(fun Expr) *CallExpr {
|
|||
p.xnest++
|
||||
|
||||
for p.tok != _EOF && p.tok != _Rparen {
|
||||
c.ArgList = append(c.ArgList, p.expr()) // expr_or_type
|
||||
c.ArgList = append(c.ArgList, p.expr())
|
||||
c.HasDots = p.got(_DotDotDot)
|
||||
if !p.ocomma(_Rparen) || c.HasDots {
|
||||
break
|
||||
|
|
|
@ -10,8 +10,8 @@ var c chan int
|
|||
var v int
|
||||
|
||||
func main() {
|
||||
if c <- v { // ERROR "used as value|missing condition|invalid condition"
|
||||
if c <- v { // ERROR "used as value"
|
||||
}
|
||||
}
|
||||
|
||||
var _ = c <- v // ERROR "used as value|unexpected <-"
|
||||
var _ = c <- v // ERROR "unexpected <-"
|
||||
|
|
|
@ -4,14 +4,9 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// TODO(mdempsky): Update error expectations for new parser.
|
||||
// The new parser emits an extra "missing { after for clause" error.
|
||||
// The old parser is supposed to emit this too, but it panics first
|
||||
// due to a nil pointer dereference.
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
for x // GCCGO_ERROR "undefined"
|
||||
{ // ERROR "expecting .*{.* after for clause|missing operand"
|
||||
z // ERROR "undefined|expecting { after for clause"
|
||||
{ // ERROR "unexpected {, expecting for loop condition"
|
||||
z
|
||||
|
|
Loading…
Reference in a new issue