Is it documented that Cargo can download and bundle multiple versions of the same crate?

落花浮王杯 提交于 2020-01-13 16:22:10

问题


By forking and playing with some code, I noticed that Cargo can download and bundle multiple versions of the same crate in the same project (native-tls 0.1.5 and 0.2.1, for example). I have wasted so much time by looking at the documentation of the wrong version.

I have looked for some information about this behaviour but I was not able to find anything. Is this documented somewhere?

Is there an easy way to determine/detect the version used by the code you're working on (current edited file)? Or can we tell Cargo to show some warnings/prevent the build if two versions the same crate are required?


回答1:


Cargo can indeed link multiple versions of some crate, but only one of those versions can be a direct dependency. The others are indirect references.

The direct reference is always the version referenced by Cargo.toml and on top-level of Cargo.lock (while the indirect references are in the dependencies subsections).

I am not sure how much it is documented, unfortunately.




回答2:


It was a conscious decision when designing Rust to allow multiple versions of the same crate.

You have probably heard of Dependency Hell before, which occurs when 2 (or more) dependencies A and B have a common dependency C but each require a version which is incompatible with the other.

Rust was designed to ensure that this would not be an issue.

In general, cargo will attempt to find a common version which satisfies all requirements. As long as crate authors use SemVer correctly, and the requirements give enough leeway, a single version of the dependency can be computed and used successfully.

Sometimes, however, multiple versions of the same dependency are necessary, such as in your case since 0.1.x and 0.2.x are considered two different major versions. In this case, Rust has two features to allow the two versions to be used within the same binary:

  • a unique hash per version is appended to each symbol.
  • the type system considers the same type Foo from two versions of C to be different types.

There is a limitation, of course. If a function of A returns an instance of C::Foo and you attempt to pass it to a function of B, the compiler will refuse it (it considers the two types to be different). This is an intractable problem1.

Anytime the dependency on C is internal, or the use of C is isolated, it otherwise works automatically. As your experience shows, it is so seamless that the user may not even realize it is happening.

1See the dtolnay trick that crate authors can use to allow some types to be interchangeable.



来源:https://stackoverflow.com/questions/51714866/is-it-documented-that-cargo-can-download-and-bundle-multiple-versions-of-the-sam

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!