What are Rust's three procedural macros and derive's advantage over macro_rules?
Tests Rust macros and AST generation vs text macros. Lists derive, attribute-like, and function-like macros, then explains derive needs AST introspection for per-field impl unreachable with macro_rules. Red flag: that macro_rules can iterate struct fields.
What's really being asked
This question tests whether you understand the architectural boundary between declarative and procedural macros in Rust. Interviewers want to see that you know procedural macros run at compile time on TokenStream inputs and operate at the AST level, while macro_rules is a pattern-matching system on token trees without semantic understanding of Rust syntax.
The full answer
First, list the three kinds of procedural macros: custom derive, attribute-like, and function-like. Second, explain that a custom derive macro is attached to a type definition and receives the full AST of that type as a TokenStream. Third, contrast this with macro_rules, which can only match and substitute token patterns but cannot inspect the semantic structure of a type, such as counting fields, reading field names, or checking types. Fourth, emphasize that derive macros generate code based on the actual shape of the data, which requires parsing Rust syntax into a structured form, something macro_rules cannot do robustly because it lacks type introspection and operates before name resolution.
The mistakes people make
A major red flag is claiming that macro_rules could implement a custom derive by simply repeating a pattern. Another mistake is confusing the three types or omitting attribute-like and function-like procedural macros. Some candidates also incorrectly state that procedural macros run at runtime or that they modify the compiler itself. Failing to mention TokenStream or AST-level manipulation suggests shallow knowledge.
What usually comes next
An interviewer might ask how you would implement a custom derive macro in practice, including the use of syn and quote crates. They might ask about hygiene in procedural macros or how to emit helpful compiler errors from within a proc macro. Another follow-up is asking when you would choose an attribute-like macro over a derive macro, or how function-like procedural macros differ from macro_rules in terms of invocation syntax and capabilities.
A concrete example
Suppose you want to implement a MyDebug derive that prints each field name and value. A procedural derive macro receives the struct AST, iterates over fields, and generates an impl Debug block with format_args for each field. With macro_rules, you cannot write a pattern that accepts an arbitrary struct and iterates its fields by name and type, because macro_rules has no mechanism to destructure a struct definition into its constituent fields during expansion. You would need to write a separate macro invocation per field or use a brittle recursive pattern that does not scale.
Interview question
Which statement accurately captures why a custom derive can generate per-field code for an arbitrary struct while macro_rules cannot?
- a.macro_rules matches token trees without semantic parsing, so it cannot introspect a struct's fields, whereas derive macros parse the ASTCorrect
- b.Custom derive macros modify the compiler's internal AST directly, while macro_rules only rewrites token streams
- c.macro_rules can implement custom derives by repeating token patterns for each field explicitly passed to it
- d.macro_rules expands after name resolution, when the struct's token representation is no longer available
Why? this is the answer
Custom derive macros parse a struct's TokenStream into an AST to inspect fields, while macro_rules only matches token patterns without semantic understanding. Option B is a common misconception—proc macros do not modify the compiler—and option C is the red flag that macro_rules could handle derive via simple repetition if fields are listed explicitly.
Just read this? Test yourself on what you have been reading.
Read the original → doc.rust-lang.org
- #rust
- #macros
- #procedural-macros
- #compile-time
- #metaprogramming
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on rust — each one lists the topics its interview covers.
See open roles