How to programmatically get the number of fields of a struct?

Are there any possible API like field_count() or is it only possible to get that via macros? There is no such built-in API that would allow you to get this information at runtime. Rust does not have runtime reflection (see this question for more information). But it is indeed possible via proc-macros! Note: proc-macros are … Read more

Why do proc-macros have to be defined in proc-macro crate?

Procedural macros are fundamentally different from normal dependencies in your code. A normal library is just linked into your code, but a procedural macro is actually a compiler plugin. Consider the case of cross-compiling: you are working on a Linux machine, but building a WASM project. A normal crate will be cross-compiled, generate WASM code … Read more

How to report errors in a procedural macro using the quote macro?

Apart from panicking, there are currently two ways to reports errors from a proc-macro: the unstable Diagnostic API and “the compile_error! trick”. Currently, the latter is mostly used because it works on stable. Let’s see how they both work. The compile_error! trick Since Rust 1.20, the compile_error! macro exists in the standard library. It takes … Read more

What does the tt metavariable type mean in Rust macros?

That’s a notion introduced to ensure that whatever is in a macro invocation correctly matches (), [] and {} pairs. tt will match any single token or any pair of parenthesis/brackets/braces with their content. For example, for the following program: fn main() { println!(“Hello world!”); } The token trees would be: fn main () ∅ … Read more

How to write a custom derive macro?

Create a crate for your procedural macros: cargo new my_derive –lib Edit the Cargo.toml to make it a procedural macro crate: [lib] proc-macro = true Implement your procedural macro: extern crate proc_macro; use proc_macro::TokenStream; #[proc_macro_derive(MyMacroHere)] pub fn my_macro_here_derive(input: TokenStream) -> TokenStream { // … } Import the procedural macro and use it: extern crate my_derive; … Read more

How do I see the expanded macro code that’s causing my compile error?

cargo rustc –profile=check — -Zunpretty=expanded, but a more concise alternative is the cargo-expand crate. It provides a Cargo subcommand cargo expand which prints the result of macro expansion. It also passes the expanded code through rustfmt which generally results in much more readable code than the default output from rustc. Install by running cargo install … Read more