cargo: Cargo is unable to resolve dependency versions

Problem Cargo is unable to select two versions of diesel as dependency of some crate.

error: failed to select a version for `diesel`.
    ... required by package `infer_schema_internals v1.3.0`
    ... which is depended on by `infer_schema_macros v1.3.0`
    ... which is depended on by `diesel_infer_schema v1.3.0`
    ... which is depended on by `diesel_tests v0.1.0 (/home/user/Docs/rust/diesel/diesel_tests)`
versions that meet the requirements `~1.3.0` are: 1.3.3, 1.3.2, 1.3.0

all possible versions conflict with previously selected packages.

  previously selected package `diesel v1.4.0`
    ... which is depended on by `diesel_demo_step_1_pg v0.1.0 (/home/user/Docs/rust/diesel/examples/postgres/getting_started_step_1)`

failed to select a version for `diesel` which could resolve this conflict

I’ve seen this working if the other version of diesel is 0.x, so this does not make any sense for me that a it is not possible to use two semver compatible versions at the same time as dependency if explicitly requested.

Detailed dependency situation: We have a workspace containing several crates. Most of them depend on diesel = "1.4.0". Additionally there is one crate (diesel_tests), that depends on diesel_infer_schema = "1.3.0". Internally diesel_infer_schema depends on diesel = "~1.3.0" which causes the version selection problem shown above.

Steps

  1. Clone diesel
  2. Change dir to /path/to/diesel_clone/diesel/
  3. Try to build diesel

Possible Solution(s) Cargo should be able to use 2 versions of the same dependency if requested explicitly even if there would be an semver compatible version if the versions are specified in a other way. (I.e. That should just work)

Notes

Output of cargo version:

  • cargo version: cargo 1.31.0 (339d9f9c8 2018-11-16)
  • rust: 1.31.0 (installed through rustup)
  • OS: ubuntu 18.10

cc @sgrif @killercup @Eijebong (That breaks our CI)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16 (15 by maintainers)

Commits related to this issue

Most upvoted comments

I don’t think a closed issue from three years ago is likely to be a good home for this discussion.

I do not have inside information, I was not around when this compromise was made. But as a current member of the cargo team, one of the places I’ve recently written up my understanding is: https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/Cargo.20and.20duplicating.20dependencies

If the cause of the arguments over versioning is MSRV tensions, then it is likely to be more productive to suggest changes that directly affect MSRV aware resolution.

Any RFC that allows multiple semver compatible versions will need to describe precisely when it will be allowed, when it will not be allowed, how the resolver will decide if it is allowed, how that decision will be made clear to the user who cares, and how a user would be able to control if it applies on a case-by-case basis. Resolution is already NP-complete so none of those questions are straightforward.

@weiznich

Let’s elaborate this in another way: I do not understand the reasoning behind that version resolution schema

Ah that’s just how Cargo has always worked. Cargo allows multiple major versions of a crate, but all selected versions of a crate must be semver-incompatible (e.g. can’t have 1.3.0 and 1.4.0 as they’re semver compatible).

There’s a whole bunch of reasoning behind why Cargo does this, but it’s probably a bit much to get in here. We’d like to change this, we just haven’t yet.

I just cannot come up with a reason why this may be a bad idea

One example is that if you’re using 1.3.0 and I’m using 1.4.0 and someone tries to use us both, they get compile errors that look obscure as opposed to a version resolution error. Instead we need to be using the same version to be used together.


@sgrif

Cargo should allow two different versions of this library to be used, shouldn’t it?

Yes, but only if they’re semver incompatible (and 1.3.0 and 1.4.0 are compatible, 1.4.0 wasn’t a breaking change relative to 1.3.0 semver-wise)

Looking in the Cargo.lock for crates.io, at the very top I see that we have aho-corasick 0.5.3 and 0.6.3.

That’s because Cargo’s interpretation of semver means that 0.5.x and 0.6.y are semver-incompatible. The 0.6 branch was a breaking change relative to the 0.5 branch.

The ~ requirement is indeed more strict than ^, but Cargo strongly discourages usage of any version requirement other than ^ unless you’re really sure you know what you’re doing