-
Notifications
You must be signed in to change notification settings - Fork 1.7k
failed to parse if_chain
macro invocation
#7845
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
Comments
Here's a MWE without the use of fn main() {
macro_rules! identity { ($($es:tt)*) => { $($es)* } }
identity! { let _ = (); }
} Adding any tokens after the call to |
[deleted] |
Are you sure? In the simplified version there is no alternate case to match. |
Yeah, you are right, it is another issue. |
DiagnosisThe syntax tree of that MWE (without semicolon) :
But with semicolon:
And in So that's why the one without semi colon we will treat it as On the other hand, in body lowering code: We only handle FixesSo, to fix this bug, we have to handle |
Note that adding a semicolon is not necessarily an option, for example in fn foo() -> bool {
macro_rules! identity { ($($es:tt)*) => { $($es)* } }
identity! { let _ = (); true }
} adding a semicolon would cause a typechecking error. It would be an option to introduce an extra block scope here, i.e. assume that |
For reference, this is how rustc expands @digama0's snippet: #![feature(prelude_import)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
fn foo() -> bool {
macro_rules! identity { ($ ($ es : tt) *) => { $ ($ es) * } }
let _ = ();
true
} So the tokens are substituted right in, with no extra braces or semicolons. |
Here's a simple version of the problem using the
if_chain
macro:In rustc this works fine, but rust-analyzer marks the
(())
asfailed to parse macro invocation
. Note thatif_chain!
is amacro_rules
macro, so this is an issue in macro expansion. The contents of thethen { ... }
branch is matched using the matcherthen { $($then:tt)* }
so even though this portion of the code is mostly untouched by the macro (it's supposed to expand to justlet _ = drop(());
) it is matched as a list of token trees, of which(())
is one of them. Thelet _ =
is also part of the error, so it may be getting confused with the other matches in the macro.The text was updated successfully, but these errors were encountered: