# Associated Proc Macro Pattern
It's a common pattern to provide a `foo` crate with trait definitions, and `foo-derive` crate with a
proc-macro derive implementation. Typically, you want `foo` and `foo-derive` to be versioned in
lockstep, because derive crates like to use `#[doc(hidden)]` non-semver-guarded API. Usually, this
is solved by a `derive` feature, which makes `foo` depend on `foo-derive` with `=x.y.z` constraint.
This, however, is problematic for compile times! It means that compilation of `foo-derive` is
sequenced before compilation of `foo`. As `foo-derive` is a derive macro, it needs to parse the Rust
language. Rust is not a small language, so parsing it is fundamentally hard, and requires loads of
code to do correctly. So it takes some time to compile `foo-derive`. What's worse, while normally
Cargo pipelines compilation such that `.rmeta` files are all that's needed to unblock compilation of
dependent crates, for proc macros Cargo really needs to link the whole .so!
The bottom line, while
```toml
foo = { version = "x.y.z", features = ["derive"] }
```
is easy to explain and
works correctly, it could significantly reduce the amount of parallelism available during builds.
On the other hand, while
```toml
foo = { version = "x.y.z" }
foo-derive = { version = "x.y.z" }
```
provides better compilation time, it doesn't constrain `foo` and `foo-derive` to be the same
version.
The pattern in this crate shows how to add that constraint! We can use the following declaration of
dependencies in `foo`'s Cargo.toml:
```toml
[package]
name = "foo"
version = "1.2.3"
[dependencies]
foo-derive = { version = "=1.2.3", optional = true }
[target.'cfg(all(to_be, not(to_be)))'.dependencies] # <- the trick
foo-derive = { version = "=1.2.3" }
[features]
derive = ["dep:foo-derive"]
```
The trick is a target specific dependency with "impossible" cfg. This cfg is never true, so `foo`
never actually depends on `foo-derive` (unless the `derive` feature flag is enabled). Non the less,
be