-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
Hello,
I was reading about proc_macros and the book currently uses two crates. To quote from the macro chapter:
Our two crates are tightly related, so we create the procedural macro crate within the directory of our hello_macro crate. If we change the trait definition in hello_macro, we’ll have to change the implementation of the procedural macro in hello_macro_derive as well. The two crates will need to be published separately, and programmers using these crates will need to add both as dependencies and bring them both into scope. We could instead have the hello_macro crate use hello_macro_derive as a dependency and reexport the procedural macro code. But the way we’ve structured the project makes it possible for programmers to use hello_macro even if they don’t want the derive functionality.
We need to declare the hello_macro_derive crate as a procedural macro crate. We’ll also need functionality from the syn and quote crates, as you’ll see in a moment, so we need to add them as dependencies. Add the following to the Cargo.toml file for hello_macro_derive:
Later on we also see:
[dependencies]
hello_macro = { path = "../hello_macro" }
hello_macro_derive = { path = "../hello_macro/hello_macro_derive" }The part with bold actually contains some crucial information that's easily lost. Without it it looks like proc_macros are kind of a hack and if used will force your library to be proc_macro only.
Already they aren't super straight-forward to use since they require the whole extern proc_macro magic, but I think we should do this example the other way around (make hello_crate depend on an internal hello_macro_derive and re-export the proc_macros from it).
We can mention that they can be two crates if needed, but that's already kind of an option that exists and is sort-of-known.
As someone who wanted to add proc_macro functionality to an existing crate that exported macros, it was really hard to find that crucial part of information that you can reexport proc_macros from crates that aren't using:
[lib]
proc-macro = true
The choice of splitting doesn't go into enough details as to why this option would be preferred vs just re-exporting the proc_macros:
Do proc_macros generate a significantly larger binary?
Are there other downsides?
If people don't want to use some functionality from a crate, they always have the option to not call/import that part of the functionality so the reasoning in this sentence is a bit strange and looks like it misses something: But the way we’ve structured the project makes it possible for programmers to use hello_macro even if they don’t want the derive functionality.
I am well aware that I'm quite new when it comes to advanced features and one data point from some evening coder (me) is not representative , but I've read this chapter at least three times, and I still opened this issue for my crate, not realizing that they can be re-exported: AlexEne/rust_hawktracer#9