3

I have two crates X and Z and I want to use both but X depends on Z of on some specific version. For example, mongodb depends on tokio 0.2 and I was using tokio 0.3.

X does not re-export Z so I (think) have to manually specify Z in Cargo.toml. If I specify the wrong version, it might break. How can I tell cargo to use whatever version of Z that X requires?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
너를 속였다
  • 899
  • 11
  • 26
  • If `X` requires you to use the right version of `Z` to interoperate correctly, it needs to provide you with the means to do so, which _could_ mean that it should simply re-export the version of `Z` it's using, but it could also mean that it provides an interface that encapsulates the bits from `Z` it's using. If `X` doesn't do this, I'd consider that a bug. – Sven Marnach Aug 19 '20 at 07:51
  • 1
    See also [How do I use a crate from another crate without explicitly defining a new dependency in my project?](https://stackoverflow.com/q/44876113/155423); [Can I force the use of my dependencies' Cargo.lock when resolving package versions?](https://stackoverflow.com/q/49723779/155423); [Set specific version of the dependency of a project's dependency in Cargo.toml or Cargo.lock](https://stackoverflow.com/q/27770031/155423) – Shepmaster Aug 19 '20 at 13:22

1 Answers1

2

Cargo has some automatic dependency version resolution capability. You should be able to specify whatever version requirements of Z you need, and cargo will figure out how to choose the correct version to (potentially) use in both your code and X. This is assuming both crates correctly use semantic versioning.

If X doesn't expose Z in any way, you don't really need to use the same version of Z. If you use a different major version of Z than X, Cargo will just use both versions of Z, once for you and once for X.

See alexcrichton's comments on this for a little bit more detail.

Emoun
  • 2,297
  • 1
  • 13
  • 20
  • 1
    Using `Z = "*"` will tell Cargo to select the version of `Z` itself. If `X` is the only other crate in your dependency tree depending on `Z`, this will indeed lead to Cargo selecting the same version of `Z` that `X` depends on. If there are other crates depending on other versions of `Z`, you will lose that guarantee, though, so this isn't really a solution. – Sven Marnach Aug 19 '20 at 09:26
  • @SvenMarnach Yes, since there is no real way to 100% guarantee that you use the same version as `X` and no other, better just let Cargo handle it. It should be able to make it work, unless the crates don't follow semantic versioning. – Emoun Aug 19 '20 at 09:43
  • That's simply not true. Even if all crates in your dependency tree use semantic versioning correctly, there is still no way for Cargo to know that you actually want the version of `Z` used by dependency `X`, rather than the version of `X` used by dependency `Y`, since there is no way to tell Cargo that's what you want. – Sven Marnach Aug 19 '20 at 09:46
  • 1
    What I'm trying to say is that you shouldn't be hung up on what version `X` uses if it doesn't expose it anyway. Just use whatever version of `Z` you need in your code and cargo will give `X` whatever version of `Z` it needs. If there happens to exist a version that you can both use, yay, you both get it. If not, no problem, the crate is compiled twice, once for you and once for `X`. – Emoun Aug 19 '20 at 09:50
  • 1
    But the crate is not just compiled twice, you get all of its runtime resources twice as well, right? E.g. if `Z` creates a thread pool or a logger, you'll end up with two distinct thread pools or loggers or whatever. Things will still work if `Z` is correctly written, but it's not like there will be no run-time cost to pay, nor that the cost will be completely invisible. Am I mistaken? – user4815162342 Aug 19 '20 at 11:48
  • Yes, I would assume so. At that point each version of the crate is treated as a distinct entity by the compiler, and so might as well be different crates altogether. E.g., say you have a type `Z::SomeType`, the compiler would not regard one from the first version as the same type as one from the second version. – Emoun Aug 19 '20 at 13:15