Where is macro_rules! coming from? Where is it documented?

I though I should be able to find it in the std documentation but the search has no results and the list of macros does not mention it.

The best (and only?) thing I found was macro_rules! in Rust by Example

There is also information in the Rust reference: Macros By Example - The Rust Reference

1 Like

you can find the document in the book and the reference

macro_rules is a built-in primitive of the language, it's NOT a macro itself, thus cannot be defined in the library.

2 Likes

Well it's probably more correct to say it's a "built in macro", it's still using macro syntax with ! (I assume it is or was essentially a proc macro, taking and returning a sequence of token trees internally)

(The future macros 2.0 using the macro keyword won't be a macro itself, though!)

1 Like

But it doesn't. Macro calls cannot have an identifier following the bang, you need to wrap it in extra parenthesis. And a macro must expand to some valid syntax in the language although it could be unstable syntax or compiler built-ins, which probably could include an unstable macro_rules! declaration, while macro_rules! doesn't expand to anything, and doesn't respect the lexical scopes.

2 Likes

macro_rules! used to be treated like other (builtin) macros by rustc, "expanding" to no code and a side effect on parser state. This is why macro_rules! scoping with #[macro_export] and #[macro_use] is the way it is. It's also why syntax errors in the macro_rules! definition itself are reported like errors using declarative macros (e.g. "no rules expected the token") — it's parsed by that same syntax matching machinery in the compiler.

Coinciding with adding the ability to use macro names, macro_rules! was made into its own specific item syntax independent from macro call syntax.

Bonus trivia: because macro_rules! is a weak keyword, it's not a reserved name in the macro namespace and it's perfectly valid to define macro_rules! macro_rules. But maybe, don't, for the same reason that while you can define your own type i32 shadowing the primitive, you shouldn't.

Oh, asm!, the “macro-like expression,” how we love ye for being the exception to prove the rule,,,

1 Like

That means it wasn't treated like other macros, because macros don't store any state between invocations, and macros by example don't have any side effects at all (which is a major plus).

That falls into the "compiler builtin" category. In a sense, this means that a macro can do anything at all via special-case compiler treatment. However, asm! is fully hygienic, like a proper macro. It's like a special opaque expression, which makes it closer to true macros than macro_rules!.