Rust 版本

rust-version 字段是一个可选的键,用于告诉 cargo 你的软件包支持的 Rust 工具链版本。

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

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

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 指南

可修补

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

依赖项支持

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

设置和更新 Rust 版本

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

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

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

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

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

根据你的风险偏好,下一个最简单的方法是继续支持你的软件包的旧主要版本或次要版本,这些版本支持较旧的 Rust 版本。

选择支持的 Rust 版本

你的软件包的用户最有可能将其支持的 Rust 版本跟踪到:

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

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

示例版本策略

  • “N-2”,意思是“具有 2 个版本更新宽限期的最新版本”
  • 每个偶数版本,具有 2 个版本的更新宽限期
  • 本日历年中的每个版本,具有一年的更新宽限期

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

更新时间线

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

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

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

当允许偏离时,就会出现“足够合理的”放弃支持版本的问题。每个人都可以得出相当不同的理由;进行这种讨论可能会让相关方感到沮丧。这将削弱那些想要避免此类冲突的人的权力,对于新的或临时的贡献者来说尤其如此,他们要么觉得他们没有资格提出问题,要么认为冲突可能会损害他们的更改被合并的机会。

工作区中的多重策略

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

在特定 Rust 版本下验证特定软件包可能会变得复杂。诸如 cargo-hack 之类的工具可以提供帮助。

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

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

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

一个或多个策略

减轻支持较旧 Rust 版本的缺点的一种方法是将你的策略应用于你继续支持的软件包的较旧的主要版本或次要版本。你可能仍然需要一个策略来决定开发分支支持哪些 Rust 版本,以及这些主要版本或次要版本的发布分支支持哪些 Rust 版本。

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

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

支持旧版本是有成本的。此成本取决于软件包中 bug 的风险和影响,以及可以接受反向移植的内容。按需创建发布分支并将反向移植负担转移到社区是平衡此成本的方法。

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

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

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