Yeah, right. And that’s why the first example (without the semicolons, with the expr
arm first) should be disallowed. In fact it was taken from the running
example that triggered this whole issue that used type ascription. Now
that type ascription is actually landing, it’s no longer
future-proofing, so I changed the example to use a @ instead of a :, but the example remains the same.
macro_rules! foo(
($e:expr) => ...;
($x:ident @ $e:expr) => ...
);
Let’s invoke the macro with: foo!(x @ x). If expr ::= ident @ expr
is ever added as a production to the language, we have a problem.
Problem that can be solved by swapping arm, because errorneous input now
match the first arm, both before and after extension of the language.
Now for the third example, the one you are talking about:
macro_rules! foo(
($x:ident @ $e:expr ; $e2:expr) => ...;
($e:expr ; $x:ident @ $e2:expr) => ...
);
Mhhhh I guess I got confused at some point because I can’t find
anymore an example that triggers a problem, and thinking about it I
believe there is none, I shouldn’t have used the same ‶hypothetical future
syntax″ before and after the semicolon. But I think I can find an
example of a macro such that, whatever is the order in which you put the
arms, you have an error, because the ‶first half″ (before the
semicolon) of the first arm is more specific than the ‶first half″ of
the second arm, but it’s the opposite for the ‶second halfs″. For
example:
macro_rules! foo(
($x:ident ; $e2:expr) => ...;
($e:expr ; $x:ident @ $e2:expr) => ...
);
Here foo!(x ; x @ x) can change arm if we add the same
production as above to the grammar. Ok it’s not exactly the same example
but from the point of vue of the algorithm it’s still a more specific
token in the first arm versus more general NT in the second arm″ case.
And to reject it we need to continue the analysis after the semicolons.
Which I think is not possible in the general case, for the reasons I
gave in my previous post.