为什么 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 (
libBase
): 一个核心库,提供线、矩形、多边形等基本类型
- geo-booleanop (
libExtension
):一个建立在地理类型之上的库,用一个新功能扩展它:一个新特征BooleanOp
具有类似 intersection/union/... 的功能,并针对来自地理类型的多边形类型实现。
- 任何将 geo-types 和 geo-booleanop 结合在一起以使用多边形的
BooleanOp
特性的用户包。
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}>`
这令人惊讶,因为:
- 根本不可能将 geo-booleanop v0.2.1 与 geo-types v0.5.0 结合使用,因为它们不兼容。
- 关于没有名为
union
的方法的错误令人困惑,因为用户代码所做的一切都正确地将 BooleanOp
特性引入范围,这应该为多边形提供准确的方法。
- 具有讽刺意味的是,编译器还输出一条警告,指出
BooleanOp
特征导入未使用。
我的问题是:
- 为什么
cargo build
不显示突出显示依赖项不兼容的编译错误?
- 如果这是设计使然,我们可以在 geo-booleanop 网站上做些什么来让我们的用户更容易理解这些问题吗?目前,他们根据编写的代码做所有正确的事情,将特征纳入范围,但编译器的行为就好像特征缺失一样——而实际上这是版本不匹配。我们可以在图书馆网站上强制执行更明确的错误吗?
详细信息以防万一:
BooleanOp
特征在其基础浮点类型 (see implementation) 中是通用的。这是不是导致问题的原因,因为在客户端代码像在其他编程语言中一样使用泛型之前,泛型不会被实例化?
- 这是复制客户端代码:main.rs and Cargo.toml。
我将你的场景总结如下:
- 你的 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-types
与 geo-booleanop
一起使用,
他们实际上可以独立工作。
为了清楚起见,我将这两个版本分别称为 geo_types_04
和 geo_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
调用的。
由于这个问题涉及到多个依赖关系,不知道应该从哪个方向去复现,希望可以结合具体的例子来提问。这个问题背后更普遍的模式是:有一个依赖链 user => libExtension => libBase
and libExtension
and libBase
are incompatible.
在我们无法完全理解的geo-booleanop project, we run into an interesting issue中。它涉及以下包的相互作用:
- geo-types (
libBase
): 一个核心库,提供线、矩形、多边形等基本类型 - geo-booleanop (
libExtension
):一个建立在地理类型之上的库,用一个新功能扩展它:一个新特征BooleanOp
具有类似 intersection/union/... 的功能,并针对来自地理类型的多边形类型实现。 - 任何将 geo-types 和 geo-booleanop 结合在一起以使用多边形的
BooleanOp
特性的用户包。
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}>`
这令人惊讶,因为:
- 根本不可能将 geo-booleanop v0.2.1 与 geo-types v0.5.0 结合使用,因为它们不兼容。
- 关于没有名为
union
的方法的错误令人困惑,因为用户代码所做的一切都正确地将BooleanOp
特性引入范围,这应该为多边形提供准确的方法。 - 具有讽刺意味的是,编译器还输出一条警告,指出
BooleanOp
特征导入未使用。
我的问题是:
- 为什么
cargo build
不显示突出显示依赖项不兼容的编译错误? - 如果这是设计使然,我们可以在 geo-booleanop 网站上做些什么来让我们的用户更容易理解这些问题吗?目前,他们根据编写的代码做所有正确的事情,将特征纳入范围,但编译器的行为就好像特征缺失一样——而实际上这是版本不匹配。我们可以在图书馆网站上强制执行更明确的错误吗?
详细信息以防万一:
BooleanOp
特征在其基础浮点类型 (see implementation) 中是通用的。这是不是导致问题的原因,因为在客户端代码像在其他编程语言中一样使用泛型之前,泛型不会被实例化?- 这是复制客户端代码:main.rs and Cargo.toml。
我将你的场景总结如下:
- 你的 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-types
与 geo-booleanop
一起使用,
他们实际上可以独立工作。
为了清楚起见,我将这两个版本分别称为 geo_types_04
和 geo_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
调用的。