Crate version incompatibility

Let's say I use crate A version 1.0 I depend Create B depend on create A version 0.2 I depend Create C depend on create A version 0.3

I am pretty much stuck, screwed! The current cargo does not provide any solution to this problem.

Is there anyway for me to specify: crate A, use version 1.0, for me, and all dependencies? If it does not compile, then boom, it won't work anyway. I am counting on my luck that it will work. Or maybe I am sure it will work. But Cargo does not give me a chance to try it at all.

Is it better to give me a way to specify a version, and I will take full responsibility of the compatibility?

I think this question could be a better fit on users.rust-lang.org, rather than the internals forum.

3 Likes

Can you build a reproducible example of the problem you're seeing? Cargo should have no trouble building 1.0 and 0.2 and 0.3 of the same crate into the same project.

4 Likes

The real problem is to use the same version, not get 3 versions into the lib.

Here is my problem: Let c = ClientBuilder::new(URI:::fromstr(“http://xxxx”)?); ClientBuilder is crate B requires a url of create http 0.2. And I am using http 1.0 The uri I passed to ClientBuilder is the wrong version. The error I throw away is will be the wrong version too.

There are a bunch of practical tools for dealing with this problem. Most of which are in the process of being improved.

Most crates re-export their public dependencies. This allows you to at least name the version of the transitive dependency that will work with the direct dependency.

This relies on people keeping track of which dependencies are part of the public API, it would be very convenient if you could record that in cargo.toml. Which is the public/private dependencies RFC. The original RFC had wanted the resolver to force picking the versions of your direct dependency is such that your transitive dependencies at the same version. This was very hard to implement, and prevented the other benefits we would get from that RFC. A new superseding RFC was just merged that does not affect the resolver.

Cargo can't automatically update your direct dependencies to have a different transitive dependency. Because the transitive dependency made a breaking change. It has told its users that they need to reevaluate their use of the API. Your direct dependencies need a human to evaluate what is involved in updating to the new version. If you would like to experiment with that you can pull their code and make the changes, then test them in your project either by using a git dependency or using the patch section to overrides the dependency. Both of which are intentionally designed to make it very easy for you to give your improvements back to the community.

I have some pipedreams about other tooling we should add to cargo.toml, but for now I mostly want to see how the community response to the tools that are already in the works.

1 Like

Overriding the version of a transitive dependency is a commonly requested option.

1 Like

This would be very useful. Several times I have had transitive dependencies in multiple versions, simply because of semver changes that didn't matter (because the functionality that broke semver wasn't used by my dependencies).

Being able to override that would be very useful. Another thing that would be useful is to be able to specify that my library is compatible with multiple different semver versions of a direct dependency. That would lessen the headache for any downstream consumer of my code.

1 Like

This you can already do. foo = ">2.0.0, <5.0.0", although cargo will try and provide you with the latest version even if that means more duplication in the tree.

Thanks, didn't know that. But if it doesn't make cargo unify versions it doesn't seem very useful currently. Maybe it will be good for the MSRV-aware resolver also being discussed currently.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.