为什么 cargo build 不显示具有不兼容依赖项的编译错误?

Why is cargo build not showing compilation errors with incompatible dependencies?

由于这个问题涉及到多个依赖关系,不知道应该从哪个方向去复现,希望可以结合具体的例子来提问。这个问题背后更普遍的模式是:有一个依赖链 user => libExtension => libBase and libExtension and libBase are incompatible.

在我们无法完全理解的geo-booleanop project, we run into an interesting issue中。它涉及以下包的相互作用:

geo-types 包最近从版本 0.4 到 0.5 发生了重大变化,例如,它将其 Rect 类型的某些字段从 pub 字段更改为 getters。

此更改尚未采用 geo-booleanop 包,即,它仍然显式使用这些 pub 字段。目前,geo-booleanop 的 Cargo.toml 指定了 geo-types = "0.4",并且尝试将其设置为 0.5 并在 geo-booleanop 中执行 cargo build 会导致 pub 字段访问中的编译器错误,如预期的那样。

现在令人惊讶的是:在创建结合了最新版本的 geo-types 和 geo-booleanop 的用户包时,我们在用户包中看到 cargo build 的以下输出:

$ cargo build
[...]
   Compiling geo-booleanop v0.2.1
   Compiling geo-types v0.5.0
[...]

error[E0599]: no method named `union` found for type `geo_types::polygon::Polygon<{float}>` in the current scope
  --> src/main.rs:21:23
   |
21 |     let union = poly1.union(&poly2);
   |                       ^^^^^ method not found in `geo_types::polygon::Polygon<{float}>`

这令人惊讶,因为:


我的问题是:


详细信息以防万一:

我将你的场景总结如下:

  • 你的 Cargo.toml 取决于 geo-booleanop 0.2.1 和 geo-types 0.5.0
  • geo-booleanop 0.2.1 取决于 geo-types 0.4.x

如果您查看 Cargo.lock 文件,您会注意到有两个 [[package]] 条目用于 geo-types,一个用于 0.4.x,一个用于 [=17] =].

当同一个项目的两个(传递的)依赖需求不兼容时, cargo 实际上试图编译 both 它们。 Cargo 不会将间接依赖项公开给您的箱子, 所以 Cargo 分别构建两个版本,就好像它们没有相同的板条箱名称一样。 只要您不尝试将 geo-typesgeo-booleanop 一起使用, 他们实际上可以独立工作。

为了清楚起见,我将这两个版本分别称为 geo_types_04geo_types_05。 geo-booleanop 处理名为 geo_types_04 的依赖项, geo_types_04 没有暴露在你的箱子里, 所以你根本不需要关心 geo_types_04 是否被使用。

只有当 geo-booleanop 公开 accepts/returns 在 geo_types_04 中定义的某种类型的函数时才会成为问题。 然后你假设它是 geo_types_05, 导致不兼容。

这次你的错误实际上是更易读的错误之一 ones.Sometimes 你会得到像 Expected geo_types::Line, got geo_types::Line 这样的错误,因为接受 geo_types_04::Line 的函数是用 geo_types_05::Line 调用的。