-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Odd behaviour coming from macros #84259
Comments
I believe this is working as intended (for now). Non-terminal metavariables are parsed as a whole, and if it fails, the whole macro is rejected. macro_rules does not support backtracking (see #42838 and some of the issues linked there). |
I feel like it doesn't have much to do with backtracking. Because Moreover, why Rust is even trying to use the first arm?
|
That's not true, a |
Hm... Indeed then the macro dives into the first arm trying to parse struct T; And call I'll reiterate my point. Consider the following code struct T;
struct U(i32);
struct R(T);
#[macro_export]
macro_rules! test {
// First arm
($array_type:ty => $($elem:expr),+ $(,)?) => {};
// Second arm. Should be tried if the first fails, right? Macros are a match-like thing after all
($($elem:expr),+) => {println!("Expression branch")};
}
fn main() {
// Doesn't get rejected. Rust tries the second arm after realizing the first arm failed
test!(T);
// Gets rejected. Rust should try all the arms, but terminates after failing with the first arm
test!(U(2));
// Doesn't get rejected purely because R(T) parses as a type
test!(R(T));
} Rust compiles well the first line of the main, but fails with the second one. They both don't satisfy the first arm of the macro in some way, but the second macro invocation gets a different treatment than the first one. |
It only fails when there is an error matching a nonterminal matching fragment. |
Which brings us back to the backtracking issue, which seems dead... Alright, guess I'll close this issue. Is there any progress on the original backtracking issue, which is unseen to us? |
I'm not aware of anyone working on it. #33840 (comment) discusses some of the complexity involved in solving it. |
Yeah... Seems like the feature isn't going to be added at least for backtracking and trying other macro arms... Guess I'll look for other ways to solve the issue in the |
I tried this code:
I expected it to compile, since
T(2)
is obviously an expression.Instead I received the following compiler error:
The compiler seems to forcefully parse the string with the first rule (although it is clearly inapplicable here), fails and terminates with an error.
What is more surprising is that the following code compiles just fine
Even the right branch gets picked (the second one)!
Moreover, reordering the branches breaks the following example (which compiles if you swap the
test
's arms back)Meta
rustc --version --verbose
:Beta and nightly struggle with this code too.
The text was updated successfully, but these errors were encountered: