Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upMacro matchers only match when they feel like it #27832
Comments
jdm
added
the
A-macros
label
Aug 14, 2015
This comment has been minimized.
This comment has been minimized.
|
It seems like the However, fixing this (if it can be fixed) is probably a breaking change :( |
This comment has been minimized.
This comment has been minimized.
|
Found the culprit: https://github.com/rust-lang/rust/blob/master/src/libsyntax/ext/tt/macro_parser.rs#L514-L522
Do you really think this would break something? I actually don't think it would, since a fix for this should only accept more macro invocations. |
This comment has been minimized.
This comment has been minimized.
|
On second thought... I think that's not the direct cause, since all other fragments behave roughly the same. Oh well, back to the drawing board |
This comment has been minimized.
This comment has been minimized.
|
Okay, so as it turns out, all NT parsers introduce this bug (except macro_rules! m {
( $b:expr ) => ();
( $t:tt $u:tt ) => ();
}
fn main() {
m!(3); // works trivially
m!(1 2); // works, since `1` is a valid expression
m!(_ 1); // doesn't work, since `_` is not an expression (but a valid TT, of course)
}Now that this confusion is out of the way, I think I see what happens: When parsing However, when parsing So, fixing this would indeed be a breaking change, since the intended behaviour is (at least as far as I know), to reject the invocation, but this isn't happening. |
This comment has been minimized.
This comment has been minimized.
|
@jonas-schievink I disagree that attempting the second arm is a bug. Ideally, Ideally, your last example should go something like this (using
|
This comment has been minimized.
This comment has been minimized.
That would indeed be useful! But I think this comment implies that that isn't the intended behaviour: rust/src/libsyntax/ext/tt/macro_parser.rs Lines 11 to 13 in c115c51 |
This comment has been minimized.
This comment has been minimized.
|
@jonas-schievink I believe that's referring to how it parses within a rule. Earley parsers can deal with ambiguities by tracking multiple potential parse forests (if I remember correctly; my understanding is a little vague). What it's saying is that it has to commit to parsing a non-terminal (i.e. higher-level productions like expressions) because the parser doesn't have any way to back out of a partial parse. So when it encounters one, it has to parse it, come hell or high water. Having the macro system not check successive rules once a rule starts matching would be apocalyptic: it would kill damn near every useful, non-trivial macro. We're talking mass hysteria, cats and dogs living together. |
This comment has been minimized.
This comment has been minimized.
Fair enough. In that case the bug is just that the macro expander will panic when it can't parse an NT, so it can't backtrack. I also managed to dig up #3232, which was closed as "not a bug", but this definitely feels like one. |
jseyfried
self-assigned this
Jan 12, 2017
This comment has been minimized.
This comment has been minimized.
|
@jonas-schievink Sorry to dig this up again, but isn't an |
This comment has been minimized.
This comment has been minimized.
|
@dylanede Correct! That's why I mentioned this comment:
(AFAIK, token == terminal) |
lfairy
referenced this issue
May 10, 2017
Merged
Suggest `!` for bitwise negation when encountering a `~` #41722
This comment has been minimized.
This comment has been minimized.
jeberger
commented
Jun 23, 2017
|
I got bitten by this bug too. Note that I see two different issues here:
|
jonas-schievink commentedAug 14, 2015
...or at least that's how much I currently understand, since macros are really counterintuitive sometimes.
I don't think this is supposed to happen. Even if it is, the exact rules used for macro matching should definitely be documented somewhere (I think there's not even an RFC).