mirror of
https://github.com/golang/go
synced 2024-11-23 07:20:06 -07:00
go/parser: better error message if = is seen instead of ==
Fixes #4519. R=rsc CC=golang-dev https://golang.org/cl/7733044
This commit is contained in:
parent
a25c403b3a
commit
916f4cfa64
@ -48,7 +48,8 @@ type parser struct {
|
||||
syncCnt int // number of calls to syncXXX without progress
|
||||
|
||||
// Non-syntactic parser control
|
||||
exprLev int // < 0: in control clause, >= 0: in expression
|
||||
exprLev int // < 0: in control clause, >= 0: in expression
|
||||
inRhs bool // if set, the parser is parsing a rhs expression
|
||||
|
||||
// Ordinary identifier scopes
|
||||
pkgScope *ast.Scope // pkgScope.Outer == nil
|
||||
@ -539,6 +540,8 @@ func (p *parser) parseExprList(lhs bool) (list []ast.Expr) {
|
||||
}
|
||||
|
||||
func (p *parser) parseLhsList() []ast.Expr {
|
||||
old := p.inRhs
|
||||
p.inRhs = false
|
||||
list := p.parseExprList(true)
|
||||
switch p.tok {
|
||||
case token.DEFINE:
|
||||
@ -560,11 +563,16 @@ func (p *parser) parseLhsList() []ast.Expr {
|
||||
p.resolve(x)
|
||||
}
|
||||
}
|
||||
p.inRhs = old
|
||||
return list
|
||||
}
|
||||
|
||||
func (p *parser) parseRhsList() []ast.Expr {
|
||||
return p.parseExprList(false)
|
||||
old := p.inRhs
|
||||
p.inRhs = true
|
||||
list := p.parseExprList(false)
|
||||
p.inRhs = old
|
||||
return list
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1505,6 +1513,14 @@ func (p *parser) parseUnaryExpr(lhs bool) ast.Expr {
|
||||
return p.parsePrimaryExpr(lhs)
|
||||
}
|
||||
|
||||
func (p *parser) tokPrec() (token.Token, int) {
|
||||
tok := p.tok
|
||||
if p.inRhs && tok == token.ASSIGN {
|
||||
tok = token.EQL
|
||||
}
|
||||
return tok, tok.Precedence()
|
||||
}
|
||||
|
||||
// If lhs is set and the result is an identifier, it is not resolved.
|
||||
func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr {
|
||||
if p.trace {
|
||||
@ -1512,10 +1528,13 @@ func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr {
|
||||
}
|
||||
|
||||
x := p.parseUnaryExpr(lhs)
|
||||
for prec := p.tok.Precedence(); prec >= prec1; prec-- {
|
||||
for p.tok.Precedence() == prec {
|
||||
pos, op := p.pos, p.tok
|
||||
p.next()
|
||||
for _, prec := p.tokPrec(); prec >= prec1; prec-- {
|
||||
for {
|
||||
op, oprec := p.tokPrec()
|
||||
if oprec != prec {
|
||||
break
|
||||
}
|
||||
pos := p.expect(op)
|
||||
if lhs {
|
||||
p.resolve(x)
|
||||
lhs = false
|
||||
@ -1541,11 +1560,19 @@ func (p *parser) parseExpr(lhs bool) ast.Expr {
|
||||
}
|
||||
|
||||
func (p *parser) parseRhs() ast.Expr {
|
||||
return p.checkExpr(p.parseExpr(false))
|
||||
old := p.inRhs
|
||||
p.inRhs = true
|
||||
x := p.checkExpr(p.parseExpr(false))
|
||||
p.inRhs = old
|
||||
return x
|
||||
}
|
||||
|
||||
func (p *parser) parseRhsOrType() ast.Expr {
|
||||
return p.checkExprOrType(p.parseExpr(false))
|
||||
old := p.inRhs
|
||||
p.inRhs = true
|
||||
x := p.checkExprOrType(p.parseExpr(false))
|
||||
p.inRhs = old
|
||||
return x
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -71,6 +71,9 @@ var invalids = []string{
|
||||
`package p; func f() { _ = (<-<- /* ERROR "expected 'chan'" */ chan int)(nil) };`,
|
||||
`package p; func f() { _ = (<-chan<-chan<-chan<-chan<-chan<- /* ERROR "expected channel type" */ int)(nil) };`,
|
||||
`package p; func f() { var t []int; t /* ERROR "expected identifier on left side of :=" */ [0] := 0 };`,
|
||||
`package p; func f() { if x := g(); x = /* ERROR "expected '=='" */ 0 {}};`,
|
||||
`package p; func f() { _ = x = /* ERROR "expected '=='" */ 0 {}};`,
|
||||
`package p; func f() { _ = 1 == func()int { var x bool; x = x = /* ERROR "expected '=='" */ true; return x }() };`,
|
||||
}
|
||||
|
||||
func TestInvalid(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user