Join Nostr
2025-06-10 14:05:12 UTC

Hemera :nixos: :ms_snow_leopard: on Nostr: Just ran into an interesting #cargo #rustlang workflow problem, that I am not sure ...

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