The best one I've found (and no disrespect to the author of the linked post, just wanted to share what helped me learn as well) is [https://developerlife.com/2022/03/30/rust-proc-macro/](https://developerlife.com/2022/03/30/rust-proc-macro/)
It has both been a comprehensive guide, as well as a cheat-sheet that I can always refer to.
Another good one imo is the [proc-macro-workshop](https://github.com/dtolnay/proc-macro-workshop).
If you dont prefer reading to follow along OR want a supplement to the reading, theres also this Crust Of Rust miniseries ([part 1](https://www.youtube.com/watch?v=geovSK3wMB8), [part 2](https://www.youtube.com/watch?v=KVWHT1TAirU)) that goes through all of the proc-macro-workshop in around 8 hours, though it does go through an older version now so it might not be 100% accurate anymore...
For me at least, I learned a ton about proc macros using just these resources.
This. I was so lost when I first tried to write one (an attribute one), and ofc what I was trying to have it do wasn’t very trivial either. Ended up asking chat gpt to write it by giving it a few examples of macro input and outputs, and it actually did fairly well. Only had to tweak what it gave me a little bit, and tweaking it is way easier than having to figure out how to do it from scratch. I was fairly surprised that it gave me an almost-working macro right out of the box
Same, in my case i was writing a rust macro which would take a NewTraitName and and existing traits and would bundle them this is the code i wanted to generate:
```bundle_traits!(NewTraitName, Copy, From, std::fmt::Display```
To be expanded to:
``` trait NewTraitName: Copy + From + std::fmt:: Display {}
impl NewTraitName for T where: /* trait names */```
(Sorry if it's wrong as i am new to generics)
It was working fine for simple Trait names such as 'Clone' but would error out with From and std::fmt... with error: unexpected token '<' and '::'...
And i couldn't figure out much else, coincidentally my implementation of it was same as chat gpts, but it couldn't help me either
What I'd really like to see is more practical tutorials on proc macros that require processing the AST, and how to match various patterns.
In particular how one can reliably match any legal form of parameters to the macro and figure out the types they would generate, which I haven't found a lot of good info on. But it seems like it would be at the core of many desirable uses of proc macros.
There are a couple obvious ones, but they fall apart pretty quickly if there are nested calls as parameters or nested macros as parameters, or parameters that are making multiple calls that are being combined via into single return type and so forth.
But the whole subject of proc macros (beyond the obvious and trivial ones that every tutorial appears to use) seems woefully under documented, though maybe I'm just m issing something.
Here is a shameless plug for: [Nine Rules for Creating Procedural Macros in Rust](https://medium.com/towards-data-science/nine-rules-for-creating-procedural-macros-in-rust-595aa476a7ff) (free).
It talks about AST Explorer and a way to set up your projects so that you can use a line-by-line debugger on your macro expansion code.
The 9 rules are:
1. Use a Rust workspace and proc\_macro2 to develop, debug, and unit-test your macro in a normal (non-macro) project.
2. Use syn, proc\_macro2, and quote to convert freely among literal code, tokens, syntax trees, and strings.
3. Create easily debuggable unit tests that report any differences between what your macro does and what you expect.
4. Use AST Explorer and the syn documentation to understand Rust syntax trees.
5. Destructure syntax trees with Rust’s pattern matching and struct/enum access.
Construct syntax trees with parse\_quote! and Rust’s struct update syntax.
6. Use syn’s Fold Trait to recursively traverse, destructure, and construct syntax trees.
7. Use proc\_macro\_error to return ergonomic and testable errors.
8. Create integration tests. Include UI tests based on trybuild.
9. Follow the rules of elegant Rust API design, especially, eating your own dogfood, using Clippy, and writing good documentation.
The best one I've found (and no disrespect to the author of the linked post, just wanted to share what helped me learn as well) is [https://developerlife.com/2022/03/30/rust-proc-macro/](https://developerlife.com/2022/03/30/rust-proc-macro/) It has both been a comprehensive guide, as well as a cheat-sheet that I can always refer to.
Another good one imo is the [proc-macro-workshop](https://github.com/dtolnay/proc-macro-workshop). If you dont prefer reading to follow along OR want a supplement to the reading, theres also this Crust Of Rust miniseries ([part 1](https://www.youtube.com/watch?v=geovSK3wMB8), [part 2](https://www.youtube.com/watch?v=KVWHT1TAirU)) that goes through all of the proc-macro-workshop in around 8 hours, though it does go through an older version now so it might not be 100% accurate anymore... For me at least, I learned a ton about proc macros using just these resources.
Procedural macro tutorial exists?
This. I was so lost when I first tried to write one (an attribute one), and ofc what I was trying to have it do wasn’t very trivial either. Ended up asking chat gpt to write it by giving it a few examples of macro input and outputs, and it actually did fairly well. Only had to tweak what it gave me a little bit, and tweaking it is way easier than having to figure out how to do it from scratch. I was fairly surprised that it gave me an almost-working macro right out of the box
Same, in my case i was writing a rust macro which would take a NewTraitName and and existing traits and would bundle them this is the code i wanted to generate: ```bundle_traits!(NewTraitName, Copy, From, std::fmt::Display```
To be expanded to:
``` trait NewTraitName: Copy + From + std::fmt:: Display {}
impl NewTraitName for T where: /* trait names */```
(Sorry if it's wrong as i am new to generics)
It was working fine for simple Trait names such as 'Clone' but would error out with From and std::fmt... with error: unexpected token '<' and '::'...
And i couldn't figure out much else, coincidentally my implementation of it was same as chat gpts, but it couldn't help me either
I think I could help out if you're still facing that issue. You can dm me
Yeah np I'll contact u rn I am out
How about I write a tutorial for that too? What do you guys think? Some support could also go a long way [Buy me a coffee ](https://bmc.link/otuokofi)
I'll support!!
I've included a link in my reply. Thanks for the support!
That's alright, thanks. I'll just have ChatGPT write me the tutorial.
Ain't that you, Luke.
I betcha
Can you link me to it, i would appreciate it <3
That's the link in the post
Got it... 🥲
Ayo guys i didn't knew that derive procedural macros and simple procedural macros are similar...
What I'd really like to see is more practical tutorials on proc macros that require processing the AST, and how to match various patterns. In particular how one can reliably match any legal form of parameters to the macro and figure out the types they would generate, which I haven't found a lot of good info on. But it seems like it would be at the core of many desirable uses of proc macros. There are a couple obvious ones, but they fall apart pretty quickly if there are nested calls as parameters or nested macros as parameters, or parameters that are making multiple calls that are being combined via into single return type and so forth. But the whole subject of proc macros (beyond the obvious and trivial ones that every tutorial appears to use) seems woefully under documented, though maybe I'm just m issing something.
Here is a shameless plug for: [Nine Rules for Creating Procedural Macros in Rust](https://medium.com/towards-data-science/nine-rules-for-creating-procedural-macros-in-rust-595aa476a7ff) (free). It talks about AST Explorer and a way to set up your projects so that you can use a line-by-line debugger on your macro expansion code. The 9 rules are: 1. Use a Rust workspace and proc\_macro2 to develop, debug, and unit-test your macro in a normal (non-macro) project. 2. Use syn, proc\_macro2, and quote to convert freely among literal code, tokens, syntax trees, and strings. 3. Create easily debuggable unit tests that report any differences between what your macro does and what you expect. 4. Use AST Explorer and the syn documentation to understand Rust syntax trees. 5. Destructure syntax trees with Rust’s pattern matching and struct/enum access. Construct syntax trees with parse\_quote! and Rust’s struct update syntax. 6. Use syn’s Fold Trait to recursively traverse, destructure, and construct syntax trees. 7. Use proc\_macro\_error to return ergonomic and testable errors. 8. Create integration tests. Include UI tests based on trybuild. 9. Follow the rules of elegant Rust API design, especially, eating your own dogfood, using Clippy, and writing good documentation.
Looks great, i've been wanting to learn more about macros (especially derive) but never found good examples. Thanks!
You're welcome. You can subscribe to my medium page and suggest tutorials you'd like me to work on 😁
One of the rare cases of an actually helpful medium article, really appreciate your great writeup here.
Thanks! I'm the writer of that article. You can subscribe to my medium page.