宣布 Rust 1.89.0 发布

本文首发公众号 猩猩程序员 欢迎关注

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

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

ruby 复制代码
$ rustup update stable

如果您尚未安装 rustup,您可以通过我们官网的相应页面获取它,并查看 1.89.0 的详细发布说明。

如果您希望通过测试未来的版本来帮助我们,您可以考虑本地更新并使用 beta 渠道(rustup default beta)或 nightly 渠道(rustup default nightly)。遇到任何 bug,请随时报告!

1.89.0 稳定版的新特性

显式推断的常量泛型参数

Rust 现在支持将 _ 用作常量泛型参数的一个参数,编译器会从周围的上下文推断该值:

rust 复制代码
pub fn all_false<const LEN: usize>() -> [bool; LEN] {
  [false; _]
}

类似于 _ 作为类型参数的使用规则,当在函数签名中使用 _ 作为常量泛型的参数时,编译器会拒绝:

rust 复制代码
// 这是不允许的
pub const fn all_false<const LEN: usize>() -> [bool; _] {
  [false; LEN]
}

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

不匹配的生命周期语法警告

函数签名中的生命周期省略是 Rust 的一种便捷特性,但它也可能是新手和专家的绊脚石,尤其当生命周期被推断到类型时,如果没有明显的语法指示,可能会令人困惑:

rust 复制代码
// 返回类型 `std::slice::Iter` 有生命周期,
// 但代码中没有视觉指示
//
// 生命周期省略会将返回类型的生命周期推断为与 `scores` 的生命周期相同
fn items(scores: &[u8]) -> std::slice::Iter<u8> {
   scores.iter()
}

像上面的代码现在会默认生成警告:

rust 复制代码
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 lint 组来改善这个问题,但对于 elided_lifetimes_in_paths lint 的强烈反馈表明,这个 lint 过于笨拙,因为它会警告一些对于理解函数没有实际意义的生命周期:

rust 复制代码
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)
    }
}

我们意识到,造成困惑的情况出现在以下两种情况下:

  1. 生命周期省略推断规则将输入生命周期与输出生命周期连接在一起
  2. 没有语法上明显的生命周期存在

Rust 语法中有两种标志生命周期存在的方式:&',其中 ' 又分为推断生命周期 '_ 和命名生命周期 'a。当类型使用命名生命周期时,生命周期省略将不会为该类型推断生命周期。通过这些标准,我们可以构建出三组:

自显生命周期 允许省略生命周期推断 示例
ContainsLifetime
&T&'_ TContainsLifetime<'_>
&'a TContainsLifetime<'a>

mismatched_lifetime_syntaxes lint 检查函数的输入和输出是否属于同一组。上述初始示例中,&[u8] 属于第二组,而 std::slice::Iter<u8> 属于第一组,因此它们的生命周期是"隐藏的"。由于输入和输出的生命周期属于不同的组,lint 会发出警告,减少对生命周期存在但视觉上不明显的困惑。

更多 x86 目标特性

target_feature 属性现在支持 sha512sm3sm4klwidekl 等 x86 目标特性。此外,x86 上还支持一些 AVX512 内在特性和目标特性:

rust 复制代码
#[target_feature(enable = "avx512bw")]
pub fn cool_simd_code(/* .. */) -> /* ... */ {
    /* ... */
}

跨编译文档测试

当运行 cargo test --doc --target other_target 时,文档测试现在将被测试。这可能会导致一些断裂,因为本来会失败的文档测试现在会被测试到。

失败的测试可以通过在文档测试中使用 ignore-<target> 注解来禁用:

csharp 复制代码
/// ```ignore-x86_64
/// panic!("something")
/// ```
pub fn my_function() { }

i128 和 u128 在 extern "C" 函数中的使用

i128 和 u128 不再触发 improper_ctypes_definitions lint,这意味着这些类型可以在 extern "C" 函数中使用而不会产生警告。需要注意的是:

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

这是去年布局更改的最后一步:blog.rust-lang.org/2024/03/30/...

将 x86_64-apple-darwin 降级为 Tier 2

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

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

预计 RFC 将在 Rust 1.89 和 1.90 发布之间接受,这意味着 Rust 1.89 将是最后一个将 x86_64-apple-darwin 视为 Tier 1 目标的版本。

对于用户来说,这个变化不会立即产生影响。在目标仍处于 Tier 2 时,Rust 项目将继续分发标准库和编译器的构建,供 rustup 或其他安装方法使用。随着时间推移,目标的测试覆盖率减少可能会导致某些功能不再兼容或出现问题,且没有进一步的公告。

wasm32-unknown-unknown 目标的标准 C ABI 支持

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

平台支持

  • 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 中的所有更改。

Rust 1.89.0 的贡献者

许多人共同努力,创造了 Rust 1.89.0。没有你们,我们无法做到。谢谢大家!

本文首发公众号 猩猩程序员 欢迎关注

相关推荐
代码搬运媛4 小时前
Jest 测试框架详解与实现指南
前端
counterxing5 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq5 小时前
windows下nginx的安装
linux·服务器·前端
之歆6 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜6 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai108086 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
kyriewen8 小时前
产品经理把PRD写成“天书”,我用AI半小时重写了一遍,他当场愣住
前端·ai编程·cursor
humcomm8 小时前
元框架的工作原理详解
前端·前端框架
canonical_entropy8 小时前
Attractor Before Harness: AI 大规模开发的方法论
前端·aigc·ai编程
zhangxingchao9 小时前
多 Agent 架构到底怎么选?从 Claude Agent Teams、Cognition/Devin 到工程落地原则
前端·人工智能·后端