EDIT: Credit to @jswrenn for suggesting a solution: have a particular version of zerocopy depend upon an exact version of zerocopy-derive. This should solve the problem.
I'm the author of zerocopy, which uses the zerocopy-derive proc macro crate to derive impls of some of its traits. I'm working on a refactor that will clean up zerocopy-derive's code and aims to make compilation faster. In particular, I'm trying to factor out some code which is independent of the type that the trait is derived on. Currently, this code is emitted once for every trait impl. I'd like to define this elsewhere in "normal" Rust code rather than in proc-macro-generated Rust code. That will allow me to define it once and then use it in each impl.
I first tried to put it in
zerocopy-derive itself, but apparently that's not supported:
error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]` --> src/lib.rs:30:1 | 30 | pub struct Foo; | ^^^^^^^^^^^^^^^
My next thought was to define it in
zerocopy itself, but this raises a semver problem. Currently,
zerocopy-derive's derive macros, and thus takes a dependency on
zerocopy-derive. This means that
zerocopy-derive cannot also take a dependency on
zerocopy - this would be a dependency cycle, which is disallowed.
zerocopy-derive taking an explicit dependency on
zerocopy, how do I ensure that the crate which uses the derive depends upon a version of
zerocopy which is recent enough that it has the features in question? If an older version of
zerocopy is used, the code emitted by
zerocopy-derive will fail to compile. Complicating matters further, if a newer version of
zerocopy is used which has made a breaking changes to these features, code emitted by
zerocopy-derive will fail to compile.
I genuinely can't figure out whether it's even possible - let alone possible cleanly and without massive headache - to solve the semver problem.
I also considered introducing a third
zerocopy-derive-utils crate which contains the features in question.
zerocopy-derive could then take a dependency on this crate, and semver should sort everything out as normal. This should work, but introduces a third crate, which is pretty suboptimal.
Anyone dealt with anything similar or have any advice?