Commit b0507f15 authored by Robert Griesemer's avatar Robert Griesemer

go/parser: better error message for incorrect type switch header

Fixes 11829.

Change-Id: I2e39f61e12953147b0cd6a11d29179c500c94964
Reviewed-on: https://go-review.googlesource.com/14566Reviewed-by: default avatarChris Manghane <cmang@golang.org>
parent 5b3f29a2
...@@ -1910,14 +1910,23 @@ func isTypeSwitchAssert(x ast.Expr) bool { ...@@ -1910,14 +1910,23 @@ func isTypeSwitchAssert(x ast.Expr) bool {
return ok && a.Type == nil return ok && a.Type == nil
} }
func isTypeSwitchGuard(s ast.Stmt) bool { func (p *parser) isTypeSwitchGuard(s ast.Stmt) bool {
switch t := s.(type) { switch t := s.(type) {
case *ast.ExprStmt: case *ast.ExprStmt:
// x.(nil) // x.(type)
return isTypeSwitchAssert(t.X) return isTypeSwitchAssert(t.X)
case *ast.AssignStmt: case *ast.AssignStmt:
// v := x.(nil) // v := x.(type)
return len(t.Lhs) == 1 && t.Tok == token.DEFINE && len(t.Rhs) == 1 && isTypeSwitchAssert(t.Rhs[0]) if len(t.Lhs) == 1 && len(t.Rhs) == 1 && isTypeSwitchAssert(t.Rhs[0]) {
switch t.Tok {
case token.ASSIGN:
// permit v = x.(type) but complain
p.error(t.TokPos, "expected ':=', found '='")
fallthrough
case token.DEFINE:
return true
}
}
} }
return false return false
} }
...@@ -1963,7 +1972,7 @@ func (p *parser) parseSwitchStmt() ast.Stmt { ...@@ -1963,7 +1972,7 @@ func (p *parser) parseSwitchStmt() ast.Stmt {
p.exprLev = prevLev p.exprLev = prevLev
} }
typeSwitch := isTypeSwitchGuard(s2) typeSwitch := p.isTypeSwitchGuard(s2)
lbrace := p.expect(token.LBRACE) lbrace := p.expect(token.LBRACE)
var list []ast.Stmt var list []ast.Stmt
for p.tok == token.CASE || p.tok == token.DEFAULT { for p.tok == token.CASE || p.tok == token.DEFAULT {
......
...@@ -64,7 +64,7 @@ var invalids = []string{ ...@@ -64,7 +64,7 @@ var invalids = []string{
`package p; func f() { for _ = range x ; /* ERROR "expected '{'" */ ; {} };`, `package p; func f() { for _ = range x ; /* ERROR "expected '{'" */ ; {} };`,
`package p; func f() { for ; ; _ = range /* ERROR "expected operand" */ x {} };`, `package p; func f() { for ; ; _ = range /* ERROR "expected operand" */ x {} };`,
`package p; func f() { for ; _ /* ERROR "expected boolean or range expression" */ = range x ; {} };`, `package p; func f() { for ; _ /* ERROR "expected boolean or range expression" */ = range x ; {} };`,
`package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type) {} };`, `package p; func f() { switch t = /* ERROR "expected ':=', found '='" */ t.(type) {} };`,
`package p; func f() { switch t /* ERROR "expected switch expression" */ , t = t.(type) {} };`, `package p; func f() { switch t /* ERROR "expected switch expression" */ , t = t.(type) {} };`,
`package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type), t {} };`, `package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type), t {} };`,
`package p; var a = [ /* ERROR "expected expression" */ 1]int;`, `package p; var a = [ /* ERROR "expected expression" */ 1]int;`,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment