第41章 Cargo Fix:自动修复 Rust 代码的 Lint 警告
名称
cargo fix — 自动修复 rustc 报告的 lint 警告
用法
cargo fix [options]
描述
此 Cargo 子命令会自动获取 rustc 在诊断信息(如警告)中提供的修复建议,并将其应用到源代码中。其目的是自动化那些 rustc 本身已经知道如何修复的任务。
执行 cargo fix 时,底层会运行 cargo-check(1)。适用于当前 crate 的警告会被自动修复(如果可能),检查过程结束后会显示所有剩余的警告。例如,若要应用当前包的所有修复,可以运行:
cargo fix
这与 cargo check --all-targets 的行为相同。
cargo fix 只能修复通过 cargo check 正常编译的代码。如果代码是通过可选特性有条件启用的,需要启用这些特性才能分析该代码:
cargo fix --features foo
类似地,其他 cfg 表达式(如平台特定代码)需要通过 --target 指定目标平台来修复代码。
cargo fix --target x86_64-pc-windows-gnu
如果在 cargo fix 方面遇到任何问题,或有其他疑问或功能请求,请随时在 https://github.com/rust-lang/cargo 上提交 issue。
版本迁移
cargo fix 子命令还可用于将包从一个版本迁移到下一个。一般流程如下:
- 运行
cargo fix --edition。如果项目有多个特性,可以考虑同时使用--all-features标志。如果项目有由cfg属性控制的平台特定代码,可能需要使用不同的--target标志多次运行cargo fix --edition。 - 修改
Cargo.toml,将版本字段设置为新版本。 - 运行项目测试,确认一切正常。如果出现了新的警告,可以考虑再次运行
cargo fix(不带--edition标志),应用编译器给出的建议。
希望到这里就大功告成了!不过请记住上面提到的注意事项:cargo fix 无法更新未启用的特性(feature)或 cfg 表达式涉及的代码。此外,在少数情况下,编译器无法自动迁移所有代码,改用新 edition 构建后可能还需要手动修改。
OPTIONS
Fix 选项
--broken-code-
即使代码本身已有编译错误也进行修复。当
cargo fix无法应用更改时,这个选项很有用:它会照常应用更改,并把有问题的代码留在工作目录中,供你检查和手动修复。 --edition-
应用将代码迁移到下一个 edition 所需的更改。注意它不会更新
Cargo.toml中的 edition 字段,需要在cargo fix --edition完成后手动修改。 --edition-idioms-
应用相关建议,将代码更新为当前 edition 的推荐写法。
--allow-no-vcs-
即使未检测到 VCS 也进行修复。
--allow-dirty-
即使工作目录有未提交的更改(包括已暂存的更改)也进行修复。
--allow-staged-
即使工作区存在已暂存的更改,也修复代码。
包选择
如果未指定任何包选择选项,选中的包取决于所选的 manifest 文件(若未指定 --manifest-path,则基于当前工作目录)。如果该 manifest 是 workspace 的根目录,则选择 workspace 的默认成员;否则仅选择该 manifest 定义的包。
可以通过根 manifest 中的 workspace.default-members 键显式设置 workspace 的默认成员。如果未设置,virtual workspace 将包含所有 workspace 成员(等效于传入 --workspace),而 non-virtual workspace 仅包含根 crate 本身。
-pspec…--packagespec…-
仅修复指定的包。SPEC 格式参见 cargo-pkgid(1)。此标志可以指定多次,支持
*、?和[]等常见 Unix glob 模式。但为了避免 shell 在 Cargo 处理之前意外展开 glob 模式,必须将每个模式用单引号或双引号包裹。 --workspace-
修复 workspace 中的所有成员。
--all-
--workspace的已弃用别名。 --excludeSPEC…-
排除指定的包。必须配合
--workspace标志使用。该标志可多次指定,并支持常见的 Unix glob 模式,例如*、?和[]。为防止 shell 在 Cargo 处理之前意外展开 glob 模式,务必使用单引号或双引号将每个模式包围。
目标选择
若未指定目标选择选项,cargo fix 将修复所有目标(即隐含了 --all-targets)。如果二进制目标缺失其 required-features,则会被跳过。
传入目标选择标志后,将仅修复指定的目标。
注意,--bin、--example、--test 和 --bench 标志也支持常见的 Unix glob 模式,例如 *、? 和 []。为防止 shell 在 Cargo 处理之前意外展开 glob 模式,务必使用单引号或双引号将每个 glob 模式包围。
--lib-
修复该包的库。
--binname…-
修复指定的二进制文件。该标志可多次指定,并支持常见的 Unix glob 模式。
--bins-
修复所有二进制目标。
--examplename…-
修复指定的示例。该标志可多次指定,并支持常见的 Unix glob 模式。
--examples-
修复所有示例目标。
--testname…-
修复指定的集成测试。此标志可多次指定,并支持常见的 Unix glob 模式。
--tests-
修复所有在 manifest 中设置了
test = true的目标。默认包括以 unittest 形式构建的库和二进制文件,以及集成测试。注意这也会构建所需的依赖项,因此 lib 目标可能被构建两次(一次作为 unittest,一次作为二进制文件、集成测试等的依赖)。可以通过在 manifest 中设置目标的test标志来启用或禁用目标。 --benchname…-
修复指定的基准测试。此标志可多次指定,并支持常见的 Unix glob 模式。
--benches-
修复所有在 manifest 中设置了
bench = true的目标。默认包括以 benchmark 形式构建的库和二进制文件,以及 bench 目标。注意这也会构建所需的依赖项,因此 lib 目标可能被构建两次(一次作为 benchmark,一次作为二进制文件、基准测试等的依赖)。可以通过在 manifest 中设置目标的bench标志来启用或禁用目标。 --all-targets-
修复所有目标。等同于同时指定
--lib --bins --tests --benches --examples。
Feature 选择
feature 标志用于控制启用哪些 feature。未提供 feature 选项时,所有选中的包都会激活 default feature。
详情请参阅 feature 文档。
-Ffeatures--featuresfeatures-
要激活的 feature 列表,以空格或逗号分隔。workspace 成员包的 feature 可以使用
package-name/feature-name语法启用。此标志可指定多次,会激活所有列出的 feature。 --all-features-
激活所有选中包的全部可用 feature。
--no-default-features-
不激活所选包的
defaultfeature。
编译选项
--targettriple-
针对指定目标架构执行修复。此标志可指定多次,默认值为宿主架构。triple 的通用格式为
<arch><sub>-<vendor>-<sys>-<abi>。可选值:
rustc --print target-list中支持的任何目标。"host-tuple",将在内部替换为宿主目标。在交叉编译部分 crate 时特别有用,例如不想将宿主机器指定为目标时(比如许多宿主都可能参与的共享项目中的xtask)。- 自定义 target specification 的路径。更多信息参见Custom Target Lookup Path。
也可以通过
build.targetconfig 值指定。指定该标志会使 Cargo 以不同模式运行,target 产物将被放置到单独的目录中。更多细节参见build cache 文档。
-r--release-
修复使用
releaseprofile 的优化产物。还可以使用--profile选项按名称选择特定 profile。 --profilename-
使用指定的 profile 进行修复。
作为一种特殊情况,指定
testprofile 还会启用测试模式检查,这会启用测试检查并激活testcfg 选项。更多细节参见rustc 测试。关于 profile 的更多细节,参见参考文档。
--timings-
输出每次编译的耗时信息,并跟踪随时间变化的并发信息。
构建结束后,文件
cargo-timing.html将被写入target/cargo-timings目录。如果你想查看之前的运行,还会生成一个文件名中包含时间戳的额外报告。这些报告仅适合人工阅读,不提供机器可读的耗时数据。
Output Options
--target-dirdirectory-
指定所有生成产物和中间文件的存放目录。也可以通过
CARGO_TARGET_DIR环境变量或build.target-dir配置项 来设置。默认为 workspace 根目录下的target。
显示选项
-v--verbose-
使用详细输出。指定两次可获得“非常详细”的输出,包含依赖警告和构建脚本输出等额外信息。也可以通过
term.verbose配置项 来设置。 -q--quiet-
不打印 cargo 日志信息。也可以通过
term.quiet配置项 来设置。 --colorwhen-
控制何时使用彩色输出。有效取值:
auto(默认):自动检测终端是否支持彩色输出。always:始终显示颜色。never:从不显示颜色。
也可以通过
term.color配置项 来设置。 --message-formatfmt-
诊断信息的输出格式。该选项可多次指定,值为逗号分隔列表。有效值如下:
human(默认):以人类可读的文本格式显示。与short和json冲突。short:输出简短的人类可读文本信息。与human和json冲突。json:向 stdout 输出 JSON 消息。更多详情请参见参考文档。与human和short冲突。json-diagnostic-short:确保 JSON 消息中的rendered字段包含 rustc 的“short”渲染结果。不能与human或short一起使用。json-diagnostic-rendered-ansi:确保 JSON 消息中的rendered字段包含嵌入式 ANSI 颜色代码,以遵循 rustc 的默认配色方案。不能与human或short一起使用。json-render-diagnostics:指示 Cargo 不要在输出的 JSON 消息中包含 rustc 的诊断信息,而是由 Cargo 自身渲染来自 rustc 的 JSON 诊断信息。Cargo 自身的 JSON 诊断信息以及来自 rustc 的其他信息仍会输出。不能与human或short一起使用。
Manifest Options
--manifest-pathpath-
Cargo.toml文件的路径。默认情况下,Cargo 会在当前目录或其父目录中查找Cargo.toml文件。 --ignore-rust-version-
忽略包中的
rust-version配置。 --locked-
断言使用的依赖项及其版本与最初生成现有
Cargo.lock文件时完全一致。若出现以下任一情况,Cargo 将报错退出:- 锁文件缺失。
- 由于依赖项解析结果不同,Cargo 试图修改锁文件。
该选项适用于需要确定性构建的环境,例如 CI 流水线。
--offline-
禁止 Cargo 出于任何原因访问网络。若未指定此标志,当 Cargo 需要访问网络但网络不可用时,它会停止并报错。指定此标志后,Cargo 将尝试在无网络环境下继续执行。
请注意,这可能导致与在线模式不同的依赖项解析结果。Cargo 将仅限于使用本地已下载的 crate,即使本地索引副本中显示存在更新的版本。请先使用 cargo-fetch(1) 命令下载依赖项,然后再进入离线模式。
也可通过
net.offline配置项 指定。 --frozen-
等效于同时指定
--locked和--offline。
通用选项
+toolchain-
如果 Cargo 是通过 rustup 安装的,且
cargo的第一个参数以+开头,该参数将被解释为 rustup 工具链名称(例如+stable或+nightly)。有关工具链覆盖机制的更多信息,请参阅 rustup 文档。 --configKEY=VALUE 或 PATH-
覆盖 Cargo 的配置项。参数应为 TOML 语法的
KEY=VALUE,或一个额外配置文件的路径。此标志可多次指定。详见命令行覆盖一节。 -CPATH-
在执行任何指定操作前先切换当前工作目录。这会影响 Cargo 默认查找项目清单(
Cargo.toml)的位置,以及搜索.cargo/config.toml的目录等。此选项必须放在命令名之前,例如cargo -C path/to/my-project build。此选项仅在 nightly channel 上可用,且需要
-Z unstable-options标志来启用(参见 #10098)。 -h--help-
打印帮助信息。
-Zflag-
Cargo 的不稳定(仅 nightly)标志。运行
cargo -Z help查看详情。
其他选项
-jN--jobsN-
并行任务数量。也可通过
build.jobs配置项 指定。默认值等于逻辑 CPU 数量。如果传入负数,则将最大并行任务数设为逻辑 CPU 数量加上该值。如果传入字符串default,则重置为默认值。不能为 0。 --keep-going-
尽可能构建依赖图中的所有 crate,而不是在第一个构建失败时中止整个过程。
例如,如果当前包依赖
fails和works这两个 crate,且其中一个构建失败,那么cargo fix -j1可能构建也可能不构建成功的那个(取决于 Cargo 选择先运行哪一个),而cargo fix -j1 --keep-going则肯定会运行两个构建任务,即使先执行的那个失败了。
环境变量
关于 Cargo 读取的环境变量详情,请参见 参考文档。
退出状态
0:Cargo 执行成功。101:Cargo 执行失败。
示例
-
将编译器建议应用于本地包:
cargo fix -
更新包以适配下一个版本(edition):
cargo fix --edition -
应用当前版本的惯用写法建议:
cargo fix --edition-idioms