-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
macros should be parsed more lazily #6994
Comments
Nominating for well-defined. |
double triage before triage meeting. i think this could maybe be well-covered; we understand how it should work, and it's not a backwards-compat hazard. |
I think the tag "A-macos" is unfortunate, since this is not Mac OS specific. Or is it? |
I imagine it's just a typo because |
I guess so. Maybe rename "A-macos" to "A-mac_os" or "A-mac"? |
Accepted for milestone 3, feature-complete |
Wow! glad to see this wind up on a milestone... |
P-low, not 1.0. |
Would this be fixable by allowing // the z flows into and out of two macros (g & f) along one path, and one (just g) along the
// other, so the result of the whole thing should be "let z_123 = 3; z_123
macro_rules! g (
($x:ident) =>
(
{macro_rules! f(
($$y:ident)=>({let $$y=3;$x})
);
f!($x)})
)
fn a(){g!(z)} The |
No, don't go down that road; I don't believe that will lead to a nice solution. |
OK. It would be nice if the eventual solution was not specific to nested (I could easily imagine other more common procedural macros that may wish to "overload" the |
Hang on... where is the $a bound, in your example? |
Sorry, was on my phone making it difficult to explain fully. I meant something like let a: i32 = ...;
macro_rules! foo {
($e: expr) => { quote_expr!(cx, $$a + $e) }
}
foo!(1);
foo!(2); The above is theoretically equivalent to the following, which is unquoting/splicing
(The |
in this case, you shouldn't need |
I'm thinking more about this issue, and I think it's misnamed. The fundamental issue here is how the transcription engine matches up bindings of macro variables with uses of those variables. The solution, I think, is pretty straightforward: the transcription engine should just ignore transcription Also, hygiene should stick its nose in, here. There should be a renaming of all pattern identifiers. I think the sneaky side-effect of this will be to make the $'s in the right-hand sides redundant. |
No, The ones with |
Hey! Let's argue! :) I understand now better what you're looking for. Specifically, you want to use $ as an unquote mechanism in procedural macros, in order to splice in other syntactic terms and values from the context of the macro definition (specifically, I missed the fact that you were using quote_expr! before, sorry). This is plausible, but I'd like to point out that it's not the same as what $a does currently—it's not an unquoting mechanism. This is perhaps most clear when the identifier 'a' is bound to a sequence rather than a single syntactic term, but even in the single-match case, the RHS use of $a is not actually inserting the value of an 'a' variable defined in a surrounding context. I think that something like this is possible, but I don't think that re-using $ is the right way to go. Lemme fix this, and then we'll see where we are. |
Oh dear Lord... I may have spoken too quickly. Or perhaps I meant to say, I may have spoken way too late. I see that the source is already peppered with uses of $ that may in fact be unquotes. Reading more... |
Yes, I see that it absolutely is used that way. That's a bad pun, and I think it might be painful.... |
The problem would be resolved IMO if we have some technique that works for those cases that's not |
Triage: OP's code, with a semicolon, still generates the same error. |
Triage: There is still the same error happening on // the z flows into and out of two macros (g & f) along one path, and one (just g) along the
// other, so the result of the whole thing should be "let z_123 = 3; z_123
macro_rules! g (
($x:ident) =>
(
{macro_rules! f(
($y:ident)=>({let $y=3;$x})
);
f!($x)})
);
fn a(){g!(z)} Error:
|
This is a FIXME issue; currently, macro invocations are parsed too eagerly. In particular, the current system decides before expansion time whether a rhs pattern-use (e.g. $y) is bound or unbound. This is incompatible with macro-producing macros that use a given identifier in a pattern position. It's also incompatible with macros inside macros, where inner binding patterns are believed to be pattern uses. The solution is to delay this decision until the macro is encountered at expansion-time, by which time all outer macros have been expanded.
Here's an example of a macro that doesn't work in the current system:
Trying to expand this yields this error:
... indicating that the $y is believed to be a use, rather than a binder.
The text was updated successfully, but these errors were encountered: