Idea: Pre-expanded crates and `expansion-dependencies`

Currently procedure macro is used as a dependency of the downstream crate, So when the downstream crate is compiled, the macros got expanded on the fly during compilation.

I'm thinking maybe it's possible to add a new kind of dependency in Cargo.toml, maybe call it [expansion-dependencies], that acts just as normal dependencies. But instead, before uploading to crates.io, the proc macros defined in these crates got expanded and inlining the expansion results into the original source code. Only the expanded source code is uploaded to crates.io, and the dependency got automatically removed.

The benefits is much shorter compilation time.

The cons is the implementation complexity. Also when inlining, span info is removed, so the generated code has to use the current crate edition.

It’s very common for proc-macros to rely on an exact version of their runtime crate by using non-public semver exempt details from them. Pre-expanding would then extend this exact version requirement to the published crate, likely causing many unresolveable dependency trees.

See recent discussion here:

@Nemo157 Right, but then a proc macro crate can declare itself as able to be pre-expanded or not. For crates like thiserror and displaydoc, i think they're perfectly fittable for such pre-expansion.

@djc Thanks for the pointer! Indeed the motivation is exactly the same, however that topic has a slightly wrong title, which leads to people start talking about the implementation of pre-compiled proc macro crates themselves. It also defaulted to all proc_macros, and as @Nemo157 pointed out above, it's not possible in many cases.

Let's continue the discussion in that topic.