(Just want to make a note before this: this is my first RFC/Pre-RFC and I'm reasonably new to rust compiler dev in general, so please be patient but point out issues with this. Thanks!)
(also, if you have any more examples, please tell me, as I want to add more but can't think of any more)
- Feature Name:
same_crate_proc_macros
- Start Date: (fill me in with today's date, YYYY-MM-DD)
- RFC PR: rust-lang/rfcs#0000
- Rust Issue: rust-lang/rust#0000
Glossary
Same-crate proc macros: The subject of this RFC, proc macros that can be used in the same crate as where they're defined.
External proc macros: The current proc macros, where they are defined in a different or external crate as where they are used. This does not necessarily require the current system where the crate type has to be proc-macro
.
Summary
Add support for same-crate proc macros. My idea for how this could be implemented would involve compiling twice(with some caveats to hopefully provide similar performance as to currently).
Motivation
This could be quite useful in some scenarios and would likely increase usage of proc macros in the rust ecosystem. One example use case would be if you are, for example, implementing the API for OpenGL or a similar library in rust. In this scenario, you may want a proc macro that can take in the exact C code and convert it into valid rust enums or the such. This is of course a very specific scenario, but this still applies for other scenarios as well.
Guide-level explanation
(see the glossary for terms)
Same-crate proc macros are pretty easy to think about, as they're just a type of proc macro that can be used in the same crate as where they're defined. Internally, when compiling, more happens then when using external proc macros, as the crate is compiled twice, however they have similar compilation performance to external proc macros as each function is still only compiled once. This doesn't really affect readability, as the only change is that, for example, a crate my_cool_library_proc
and my_cool_library
could be merged.
Reference-level explanation
Internally, the compilers flow(or possibly cargo's? unsure) would be altered by inserting two steps: The first would be somewhere before codegen, but after parsing. I only have a high level overview of the compiler's flow so at the moment that's the best level of granularity I can get. At this stage, if the crate uses same-crate proc macros, it would apply some form of filter to remove the code irrelevant to proc macros(including the actual proc macro usage), while saving this code for later. It would also set a special flag, before continuing to compile to a dynamic library for usage as a proc macro as usual. After it actually generates the dynamic library however, it would then jump back and add the code saved before back, while removing the definitions of the proc macros. It would then compile again as the format the user wants after applying the proc macros. I'm unsure about what level of changes to the compiler it would require, or if there are any corner cases.
Drawbacks
This would require some major changes to the compiler and a significant amount of work in testing to ensure this wouldn't break anything major. Other then that, I don't think there would be many hiccups on the user's end.
Rationale and alternatives
I have no clue if this design/implementation would work the best, this is simply what I came up with. There may be better ways to implement this. However, this design would likely work, and it shouldn't cause many regressions. This wouldn't be able to be implemented as a library or macro as that would require many other language features be implemented so that you could implement functions for another crate, which needless to say would be a bad idea and could lead to bad situations.
Prior art
I don't think there's much prior art, as rust's proc macros are pretty unique.
Unresolved questions
Related issues that are yet out of scope include rust-lang/rust#130856. How this is implemented may be changed before this is merged, but as far as I can tell not much would need to be changed before stabilization if this gets merged.
Future possibilities
I don't feel there are many future possibilities for this, but this could bring more attention to proc macros in general and lead to more work on the previously mentioned rust-lang/rust#130856.