Open ehuss opened 5 years ago
For the if x != S{} { /* block */ }
version, this has to parse the way it currently does, to allow the perfectly legal and normal code of comparing two variables in a condition. Here we just have to lean on rustfmt
formatting, I guess.
Oh, I'm not implying it is wrong for libsyntax to interpret it the way it does. Although a warning might be nice, this is a contrived example that I doubt anyone would ever write.
I'm more trying to understand how the grammar can be written to express this behavior. libsyntax uses "restrictions", and in https://github.com/rust-lang-nursery/wg-grammar/pull/13#issuecomment-436125874 @eddyb mentioned the open question of how to handle this. #39 is another example where restrictions need to be expressed.
Is it on the table for the GLL parser to be able to express these directly? If not, then it seems you have to bifurcate the definitions (ExprNoStruct would have all expressions except Struct, but that would require recursively copying all the expressions, which I think would be terrible).
What are the options for handling these kinds of restrictions?
I think https://github.com/rust-lang/gll/issues/27 could be a way to handle it with "flags".
I did something similar in the specification of or-patterns, https://github.com/rust-lang/rfcs/blob/master/text/2535-or-patterns.md#grammar.
Various places do not allow struct expressions. All of the following fail to parse in libsyntax, but pass in the current lyg grammar:
if S{a:1} {}
if let x=S{a:1} {}
while S{a:1} {}
while let x=S{a:1} {}
for pat in S{a:1} {}
match S{a:1} {}
This restriction applies recursively (I'm not sure how to express this), that is the following is also rejected:
if x==S{a:1} {}
if S{a:1}.foo() {}
I included a field just because rustc will give a helpful suggestion, whereas a fieldless expression gets confused by the second
{}
which rustc just treats an independent block, as this hilarious example shows:Should this kind of ambiguity rejection be part of the syntax?
See https://github.com/rust-lang/rust/pull/59981 for some examples, and where this was recently changed. See also https://github.com/rust-lang-nursery/reference/issues/569.