Rust 团队很高兴宣布 Rust 的新版本 1.78.0 发布。Rust 是一种赋予每个人构建可靠和高效软件能力的编程语言。
如果您已经通过 rustup 安装了 Rust 的先前版本,您可以使用以下命令获取 1.78.0
$ rustup update stable
如果您还没有安装,可以从我们网站的相应页面获取 rustup,并查看 1.78.0 的详细发行说明。
如果您想通过测试未来版本来帮助我们,可以考虑将本地更新到 beta 通道(rustup default beta)或 nightly 通道(rustup default nightly)。请向我们报告您遇到的任何 bug!
1.78.0 stable 中有什么
诊断属性
Rust 现在支持 #[diagnostic] 属性命名空间来影响编译器错误消息。这些被视为编译器并非必须使用的提示,提供编译器无法识别的诊断也不会出错。这种灵活性使得源代码即使在并非所有编译器都支持诊断的情况下(无论是不同版本还是完全不同的实现),也能提供诊断信息。
通过此命名空间,首个受支持的属性 #[diagnostic::on_unimplemented] 应运而生,它可以放置在 trait 上,用于在 trait 被要求但未在某个类型上实现时自定义消息。考虑稳定化拉取请求中给出的示例
以前,编译器会给出如下内置错误
error[E0277]: the trait bound `String: ImportantTrait<i32>` is not satisfied
--> src/main.rs:12:18
|
12 | use_my_trait(String::new());
| ------------ ^^^^^^^^^^^^^ the trait `ImportantTrait<i32>` is not implemented for `String`
| |
| required by a bound introduced by this call
|
使用 #[diagnostic::on_unimplemented] 后,其自定义消息会填充主要错误行,并且其自定义标签会放在源代码输出上。原始标签仍会作为帮助输出写入,任何自定义注释也会被写入。(这些具体细节可能会更改。)
error[E0277]: My Message for `ImportantTrait<i32>` is not implemented for `String`
--> src/main.rs:12:18
|
12 | use_my_trait(String::new());
| ------------ ^^^^^^^^^^^^^ My Label
| |
| required by a bound introduced by this call
|
= help: the trait `ImportantTrait<i32>` is not implemented for `String`
= note: Note 1
= note: Note 2
对于 trait 作者来说,如果您能提供比仅仅提及缺失实现本身更好的提示,这种诊断会更有用。例如,这是标准库中的一个简化示例
有关更多信息,请参阅 diagnostic 工具属性命名空间的参考部分。
断言 unsafe 前置条件
Rust 标准库对 unsafe 函数的前置条件有一些断言,但从历史上看,这些断言仅在标准库的 #[cfg(debug_assertions)] 构建中启用,以避免影响发布性能。然而,由于标准库通常以发布模式编译和分发,大多数 Rust 开发者从未实际执行过这些检查。
现在,这些断言的条件被推迟到代码生成阶段,因此将根据用户自己的调试断言设置进行检查——在调试和测试构建中默认启用。这一更改有助于用户在其代码中捕获未定义行为,尽管检查多少的具体细节通常是不稳定的。
例如,slice::from_raw_parts 要求一个对齐的非空指针。故意使用未对齐指针的以下用法具有未定义行为,虽然如果您运气不好,它在过去可能看起来“能工作”,但现在调试断言可以捕获它
thread 'main' panicked at library/core/src/panicking.rs:220:5:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.
确定性重对齐
标准库中有一些函数可以改变指针和切片的对齐方式,但它们之前有一些注意事项,如果您严格遵循它们的文档,这些注意事项使得它们在实践中难以依赖。这些注意事项主要作为对 const 求值的对冲,但它们无论如何都只对非 const 用法稳定。现在,它们被承诺根据其实际输入具有一致的运行时行为。
-
pointer::align_offset计算将指针更改为给定对齐方式所需的偏移量。如果不可能,它将返回usize::MAX,但以前允许它总是返回usize::MAX,现在这个行为已被移除。 -
slice::align_to和slice::align_to_mut都将切片转换为一个对齐的中间切片以及剩余的未对齐的头部和尾部切片。这些方法现在承诺返回尽可能大的中间部分,而不是允许实现返回不太理想的结果,例如将所有内容作为头部切片返回。
稳定化 API
为 &Stdin 实现 Read- 接受用于几个
std::error::Error相关实现的非 `'static` 生命周期 - 使
impl实现接受?Sized 为 io::Error 实现 From
这些 API 现在在 const 上下文中稳定
兼容性说明
- 正如之前宣布的,Rust 1.78 已将以下目标的最低要求提高到 Windows 10
x86_64-pc-windows-msvci686-pc-windows-msvcx86_64-pc-windows-gnui686-pc-windows-gnux86_64-pc-windows-gnullvmi686-pc-windows-gnullvm
- Rust 1.78 已将其捆绑的 LLVM 升级到版本 18,完成了之前宣布的针对 x86-32 和 x86-64 目标的
u128/i128ABI 变更。使用自己的 LLVM 版本低于 18 的分发商可能仍会遇到该帖子中提及的调用约定错误。
其他变更
查看 Rust、Cargo 和 Clippy 中的所有变更。
1.78.0 贡献者
许多人共同努力创建了 Rust 1.78.0。没有你们所有人,我们不可能做到。谢谢!