Announcing Rust 1.96.0
Announcing Rust 1.96.0
Rust 1.96.0 发布公告
May 28, 2026 · The Rust Release Team 2026 年 5 月 28 日 · Rust 发布团队
The Rust team is happy to announce a new version of Rust, 1.96.0. Rust is a programming language empowering everyone to build reliable and efficient software. Rust 团队很高兴地宣布 Rust 的新版本 1.96.0。Rust 是一门赋予每个人构建可靠且高效软件能力的编程语言。
If you have a previous version of Rust installed via rustup, you can get 1.96.0 with: $ rustup update stable
如果你之前通过 rustup 安装了旧版本的 Rust,可以通过以下命令获取 1.96.0:$ rustup update stable
If you don’t have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.96.0. 如果你还没有安装,可以从我们网站的相关页面获取 rustup,并查看 1.96.0 的详细发布说明。
If you’d like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!
如果你想通过测试未来版本来帮助我们,可以考虑在本地更新并使用 beta 通道(rustup default beta)或 nightly 通道(rustup default nightly)。如果遇到任何 Bug,请务必向我们报告!
What’s in 1.96.0 stable
Rust 1.96.0 稳定版更新内容
New Range* types
新的 Range* 类型
Many users expect Range and related core::ops types to be Copy, but this is not the case: they implement Iterator directly, and it is a footgun to implement both Iterator and Copy on the same type so this has been avoided.
许多用户期望 Range 及相关的 core::ops 类型能够实现 Copy,但事实并非如此:它们直接实现了 Iterator。在同一个类型上同时实现 Iterator 和 Copy 很容易导致误用(footgun),因此此前一直避免这样做。
RFC3550 proposed a set of replacement range types that implement IntoIterator rather than Iterator, meaning they can also be Copy. The standard library portion of that RFC is now stable, introducing:
RFC3550 提出了一组替代的范围类型,它们实现的是 IntoIterator 而非 Iterator,这意味着它们也可以实现 Copy。该 RFC 中标准库的部分现已稳定,引入了:
core::range::Rangecore::range::RangeFromcore::range::RangeInclusive
Associated iterators
关联迭代器
A Rust version in the near future will also add core::range::RangeFull and core::range::RangeTo as re-exports from core::ops (these do not implement Iterator and already implement Copy), and core::range::legacy::* as the new home for the current ranges. Range syntax like 0..1 still produces the legacy types for now, but will be updated to core::range types in a future edition.
在不久的将来,Rust 版本还将添加 core::range::RangeFull 和 core::range::RangeTo 作为 core::ops 的重新导出(它们不实现 Iterator 且已实现 Copy),并将 core::range::legacy::* 作为当前范围类型的新归宿。目前,像 0..1 这样的范围语法仍会生成旧版类型,但在未来的版本中将更新为 core::range 类型。
With these stabilizations, it is now possible to store slice accessors in Copy types without splitting start and end:
随着这些特性的稳定,现在可以在 Copy 类型中存储切片访问器,而无需拆分起始和结束索引:
use core::range::Range;
#[derive(Clone, Copy)]
pub struct Span(Range<usize>);
impl Span {
pub fn of(self, s: &str) -> &str {
&s[self.0]
}
}
The new RangeInclusive also makes its fields public, unlike the legacy version which avoided exposing the exhausted iterator state. This isn’t a concern with the new type since it must be converted to begin iteration.
新的 RangeInclusive 还将其字段设为公开,这与旧版本不同(旧版本为了避免暴露已耗尽的迭代器状态而隐藏了字段)。对于新类型来说,这不再是问题,因为它必须先转换才能开始迭代。
Library authors should consider making use of impl RangeBounds in public API, which accepts both legacy and new range types. If a concrete type is needed, prefer using new ranges as this will eventually become the default.
库作者应考虑在公共 API 中使用 impl RangeBounds,它同时接受旧版和新版的范围类型。如果需要具体类型,建议优先使用新版范围类型,因为它们最终将成为默认选择。
Assert matching patterns
断言匹配模式
The new macros assert_matches! and debug_assert_matches! check that a value matches a given pattern, panicking with a Debug representation of the value otherwise. These are essentially the same as assert!(matches!(..)) and debug_assert!(matches!(..)), but the printed value improves the possibility of diagnosing the failure.
新的宏 assert_matches! 和 debug_assert_matches! 用于检查值是否匹配给定的模式,如果不匹配则会触发 panic,并打印该值的 Debug 表示。它们本质上与 assert!(matches!(..)) 和 debug_assert!(matches!(..)) 相同,但打印出的值有助于诊断失败原因。
These new macros have not been added to the standard prelude, because they would collide with popular third-party crates that provide macros with the same name. Instead, they should be manually imported from core or std before use.
这些新宏没有被添加到标准 prelude 中,因为它们会与提供同名宏的流行第三方 crate 发生冲突。因此,在使用前需要从 core 或 std 中手动导入。
use core::assert_matches;
/// [Random Number](https://xkcd.com/221/)
fn get_random_number() -> u32 {
// chosen by a fair dice roll.
// guaranteed to be random.
4
}
fn main() {
assert_matches!(get_random_number(), 1..=6);
}
Changes to WebAssembly targets
WebAssembly 目标变更
WebAssembly targets no longer pass --allow-undefined to the linker which means that undefined symbols when linking are now a linker error instead of being converted to WebAssembly imports from the “env” module. This change prevents modules from linking unless all linking-related symbols are defined to catch bugs earlier and prevent accidental issues with symbol naming or similar.
WebAssembly 目标不再向链接器传递 --allow-undefined,这意味着链接时的未定义符号现在会直接导致链接错误,而不是被转换为来自 “env” 模块的 WebAssembly 导入。此更改要求所有与链接相关的符号必须定义才能成功链接,从而更早地捕获 Bug,并防止符号命名等方面的意外问题。
Undefined linking-related symbols are often indicative of build-time related bugs or misconfiguration. If, however, the old behavior is intended then it can be re-enabled with RUSTFLAGS=-Clink-arg=--allow-undefined or by editing the source code and using #[link(wasm_import_module = "env")] on the block defining the symbol. This change was previously announced on this blog, and now takes effect in Rust 1.96.
未定义的链接符号通常预示着构建时相关的 Bug 或配置错误。如果确实需要旧行为,可以通过 RUSTFLAGS=-Clink-arg=--allow-undefined 重新启用,或者通过编辑源代码并在定义符号的块上使用 #[link(wasm_import_module = "env")] 来实现。此更改此前已在本博客中宣布,现已在 Rust 1.96 中生效。
Stabilized APIs
已稳定的 API
assert_matches!debug_assert_matches!From<T> for AssertUnwindSafe<T>From<T> for LazyCell<T, F>From<T> for LazyLock<T, F>core::range::RangeToInclusivecore::range::RangeToInclusiveItercore::range::RangeFromcore::range::RangeFromItercore::range::Rangecore::range::RangeIter
Two Cargo advisories
两项 Cargo 安全公告
Rust 1.96 contains fixes for two vulnerabilities for users of third-party registries. CVE-2026-5223 is a medium severity vulnerability regarding extraction of crate tarballs with symlinks. CVE-2026-5222 is a low severity vulnerability regarding authentication with normalized URLs. Users of crates.io are not affected by either vulnerability. Rust 1.96 修复了针对第三方注册表用户的两个漏洞。CVE-2026-5223 是一个中等严重程度的漏洞,涉及带有符号链接的 crate tarball 解压;CVE-2026-5222 是一个低严重程度的漏洞,涉及使用规范化 URL 进行身份验证。crates.io 的用户不受这两个漏洞的影响。
Other changes
其他更改
Check out everything that changed in Rust, Cargo, and Clippy. 查看 Rust、Cargo 和 Clippy 中的所有更改。
Contributors to 1.96.0
1.96.0 的贡献者
Many people came together to create Rust 1.96.0. We couldn’t have done it without all of you. Thanks! 许多人共同努力创造了 Rust 1.96.0。没有你们,我们无法做到这一点。谢谢!