Just ran into an interesting #cargo #rustlang workflow problem, that I am not sure how it is best avoided?
A project I work on is depending on strum
and strum_macros
. Due to a cargo update
multiple strum
versions now got unified, and only a single version is built. That's good.
A dependency I was using had a pattern as such:
use strum::EnumMessage;
use strum_macros::EnumMessage;
Which is totally fine!
With the unification, the features now also got unified. Which in this case meant that EnumMessage
is now present in the macro-scope in both strum
and strum_macros
.
Which means the above two lines cause an error with EnumMessage
being imported twice! Fun.
So the situation is that strum
is fine, as it is an additive feature. And the dependency is fine as well, as it itself doesn't use the 'derive' feature.
Another reason why this happens seems to be because we are using cargo-hakari
to have less cache-misses in our workspace. But once our workspace-hack crate added the derive feature it broke the build.
The final piece seems that a transitive dependency both:
- Had the
derive
feature of strum enabled - Did a 0.x.y release (aka minor? patch?) that had a major update of its dependencies in it. (i.e. 0.26 -> 0.27)
- Is a proc-macro ? (potentially irrelevant, potentially the missing piece)
So to me the full reproduction would be:
- Have a dependency tree that contains both
foo v0.1 (derive feature)
and foo v0.2 (no features)
cargo update
- It still builds
cargo hakari
adds for both 'normal' deps and 'build' deps foo v0.2 (derive feature)
- This causes cargo to unify
foo
for both normal builds and proc-macro builds - The build fails due to duplicate entries
It feels like the use of cargo-hakari
caused this situation, as without it, it would have been fine I guess? But adding a feature flag, shouldn't break downstream crates either
so bleh