diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 74f19930..41802fca 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -395,3 +395,4 @@ - [1.86](appendix/rust-versions/1.86.md) - [1.87](appendix/rust-versions/1.87.md) - [1.88](appendix/rust-versions/1.88.md) + - [1.89](appendix/rust-versions/1.89.md) diff --git a/src/appendix/rust-versions/1.89.md b/src/appendix/rust-versions/1.89.md new file mode 100644 index 00000000..3c11e934 --- /dev/null +++ b/src/appendix/rust-versions/1.89.md @@ -0,0 +1,162 @@ +# Rust 新版解读 | 1.89 | TODO + +> Rust 1.89 官方 release doc: [Announcing Rust 1.89.0 | Rust Blog](https://blog.rust-lang.org/2025/08/07/Rust-1.89.0/) + +通过 [rustup](https://www.rust-lang.org/tools/install) 安装的同学可以使用以下命令升级到 1.89 版本: + +```shell +$ rustup update stable +``` + +## 常量泛型的显式推断参数 + +Rust现在支持在常量泛型参数中使用 `_`,从上下文推断其值: + +```rust +pub fn all_false() -> [bool; LEN] { + [false; _] +} +``` + +与类型中使用 `_` 的规则类似,在函数签名中不允许将 `_` 作为常量泛型参数: + +```rust +// 不允许这样做 +pub const fn all_false() -> [bool; _] { + [false; LEN] +} + +// 这个也不允许 +pub const ALL_FALSE: [bool; _] = all_false::<10>(); +``` + +## 生命周期语法不匹配的警告 + +函数签名中的[生命周期省略](https://doc.rust-lang.org/1.89.0/book/ch10-03-lifetime-syntax.html#lifetime-elision)是 Rust 语言的一个便利特性,但也可能成为新手和专家的绊脚石。特别是当类型中隐含生命周期但语法上不明显时: + +```rust +// 返回类型 `std::slice::Iter` 有一个生命周期, +// 但是看起来没有任何提示。 +// +// 生命周期省略推断返回类型的生命周期 +// 与 `scores` 相同。 +fn items(scores: &[u8]) -> std::slice::Iter { + scores.iter() +} +``` + +类似这样的代码现在会默认产生警告: + +```text +warning: hiding a lifetime that's elided elsewhere is confusing + --> src/lib.rs:1:18 + | +1 | fn items(scores: &[u8]) -> std::slice::Iter { + | ^^^^^ -------------------- 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年](https://github.com/rust-lang/rust/pull/46254)尝试改进这种情况,作为 [`rust_2018_idioms`](https://github.com/rust-lang/rust/issues/54910) 警告组的一部分,但关于 `elided_lifetimes_in_paths` 警告的[强烈反馈](https://github.com/rust-lang/rust/issues/131725)表明它过于生硬,因为它会警告那些对理解函数无关紧要的生命周期: + +```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`, `&'_ T`, `ContainsLifetime<'_>` | +| 是 | 否 | `&'a T`, `ContainsLifetime<'a>` | + +`mismatched_lifetime_syntaxes` 警告检查函数的输入和输出是否属于同一组。对于上面的初始示例,`&[u8]` 属于第二组,而`std::slice::Iter` 属于第一组。我们说第一组中的生命周期是*隐藏的*。 + +由于输入和输出生命周期属于不同组,警告会提示这个函数,减少对不明显但重要的生命周期的混淆。 + +`mismatched_lifetime_syntaxes` 警告取代了 `elided_named_lifetimes` 警告,后者专门针对命名生命周期做了类似的事情。 + +未来对 `elided_lifetimes_in_paths` 警告的工作计划将其拆分为更集中的子警告,并考虑最终警告其中的一部分。 + +## 更多 x86 目标特性 + +`target_feature` 属性现在支持 x86 上的 `sha512`、`sm3`、`sm4`、`kl` 和 `widekl` 目标特性。此外,x86 上也支持许多 `avx512` 内部函数和目标特性: + +```rust +#[target_feature(enable = "avx512bw")] +pub fn cool_simd_code(/* .. */) -> /* ... */ { + /* ... */ +} +``` + +## 跨平台文档测试 + +现在运行 `cargo test --doc --target other_target` 时会测试文档测试,这可能会导致一些文档测试因失败而被测试出来。 + +可以通过用 `ignore-` 注解文档测试来禁用失败的测试([文档](https://doc.rust-lang.org/stable/rustdoc/write-documentation/documentation-tests.html#ignoring-targets)): + +```rust +/// ```ignore-x86_64 +/// panic!("something") +/// ``` +pub fn my_function() { } +``` + +## `extern "C"` 函数中的 `i128` 和 `u128` + +`i128` 和 `u128` 不再触发 `improper_ctypes_definitions` 警告,意味着这些类型可以在 `extern "C"` 函数中使用而不产生警告。这有一些注意事项: + +* 当类型可用时,Rust 类型与 C 中的(无符号)`__int128` 在 ABI 和布局上是兼容的。 +* 在 `__int128` 不可用的平台上,`i128` 和 `u128` 不一定与任何 C 类型对齐。 +* `i128` 不一定与任何平台上的 `_BitInt(128)` 兼容,因为 `_BitInt(128)` 和 `__int128` 可能有不同的 ABI(如在 x86-64 上)。 + +这是去年布局变更的最后一点后续工作:[https://blog.rust-lang.org/2024/03/30/i128-layout-update](https://blog.rust-lang.org/2024/03/30/i128-layout-update)。 + +## 将 `x86_64-apple-darwin` 降级为 Tier 2 并保留工具链 + +GitHub 将很快[停止](https://github.blog/changelog/2025-07-11-upcoming-changes-to-macos-hosted-runners-macos-latest-migration-and-xcode-support-policy-updates/)为公共仓库提供免费的 macOS x86_64 运行器。苹果也宣布了[计划](https://en.wikipedia.org/wiki/Mac_transition_to_Apple_silicon#Timeline)停止支持 x86_64 架构。 + +根据这些变化,Rust 项目正在[将 `x86_64-apple-darwin` 目标](https://github.com/rust-lang/rfcs/pull/3841)从[带工具链的 Tier 1](https://doc.rust-lang.org/stable/rustc/platform-support.html#tier-1-with-host-tools)降级为[带工具链的 Tier 2](https://doc.rust-lang.org/stable/rustc/platform-support.html#tier-2-with-host-tools)。这意味着该目标(包括 `rustc` 和 `cargo` 等工具)将保证构建,但不保证通过我们的自动化测试套件。 + +我们预计在 Rust 1.89 和 1.90 发布之间会接受降级为带工具链的 Tier 2 的 RFC,这意味着 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](https://blog.rust-lang.org/2025/04/04/c-abi-changes-for-wasm32-unknown-unknown)。 + +## 平台支持 + +* [`x86_64-apple-darwin`正在被降级为带工具链的Tier 2](https://github.com/rust-lang/rfcs/pull/3841) +* [添加新的Tier-3目标`loongarch32-unknown-none`和`loongarch32-unknown-none-softfloat`](https://github.com/rust-lang/rust/pull/142053) + +有关 Rust 的分层平台支持的更多信息,请参阅 Rust 的[平台支持页面](https://doc.rust-lang.org/stable/rustc/platform-support.html)。 + + +## Others + +其它更新细节,和稳定的 API 列表,参考[原Blog](https://blog.rust-lang.org/2025/08/07/Rust-1.89.0/#stabilized-apis)