go/parser: leave checking of LHS in short var decls to type checker

Instead of checking at parse-time that the LHS of a short variable
declaration contains only identifiers, leave the check to the the
type checker which tests this already.

This removes a duplicate error and matches the behavior of the
syntax package.

For #54511.

Change-Id: I4c68f2bd8a0e015133685f9308beb98e714a83fc
Reviewed-on: https://go-review.googlesource.com/c/go/+/426476
Run-TryBot: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
This commit is contained in:
Robert Griesemer 2022-08-29 15:45:35 -07:00 committed by Gopher Robot
parent a74d46d8ff
commit 1280ae7856
4 changed files with 3 additions and 22 deletions

View file

@ -2487,8 +2487,6 @@ func (p *parser) commClause() *CommClause {
//
// All these (and more) are recognized by simpleStmt and invalid
// syntax trees are flagged later, during type checking.
// TODO(gri) eventually may want to restrict valid syntax trees
// here.
case _Default:
p.next()

View file

@ -1867,11 +1867,7 @@ func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
} else {
y = p.parseList(true)
}
as := &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}
if tok == token.DEFINE {
p.checkAssignStmt(as)
}
return as, isRange
return &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}, isRange
}
if len(x) > 1 {
@ -1918,14 +1914,6 @@ func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
return &ast.ExprStmt{X: x[0]}, false
}
func (p *parser) checkAssignStmt(as *ast.AssignStmt) {
for _, x := range as.Lhs {
if _, isIdent := x.(*ast.Ident); !isIdent {
p.errorExpected(x.Pos(), "identifier on left side of :=")
}
}
}
func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
x := p.parseRhs() // could be a conversion: (some type)(x)
if t := unparen(x); t != x {
@ -2245,11 +2233,7 @@ func (p *parser) parseCommClause() *ast.CommClause {
pos := p.pos
p.next()
rhs := p.parseRhs()
as := &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
if tok == token.DEFINE {
p.checkAssignStmt(as)
}
comm = as
comm = &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
} else {
// lhs must be single receive operation
if len(lhs) > 1 {

View file

@ -143,7 +143,6 @@ var invalids = []string{
`package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type), t {} };`,
`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 boolean expression" */ = 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 }() };`,

View file

@ -24,7 +24,7 @@ func _() {
func _() {
var a []int
a /* ERROR expected identifier */ /* ERROR non-name .* on left side of := */ [0], b := 1, 2
a /* ERROR non-name .* on left side of := */ [0], b := 1, 2
_ = a
_ = b
}