Rust 版本

rust-version 字段是一个可选的键,它告诉 Cargo 你的包支持哪个版本的 Rust 工具链。

[package]
# ...
rust-version = "1.56"

Rust 版本必须是一个至少包含一个组成部分的纯版本号;它不能包含语义版本运算符或预发布标识符。在检查 Rust 版本时,编译器预发布标识符(例如 -nightly)将被忽略。

MSRV: 自 1.56 版本起生效

用途

诊断

当你的包在不受支持的工具链上编译时,Cargo 将提供更清晰的关于工具链版本不足的诊断信息,而不是报告标准库中的无效语法或缺失功能。这会影响包中的所有 Cargo 目标,包括二进制文件、示例、测试套件、基准测试等。

开发辅助

cargo add 将自动选择依赖项的版本要求,使其与你的 rust-version 兼容的最新版本。如果它不是最新版本,cargo add 将通知用户,以便他们可以选择是保留它还是更新你的 rust-version

当选择依赖项时,解析器可能会考虑 Rust 版本。

其他工具也可能会利用它,例如 cargo clippyincompatible_msrv lint

注意: 可以使用 --ignore-rust-version 选项忽略 rust-version

支持期望

这些是一般期望;某些包可能会记录它们何时不遵循这些期望。

完整

所有功能,包括二进制文件和 API,都可以在每个 feature 下受支持的 Rust 版本上使用。

已验证

包的功能在其受支持的 Rust 版本上经过验证,包括自动化测试。另请参阅我们的 Rust 版本 CI 指南

可修补

当许可证允许时,用户可以使用你的包的分支 覆盖他们的本地依赖项。在这种情况下,Cargo 可能会为修补的依赖项加载整个工作区,该工作区应在受支持的 Rust 版本上工作,即使工作区中的其他包具有不同的受支持 Rust 版本。

依赖项支持

为了支持上述内容,预计每个依赖项的版本要求都支持至少一个与你的 rust-version 兼容的版本。但是,期望依赖项规范排除与你的 rust-version 不兼容的版本。事实上,同时支持两者可以让你平衡支持较旧 Rust 版本和不支持较旧 Rust 版本的用户的需求。

设置和更新 Rust 版本

要支持哪些 Rust 版本是在以下方面之间进行权衡:

  • 维护者不使用 Rust 工具链或其依赖项的较新功能的成本
  • 用户从包使用工具链的较新功能中受益的成本,例如,通过从 polyfill 迁移到标准库中的功能来减少构建时间
  • 包对支持较旧 Rust 版本的用户的可用性

注意: 更改 rust-version 被认为是次要的不兼容性

建议: 选择一个关于支持哪些 Rust 版本以及何时更改该版本的策略,以便用户可以将其与他们自己的策略进行比较,如果它不兼容,则可以决定是否可以接受一般改进的损失或不修复阻塞错误的风险。

最简单的支持策略是始终使用最新的 Rust 版本。

根据你的风险情况,下一个最简单的方法是继续支持支持较旧 Rust 版本的包的旧的主要或次要版本。

选择支持的 Rust 版本

你的包的用户很可能将其支持的 Rust 版本跟踪到

  • 他们的 Rust 工具链供应商的支持策略,例如 Rust 项目或 Linux 发行版
    • 注意:Rust 项目仅为最新版本提供错误修复和安全更新。
  • 用户使用新工具链重新验证其包的固定时间表,例如,每年的第一个版本

此外,用户不太可能立即使用新的 Rust 版本,而是需要时间来注意和重新验证,或者可能没有完全相同的计划。

示例版本策略

  • “N-2”,表示“最新版本,带有 2 个版本更新的宽限期”
  • 每个偶数版本,带有 2 个版本更新的宽限期
  • 今年每个版本,带有一年的更新宽限期

注意: 要查找与你的项目当前状态兼容的最小 rust-version,你可以使用第三方工具,例如 cargo-msrv

更新时间线

当你的策略指定你不再需要支持 Rust 版本时,你可以立即或在需要时更新 rust-version

通过允许 rust-version 偏离你的策略,你可以为用户提供更多的升级宽限期。但是,这太不可预测了,不能依赖它与用户跟踪的 Rust 版本保持一致。

rust-version 偏离你指定的策略越远,用户就越有可能推断出你没有打算的策略,从而导致对未满足的期望感到沮丧。

当允许漂移时,会出现一个问题,即什么足以“合理”地放弃支持的版本。每个人都可以得出合理的不同理由;解决该讨论可能会使相关方感到沮丧。这将削弱那些希望避免此类冲突的人,对于那些觉得他们没有资格提出问题或者认为冲突可能会损害他们的更改被合并机会的新贡献者或临时贡献者来说尤其如此。

工作区中的多个策略

Cargo 允许在一个工作区内支持多个策略。

验证特定 Rust 版本下的特定包可能会变得复杂。像 cargo-hack 这样的工具可以提供帮助。

对于跨策略共享的任何依赖项,必须使用最低的通用版本,因为 Cargo 统一了语义版本兼容的版本,这可能会限制工作区成员使用较高 rust-version 的共享依赖项的功能。

为了允许用户修补你的工作区成员之一的依赖项,工作区中的每个包都需要在工作区支持的最旧的 Rust 版本中加载。

当使用 incompatible-rust-versions = "fallback" 时,一个包的 Rust 版本可能会影响为另一个具有不同 Rust 版本的包选择的依赖项版本。有关更多详细信息,请参见解析器章节。

一个或多个策略

缓解支持较旧 Rust 版本缺点的另一种方法是将你的策略应用于你继续支持的包的旧主要或次要版本。你可能仍然需要一个策略,用于确定与这些主要或次要版本的发布分支相比,开发分支支持哪些 Rust 版本。

仅在“需要”时更新开发分支可以帮助减少支持的发布分支的数量。

存在可以将哪些内容向后移植到这些发布分支中的问题。通过在次要版本之间向后移植新功能,下一个可用版本将缺少它,这可能被认为是破坏性更改,违反了语义版本控制。向后移植更改还存在引入错误的风险。

支持较旧的版本是有代价的。此成本取决于包中错误的风险和影响以及可以接受的向后移植内容。按需创建发布分支并将向后移植的负担放在社区上是平衡此成本的方法。

依赖项管理工具尚无法报告仍支持非最新版本,从而将责任转移给用户以在文档中注意到这一点。

例如,Rust 版本支持策略可能如下所示:

  • 开发分支跟踪 Rust 项目的最新稳定版本,并在需要时更新
    • 更改 rust-version 时将提高次要版本
  • 该项目支持今年的每个版本,并提供另一年的宽限期
    • 支持受支持的 Rust 版本的最后一个次要版本将收到社区提供的错误修复
    • 修复程序必须向后移植到开发分支和所需的支持 Rust 版本之间的所有受支持的次要版本