What is the difference between a procedural macro and a compiler plugin?


The question is short and all in the title.
I’ve seen the procedural macro (proc_macro feature) and the compiler plugin (plugin feature) around the web. My question is if there is a real difference between this two feature, because at me seems like one is a slight modified clone of the other.

Other rustaceans say “Compiler plugins are from rust macro 1.0, procedural macro is the equivalent in the structure of macro 2.0”. It is true?


The very first line of the RFC seems to indicate that procedural macros and compiler plugins are effectively just different components of the same concept:

This RFC proposes an evolution of Rust’s procedural macro system (aka syntax extensions, aka compiler plugins).

My understanding is that in common vernacular, “procedural macro” is used in reference to custom_derive, and “compiler plugin” is used in reference to plugin. But both are subsets of the umbrella term “syntax extensions.” I could be wrong, but that’s how the conversations read to me.

And FWIW it looks like plugin is still maintained and very much on the path to stabilization. There’s even a well-written page in the unstable book with a demo plugin. In fact, plugin and custom_derive have quite different use cases and solve different problems.


But proc_macro (not custom_derive) act exactly like plugin, and it’s this “domain collision” who I don’t understand :confused:


They don’t necessarily have a “domain collision”. A proc macro is meant for manipulating a single function call or the code it annotates and each proc macro invocation is meant to be entirely independent from every other invocation.

On the other hand, looking at the lint example from the unstable book, I believe compiler plugins let you analyse an entire crate at a time and maintain state across passes. This would let you implement things like the test harness or some general “registry” so you can find all the places annotated with a particular attribute and then do something with that information.

For example, it’s not possible to implement your own test harness using just procedural macros and your own #[my_test] attribute. You should be able to implement this with compiler plugin though.


Actually, I’m pretty sure the biggest and most significant difference is that the proc macro API is on the RFC track, while the plugin API is not stable and never will be.


Thanks for the correction. :+1: This is good to know.