Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
GitHub is where the world builds software
Millions of developers and companies build, ship, and maintain their software on GitHub — the largest and most advanced development platform in the world.
go/parser: Accepts method definition without receiver #11271
go/parser accepts the following program:
without reporting any error. It should complain about the missing method receiver.
Code to reproduce:
This is working as intended. The go/parser accepts a wider syntax than is permitted by the language spec, for simplicity, and robustness. Also, some (like this one) checks are easier done after parsing - putting them into the parser makes it harder for other tools (e.g. go/types: which error should it check for, and which should it not check for? This has implications for testing as some errors may be reported twice by different libs, etc.).
It's quite unfortunate that downstream tools have to handle invalid syntax in the output of
@cespare There is no easy or even obvious solution to this problem:
Thus, we decided that it's best to be conservative in the parser and accept a wider language. What wider language one may ask? There's a fairly natural correspondence between accepted language and what the AST can represent: If an AST field is not restricted (e.g. in the case of receivers, the ast.FuncDecl.Recv field is simply an *ast.FieldList), then the parser may accept more than one parameter (as is the case) and a client must do whatever checking is needed if the language imposes restrictions (in the case of the receiver, a client must check that the respective FieldList is correct).
A more formal approach would be welcome, but this is what we have. Note that the situation is the same in an actual compiler, it's just that there the internals are not exposed. Also, note that many tools don't care (e.g. gofmt will just reproduce what it gets).
The rule is: If a program consumes an incoming AST the program must check slice lengths etc. before accessing elements - it cannot simply assume that the AST was built according to the spec. If the program assumes a field of type Expr is of a specific expression, it must use a type assertion (that may fail), etc.
We have been thinking about an paired approach:
It's not clear that this avoids many problems. It's very likely that same problem appears between that 2nd light-weight tool and any client.