Rust 1.89.0发布:全新特性与平台支持更新

Rust 1.89.0版本正式发布,引入显式推断常量泛型参数、生命周期语法检查改进、新增x86目标特性支持、跨平台文档测试等核心功能,同时调整wasm32目标ABI标准并更新平台支持策略。

宣布 Rust 1.89.0

2025年8月7日 · Rust 发布团队

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

如果您已通过 rustup 安装了旧版 Rust,可以通过以下命令获取 1.89.0:

1
$ rustup update stable

如果尚未安装,可以从我们网站的相关页面获取 rustup,并查看 1.89.0 的详细发布说明。

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

1.89.0 稳定版中的新特性

显式推断常量泛型参数

Rust 现在支持将 _ 作为常量泛型参数的参数,从上下文中推断值:

1
2
3
pub fn all_false<const LEN: usize>() -> [bool; LEN] {
  [false; _]
}

与允许 _ 作为类型的规则类似,在签名中不允许将 _ 作为常量泛型的参数:

1
2
3
4
5
6
7
// 不允许这样做
pub const fn all_false<const LEN: usize>() -> [bool; _] {
  [false; LEN]
}

// 这个也不允许
pub const ALL_FALSE: [bool; _] = all_false::<10>();

不匹配的生命周期语法检查

函数签名中的生命周期省略是 Rust 语言的一个便捷特性,但它也可能成为新手和专家的绊脚石。当在语法上不明显存在生命周期的类型中推断生命周期时,尤其如此:

1
2
3
4
5
// 返回类型 `std::slice::Iter` 具有生命周期,但没有视觉指示。
// 生命周期省略推断返回类型的生命周期与 `scores` 相同。
fn items(scores: &[u8]) -> std::slice::Iter<u8> {
   scores.iter()
}

现在,此类代码默认会产生警告:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
warning: hiding a lifetime that's elided elsewhere is confusing
 --> src/lib.rs:1:18
  |
1 | fn items(scores: &[u8]) -> std::slice::Iter<u8> {
  |                  ^^^^^     -------------------- the same lifetime is hidden here
  |                  |
  |                  the lifetime is elided here
  |
  = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
  = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
help: use `'_` for type paths
  |
1 | fn items(scores: &[u8]) -> std::slice::Iter<'_, u8> {
  |                                             +++

我们早在 2018 年就尝试改进这种情况,作为 rust_2018_idioms 检查组的一部分,但关于 elided_lifetimes_in_paths 检查的强烈反馈表明它过于生硬,因为它会警告那些对理解函数无关紧要的生命周期:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
use std::fmt;

struct Greeting;

impl fmt::Display for Greeting {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        //                -----^^^^^^^^^ expected lifetime parameter
        // 知道 `Formatter` 有生命周期对程序员没有帮助
        "howdy".fmt(f)
    }
}

然后我们意识到,我们想要消除的混淆发生在以下两种情况同时出现时:

  • 生命周期省略推断规则将输入生命周期连接到输出生命周期
  • 在语法上不明显存在生命周期

Rust 语法中有两个部分表明存在生命周期:&',其中 ' 细分为推断生命周期 '_ 和命名生命周期 'a。当类型使用命名生命周期时,生命周期省略不会为该类型推断生命周期。使用这些标准,我们可以构建三个组:

明显具有生命周期 允许生命周期省略推断生命周期 示例
ContainsLifetime
&T, &'_ T, ContainsLifetime<'_>
&'a T, ContainsLifetime<'a>

mismatched_lifetime_syntaxes 检查确保函数的输入和输出属于同一组。对于上面的初始动机示例,&[u8] 属于第二组,而 std::slice::Iter<u8> 属于第一组。我们说第一组中的生命周期是隐藏的。

由于输入和输出生命周期属于不同的组,检查将警告此函数,减少关于值何时具有在视觉上不明显的有效生命周期的混淆。

mismatched_lifetime_syntaxes 检查取代了 elided_named_lifetimes 检查,后者专门对命名生命周期执行类似操作。

未来对 elided_lifetimes_in_paths 检查的工作旨在将其拆分为更集中的子检查,并考虑最终警告其中的一个子集。

更多 x86 目标特性

target_feature 属性现在支持 x86 上的 sha512sm3sm4klwidekl 目标特性。此外,x86 上也支持许多 avx512 内部函数和目标特性:

1
2
3
4
#[target_feature(enable = "avx512bw")]
pub fn cool_simd_code(/* .. */) -> /* ... */ {
    /* ... */
}

跨平台文档测试

现在,在运行 cargo test --doc --target other_target 时将测试文档测试,这可能会由于现在测试本应失败的文档测试而导致一些破坏。

可以通过使用 ignore-<target> 注释文档测试来禁用失败的测试(文档):

1
2
3
4
/// ```ignore-x86_64
/// panic!("something")
/// ```
pub fn my_function() { }

extern “C” 函数中的 i128 和 u128

i128u128 不再触发 improper_ctypes_definitions 检查,这意味着这些类型可以在 extern "C" 函数中使用而不会产生警告。这有一些注意事项:

  • 当类型可用时,Rust 类型与 C 中的 (unsigned) __int128 在 ABI 和布局上兼容。
  • __int128 不可用的平台上,i128u128 不一定与任何 C 类型对齐。
  • 在任何平台上,i128 不一定与 _BitInt(128) 兼容,因为 _BitInt(128)__int128 可能没有相同的 ABI(如在 x86-64 上)。

这是去年布局更改的最后一点后续工作:https://blog.rust-lang.org/2024/03/30/i128-layout-update。

将 x86_64-apple-darwin 降级为 Tier 2 并保留主机工具

GitHub 将很快停止为公共仓库提供免费的 macOS x86_64 运行器。Apple 也宣布了停止支持 x86_64 架构的计划。

根据这些变化,Rust 项目正在将 x86_64-apple-darwin 目标从 Tier 1(带主机工具)降级为 Tier 2(带主机工具)。这意味着该目标(包括 rustccargo 等工具)将保证构建,但不保证通过我们的自动化测试套件。

我们预计,降级为 Tier 2(带主机工具)的 RFC 将在 Rust 1.89 和 1.90 发布之间被接受,这意味着 Rust 1.89 将是 x86_64-apple-darwin 作为 Tier 1 目标的最后一个 Rust 版本。

对于用户来说,此更改不会立即产生影响。在该目标保持为 Tier 2 期间,Rust 项目仍将通过 rustup 或替代安装方法分发标准库和编译器的构建。随着时间的推移,该目标的测试覆盖率降低可能会导致问题或兼容性丧失,而无需进一步公告。

wasm32-unknown-unknown 目标上的符合标准的 C ABI

wasm32-unknown-unknown 目标上的 extern "C" 函数现在具有符合标准的 ABI。更多信息请参阅此博客文章:https://blog.rust-lang.org/2025/04/04/c-abi-changes-for-wasm32-unknown-unknown。

平台支持

  • x86_64-apple-darwin 正在降级为 Tier 2(带主机工具)
  • 新增 Tier-3 目标 loongarch32-unknown-noneloongarch32-unknown-none-softfloat

有关 Rust 分层平台支持的更多信息,请参阅 Rust 的平台支持页面。

稳定的 API

  • NonZero<char>
  • 许多 x86 内部函数(此处未枚举)
  • AVX512 内部函数
  • SHA512、SM3 和 SM4 内部函数
  • File::lock
  • File::lock_shared
  • File::try_lock
  • File::try_lock_shared
  • File::unlock
  • NonNull::from_ref
  • NonNull::from_mut
  • NonNull::without_provenance
  • NonNull::with_exposed_provenance
  • NonNull::expose_provenance
  • OsString::leak
  • PathBuf::leak
  • Result::flatten
  • std::os::linux::net::TcpStreamExt::quickack
  • std::os::linux::net::TcpStreamExt::set_quickack

这些先前稳定的 API 现在在常量上下文中稳定:

  • <[T; N]>::as_mut_slice
  • <[u8]>::eq_ignore_ascii_case
  • str::eq_ignore_ascii_case

其他更改

查看 Rust、Cargo 和 Clippy 中的所有更改。

1.89.0 的贡献者

许多人共同创建了 Rust 1.89.0。没有大家,我们无法完成。谢谢!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计