Implement a custom derive macro for a Builder pattern
Tests proc-macro AST transformation. A strong answer lists: parse TokenStream with syn into DeriveInput, inspect fields, then quote builder code as TokenStream, noting the separate proc-macro crate. Red flag: treating tokens as strings instead of AST nodes.
WHAT THIS TESTS: Your ability to reason about Rust compile-time metaprogramming. Specifically, the interviewer wants to know if you understand the boundary between the proc-macro crate and normal Rust code, how to inspect an AST without hand-rolling a parser, and how to emit hygienic code that integrates with the compiler.
A GOOD ANSWER COVERS: Four things in order. First, the macro entry point is a function annotated with proc_macro_derive that takes a TokenStream and returns a TokenStream. Second, you pass that input to syn to parse it into a DeriveInput, which lets you iterate over fields, types, and attributes. Third, you build the desired output, for example by creating a new builder struct with optional fields and setter methods, using quote to turn Rust-like syntax back into a TokenStream. Fourth, you note that proc macros must reside in their own crate with crate-type proc-macro, and that quote preserves hygiene so generated identifiers do not accidentally collide with user code.
COMMON WRONG ANSWERS: Treating TokenStream as strings and concatenating text. This is a red flag because it ignores token hygiene and parsing edge cases. Another mistake is forgetting that derive macros only add code and cannot modify the original struct, or confusing declarative macros macro_rules with procedural macros. Some candidates also omit the separate crate requirement entirely.
LIKELY FOLLOW-UPS: How would you handle generics and where clauses on the target struct. How would you support optional attributes on fields, such as builder default values or renaming. How do you report meaningful compile errors from inside a proc macro rather than panicking. What is the difference between quote and quote_spanned for error propagation.
ONE CONCRETE EXAMPLE: Imagine a struct Command with fields executable and args. The derive macro would parse the struct, generate a CommandBuilder with private optional fields, implement methods like executable and args that return self, and a build method that returns Command after checking that required fields are present. The generated code is produced by quote and returned as a TokenStream.
Read the original → doc.rust-lang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.