Rust 1.84.0 版本发布

2025 年 1 月 9 日 · Rust 发布团队

Rust 团队很高兴地宣布 Rust 的新版本 1.84.0。Rust 是一种编程语言,旨在帮助每个人构建可靠且高效的软件。

如果您之前通过 rustup 安装了 Rust,您可以使用以下命令获取 1.84.0 版本:

$ rustup update stable

如果您还没有安装,您可以从我们网站上的相应页面获取 rustup,并查看1.84.0 版本的详细发布说明

如果您想通过测试未来的版本来帮助我们,您可以考虑在本地更新以使用 beta 频道 (rustup default beta) 或 nightly 频道 (rustup default nightly)。请报告您可能遇到的任何错误!

1.84.0 稳定版的新特性

Cargo 考虑 Rust 版本进行依赖版本选择

1.84.0 稳定了最小支持 Rust 版本 (MSRV) 感知解析器,该解析器优先选择与项目声明的 MSRV 兼容的依赖版本。通过 MSRV 感知版本选择,维护者无需手动为每个依赖选择旧版本,从而减少了支持旧工具链的工作量。

您可以通过 .cargo/config.toml 选择启用 MSRV 感知解析器

[resolver]
incompatible-rust-versions = "fallback"

然后在添加依赖项时

$ cargo add clap
    Updating crates.io index
warning: ignoring clap@4.5.23 (which requires rustc 1.74) to maintain demo's rust-version of 1.60
      Adding clap v4.0.32 to dependencies
    Updating crates.io index
     Locking 33 packages to latest Rust 1.60 compatible versions
      Adding clap v4.0.32 (available: v4.5.23, requires Rust 1.74)

在 CI 中验证最新依赖项时,您可以覆盖此设置

$ CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS=allow cargo update
    Updating crates.io index
     Locking 12 packages to latest compatible versions
    Updating clap v4.0.32 -> v4.5.23

您还可以通过在 Cargo.toml 清单文件中设置 package.resolver = "3" 来选择启用,但这将要求您将 MSRV 提升到 1.84。新的解析器将为使用 2024 Edition(将在 1.85 中稳定)的项目默认启用。

这为库作者在决定采用新的 Rust 工具链功能的策略时提供了更大的灵活性。以前,库采用来自新的 Rust 工具链的功能会迫使拥有旧 Rust 版本的下游用户升级他们的工具链,或者手动选择与他们的工具链兼容的旧库版本(并避免运行 cargo update)。现在,这些用户将能够自动使用与他们的旧工具链兼容的旧库版本。

有关在决定 MSRV 策略时的更多考虑因素,请参阅文档

迁移到新的 trait 解析器开始

Rust 编译器正在迁移到 trait 解析器的新实现。下一代 trait 解析器是对 Rust 类型系统核心组件的重新实现。它不仅负责检查 trait 约束(例如 Vec<T>: Clone)是否成立,还被类型系统的许多其他部分使用,例如规范化(找出 <Vec<T> as IntoIterator>::Item 的底层类型)和类型等价(检查 TU 是否相同)。

在 1.84 中,新的解析器用于检查 trait impl 的一致性。从高层次来看,一致性负责确保对于给定类型,trait 最多只有一个实现,同时考虑到来自其他 crate 的尚未编写或可见的代码。

此稳定化修复了旧实现的一些主要是理论上的正确性问题,导致可能出现以前未报告的“trait 的实现冲突...”错误。根据通过 Crater 对可用代码的评估,我们预计受影响的模式非常罕见。稳定化还提高了我们证明 impl 重叠的能力,从而在某些情况下允许编写更多代码。

有关更多详细信息,请参阅之前的博客文章稳定化报告

严格来源 API

在 Rust 中,指针不仅仅是一个“整数”或“地址”。例如,即使您“幸运地”在您的读/写之前释放的内存被重新分配,“use after free”(释放后使用)也是未定义行为。再举一个例子,通过从 &i32 引用派生的指针进行写入是未定义行为,即使通过不同的指针写入到相同的地址是合法的。这里的底层模式是指针的计算方式很重要,而不仅仅是此计算产生的结果地址。因此,我们说指针具有来源:为了充分描述 Rust 中与指针相关的未定义行为,我们不仅要了解指针指向的地址,还要跟踪它是“派生自”哪些其他指针。

大多数时候,程序员不需要过多担心来源,并且指针是如何派生的非常清楚。但是,当将指针强制转换为整数再强制转换回来时,结果指针的来源是不明确的。在此版本中,Rust 正在添加一组 API,这些 API 可以在许多情况下替代整数-指针-强制转换的使用,从而避免此类强制转换固有的歧义。特别是,现在可以实现使用对齐指针的最低位来存储额外信息的模式,而无需将指针强制转换为整数或强制转换回来。这使得代码更易于推理,更易于编译器分析,并且还有利于 Miri 等工具和 CHERI 等旨在检测和诊断指针误用的架构。

有关更多详细信息,请参阅标准库中关于来源的文档

稳定的 API

这些 API 现在在 const 上下文中是稳定的

其他更改

查看 RustCargoClippy 中所有已更改的内容。

1.84.0 版本贡献者

许多人齐心协力创建了 Rust 1.84.0。没有你们所有人,我们不可能做到。谢谢!