首页 > 解决方案 > 为什么 cargo build 不显示具有不兼容依赖项的编译错误?

问题描述

由于这个问题涉及多个依赖关系,我不确定从哪个方向寻找重现它,我希望可以根据具体示例询问它。这个问题背后的更一般的模式是:存在依赖链user => libExtension => libBase并且libExtensionlibBase兼容。

geo-booleanop项目中,我们遇到了一个我们无法完全理解的有趣问题。它涉及以下软件包的相互作用:

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

geo-booleanop 包尚未用于此更改,即,它仍然显式使用这些 pub 字段。当前,Cargo.tomlgeo-booleanop 指定geo-types = "0.4",并且尝试将其提升到 0.5 并cargo build在 geo-booleanop 内执行会导致在 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}>`

这令人惊讶,因为:


我的问题是:


详细信息以防万一:

标签: rustdependenciestraitsrust-cargo

解决方案


我将您的情况总结如下:

  • 您的 Cargo.toml 取决于geo-booleanop0.2.1 和geo-types0.5.0
  • geo-booleanop0.2.1 取决于geo-types0.4.x

如果您查看 Cargo.lock 文件,您会注意到有两个[[package]]条目 for geo-types,一个 for0.4.x和一个 for 0.5.0

当同一个项目的两个(传递)依赖需求不兼容时,cargo 实际上会尝试编译它们。Cargo 不会将间接依赖项暴露给您的 crate,因此 Cargo 会分别构建两个版本,就好像它们没有相同的 crate 名称一样。只要你不尝试使用geo-typeswith geo-booleanop,它们实际上可以独立工作。

为了清楚起见,我将这两个版本分别称为geo_types_04geo_types_05。geo-booleanop 适用于名为 的依赖项geo_types_04geo_types_04它不会暴露给您的 crate,因此您根本不需要关心是否geo_types_04使用。

只有当geo-booleanop公开一个接受/返回在geo_types_04. 然后你假设它是geo_types_05,导致不兼容。

这次您的错误实际上是更具可读性的错误之一。有时您会遇到错误,例如Expected geo_types::Line, got geo_types::Line因为接受的函数geo_types_04::Line是用geo_types_05::Line.


推荐阅读