Description
In a dependency chain such that:
Library A is published up to 0.5
Library B depends on A = "=3.0"
Users application C depends on B = "*"
and A = "*"
Cargo chooses version 0.5 of A
for the downstream crate C
which means anything bound on traits from A=0.3
in B are not implemented for the types in use in the interaction between B
and C
. Which means things fail to compile with errors about trait Foo is not implemented for Bar
where they clearly are in the docs. The error messages given by rustc don't help a user realize that a version mismatch is the root cause in this scenario.
To get the downstream crate to build, we need to bound their A
dependency to use to the same version as B, or do a lot of re-exports from B
. This means that if B
updates their dependencies in future, downstream will have to update their Cargo.toml again to B
's version of A
. (This will require the user probably looking at B's Cargo.toml, or the Cargo.lock)
This feels like it will become a worse problem as we starting seeing more crates semver'ing which will involve locking dependency versions down to their own needs.
Should it be documented as a 'best practice' to do re-exports for everything that downstream crates may interact with?
Or, should we consider some kind of sugar version specification e.g. A = "B"
meaning use the same version of A
as B
does.
Concrete example here