本文首发公众号 猩猩程序员 欢迎关注
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)
}
}
我们意识到,造成困惑的情况出现在以下两种情况下:
- 生命周期省略推断规则将输入生命周期与输出生命周期连接在一起
- 没有语法上明显的生命周期存在
Rust 语法中有两种标志生命周期存在的方式:&
和 '
,其中 '
又分为推断生命周期 '_
和命名生命周期 'a
。当类型使用命名生命周期时,生命周期省略将不会为该类型推断生命周期。通过这些标准,我们可以构建出三组:
自显生命周期 | 允许省略生命周期推断 | 示例 |
---|---|---|
否 | 是 | ContainsLifetime |
是 | 是 | &T ,&'_ T ,ContainsLifetime<'_> |
是 | 否 | &'a T ,ContainsLifetime<'a> |
mismatched_lifetime_syntaxes
lint 检查函数的输入和输出是否属于同一组。上述初始示例中,&[u8]
属于第二组,而 std::slice::Iter<u8>
属于第一组,因此它们的生命周期是"隐藏的"。由于输入和输出的生命周期属于不同的组,lint 会发出警告,减少对生命周期存在但视觉上不明显的困惑。
更多 x86 目标特性
target_feature
属性现在支持 sha512
、sm3
、sm4
、kl
和 widekl
等 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-none
和loongarch32-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。没有你们,我们无法做到。谢谢大家!
本文首发公众号 猩猩程序员 欢迎关注