Limits of Rust macros


I would like to learn more on Rust macros and its limits. Especially I would like to know:

  • is the exclamation mark suffix a simple convention or a syntax requirement? If this is a syntax requirement, is there already a facility to parameter this behavior like a $RUST_MACRO_SUFFIX environment variable?
  • is it already possible to alias keywords, for example aliasing } with end?

Thank you in advance for any feedback on how to achieve that, including relevant resources to read and where to make corresponding proposals if some facilities are not yet available. Thank you also to not reply with advises on why this should not be done, resources will be better spend in providing attention to other issues.



The ! is a required part of the syntax. It cannot be changed.

Macros can only expand to a limited set of complete syntactic constructs.

You cannot achieve either of these things within the language. Proposals to change the first might theoretically succeed (although I wouldn’t expect them to). Proposals to change the second are extraordinarily unlikely to succeed, as it would require redesigning the language at a fundamental level, followed by a huge overhaul of the compiler for a feature the language was specifically designed to not have in the first place.

You might want to spend some more time with the language before submitting any RFCs.


Thank you very much @DanielKeep for your kind and informative answer.

I do intend to follow your advice of better familiarize with the language before making any proposal.

Right now, I don’t see how the second proposal would conflict fundamentally with the goals of the language design, so I would be very interesting to have more information about that. If any relevant documentation exists out there, that would be perfect. A more contextual answer would be even more awesome of course.

I don’t intend to make any proposal that wouldn’t end up in being a backward incompatible solution, and I fail to see how the sketch of proposal I made would be unreachable within the realm of these constraints. Probably I just miss information to well perceive how such a change would have such a deep impact regarding the design of the language. To my mind these facilities can be confined in the lexical analyze phase, so very early in the compiling chain, that’s I wouldn’t expect conflict with any deeply engraved design goal.

Kind regards


I can’t point to any specific page, but I recall that there has historically been a strong bias against C-style unstructured macros. Rust using a more sophisticated, structured approach is a point of pride for the language. That is specifically prohibits things like having macros expand to } is deliberate. That’s the design issue.

The practical issue is that Rust macros are not a separate phase like they are in C. Macros are part of the syntactic structure of the code, and are expanded after parsing has already happened. It’s not just that it’s not desirable for them to expand to }, it’s impossible with the way the grammar and compiler are designed.

That’s the problem: they can’t.


Your answer help me immensely in better understand the issue, thank you @DanielKeep ! :slight_smile:

You were perfectly right that I had in mind compiler phase as they are more traditionally implemented for C/C++.

For now I think I’ll focus on finishing the book, trying to stash all my usual attempt to use an other language than the one used in the tutorial and test how it works (or fails to do so).

In parallel I plane to follow Tracking issue for RFC 2457, “Allow non-ASCII identifiers” which also relate to that willing to make Rust environment a more welcoming place to lexical diversity of human languages, so it empowers people beyond borders of the English speaking privileged people.


I very strongly do not recommend this, but it is technically possible to run a preprocessor over your source using a build script.


Thank you @parasyte, I’ll have a look at that.

Although I suspect this would add an extra layer of interpretation that would not seamlessly integrate with the compiler tool chain in a way that keep relationship between raised errors and the place where it was most likely introduced in the code. But unexpected good news can happen too, just like the one you provided me, thank you. At the very least it would be an easy way to start experimenting, I guess. :slight_smile: