为何未在Cargo.toml中声明的crate导致项目编译失败?
为什么未在Cargo.toml中声明的pear_codegen会导致我的Rust项目编译失败?
问题描述
我尝试编译Rust项目时出现报错,报错信息显示一个未在我的Cargo.toml中声明的crate——pear_codegen编译失败。具体编译日志如下:
$ cargo build Downloading pear_codegen v0.0.16 Compiling pear_codegen v0.0.16 Compiling ring v0.11.0 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields --> /.cargo/registry/src/github.com-1ecc6299db9ec823/pear_codegen-0.0.16/src/lib.rs:317:9 | 317 | ExprKind::Block(block) => { | ^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 1 error: aborting due to previous error For more information about this error, try `rustc --explain E0023`. error: Could not compile `pear_codegen`. warning: build failed, waiting for other jobs to finish... error: build failed
问题原因
别疑惑为什么这个“陌生”的crate会搞砸你的编译——它是你项目间接依赖的包:Cargo会自动解析并拉取所有直接依赖的依赖(也就是依赖树里的所有节点),哪怕你没在自己的Cargo.toml里显式声明它。
而这次编译失败的核心是Rust版本兼容性冲突:pear_codegen v0.0.16是一个比较旧的版本,它依赖的syn(Rust常用的语法解析库)在旧版里的ExprKind::Block是单字段的变体,但在你当前使用的新版Rust对应的syn版本中,这个变体已经改成了双字段结构。旧版pear_codegen的代码没适配这个变化,所以触发了E0023模式匹配错误。
解决办法
这里有几个可行的修复方案,按优先级推荐:
- 升级间接依赖的源头:先找出哪个直接依赖用到了
pear_codegen,运行命令:
找到对应的直接依赖后,把它升级到最新版本(或者至少是适配新版Rust的版本)——新版本的依赖大概率会使用兼容当前Rust的cargo tree | grep pear_codegenpear_codegen版本,或者已经移除了这个依赖。 - 强制替换pear_codegen版本:如果暂时没法升级源头依赖,可以在你的
Cargo.toml里添加[patch.crates-io]区块,强制所有依赖使用兼容的pear_codegen版本:
注意:替换前要确认新版本的[patch.crates-io] pear_codegen = { version = "0.1.0" } # 选择一个支持新版Rust的版本,可在crates.io查看pear_codegen和你的依赖链兼容,可能需要测试验证。 - 临时降级Rust版本:这是权宜之计,如果你暂时不想调整依赖,可以用
rustup切换到pear_codegen v0.0.16支持的旧版Rust,比如:
但长期来看,还是建议升级依赖以跟上Rust的迭代。rustup override set 1.39.0
内容的提问来源于stack exchange,提问作者Jack Fraser
相关产品推荐
相关产品推荐

