Commit 66cc0d6f authored by Robert Griesemer's avatar Robert Griesemer

don't require ()'s around composite literals if the

literal type is not a type name

R=rsc
DELTA=41  (2 added, 7 deleted, 32 changed)
OCL=28955
CL=28957
parent b7585a31
...@@ -1070,40 +1070,34 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr { ...@@ -1070,40 +1070,34 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr {
} }
// checkTypeName checks that x is type name. // isTypeName returns true iff x is type name.
func (p *parser) checkTypeName(x ast.Expr) ast.Expr { func isTypeName(x ast.Expr) bool {
// TODO should provide predicate in AST nodes // TODO should provide predicate in AST nodes
switch t := x.(type) { switch t := x.(type) {
case *ast.BadExpr: case *ast.BadExpr:
case *ast.Ident: case *ast.Ident:
case *ast.ParenExpr: p.checkTypeName(t.X); // TODO should (TypeName) be illegal? case *ast.ParenExpr: return isTypeName(t.X); // TODO should (TypeName) be illegal?
case *ast.SelectorExpr: p.checkTypeName(t.X); case *ast.SelectorExpr: return isTypeName(t.X);
default: default: return false; // all other nodes are not type names
// all other nodes are not type names
p.error_expected(x.Pos(), "type name");
x = &ast.BadExpr{x.Pos()};
} }
return x; return true;
} }
// checkCompositeLitType checks that x is a legal composite literal type. // isCompositeLitType returns true iff x is a legal composite literal type.
func (p *parser) checkCompositeLitType(x ast.Expr) ast.Expr { func isCompositeLitType(x ast.Expr) bool {
// TODO should provide predicate in AST nodes // TODO should provide predicate in AST nodes
switch t := x.(type) { switch t := x.(type) {
case *ast.BadExpr: return x; case *ast.BadExpr:
case *ast.Ident: return x; case *ast.Ident:
case *ast.ParenExpr: p.checkCompositeLitType(t.X); case *ast.ParenExpr: return isCompositeLitType(t.X);
case *ast.SelectorExpr: p.checkTypeName(t.X); case *ast.SelectorExpr: return isTypeName(t.X);
case *ast.ArrayType: return x; case *ast.ArrayType:
case *ast.StructType: return x; case *ast.StructType:
case *ast.MapType: return x; case *ast.MapType:
default: default: return false; // all other nodes are not legal composite literal types
// all other nodes are not legal composite literal types
p.error_expected(x.Pos(), "composite literal type");
x = &ast.BadExpr{x.Pos()};
} }
return x; return true;
} }
...@@ -1137,24 +1131,23 @@ func (p *parser) parsePrimaryExpr() ast.Expr { ...@@ -1137,24 +1131,23 @@ func (p *parser) parsePrimaryExpr() ast.Expr {
} }
x := p.parseOperand(); x := p.parseOperand();
for { L: for {
switch p.tok { switch p.tok {
case token.PERIOD: x = p.parseSelectorOrTypeAssertion(p.checkExpr(x)); case token.PERIOD: x = p.parseSelectorOrTypeAssertion(p.checkExpr(x));
case token.LBRACK: x = p.parseIndex(p.checkExpr(x)); case token.LBRACK: x = p.parseIndex(p.checkExpr(x));
case token.LPAREN: x = p.parseCallOrConversion(p.checkExprOrType(x)); case token.LPAREN: x = p.parseCallOrConversion(p.checkExprOrType(x));
case token.LBRACE: case token.LBRACE:
if p.expr_lev >= 0 { if isCompositeLitType(x) && (p.expr_lev >= 0 || !isTypeName(x)) {
x = p.parseCompositeLit(p.checkCompositeLitType(x)); x = p.parseCompositeLit(x);
} else { } else {
return p.checkExprOrType(x); break L;
} }
default: default:
return p.checkExprOrType(x); break L;
} }
} }
panic(); // unreachable return p.checkExprOrType(x);
return nil;
} }
...@@ -1768,7 +1761,9 @@ func (p *parser) parseReceiver() *ast.Field { ...@@ -1768,7 +1761,9 @@ func (p *parser) parseReceiver() *ast.Field {
if ptr, is_ptr := base.(*ast.StarExpr); is_ptr { if ptr, is_ptr := base.(*ast.StarExpr); is_ptr {
base = ptr.X; base = ptr.X;
} }
p.checkTypeName(base); if !isTypeName(base) {
p.error_expected(base.Pos(), "type name");
}
return recv; return recv;
} }
......
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