原文链接 Rust 团队欣然宣布:Rust 1.86.0 正式发布!
Rust 是一门帮助每个人构建可靠且高效软件的编程语言。
如果你已经通过 rustup 安装了旧版 Rust,可执行:
bash
$ rustup update stable
即可升级到 1.86.0。
如果尚未安装,请访问官网的 appropriate page on our website 获取 rustup,并查阅 [1.86.0 详细发行说明] 。
想帮忙测试未来版本?可以将本地工具链切换到 beta 通道(rustup default beta
)或 nightly 通道(rustup default nightly
)。如发现任何 Bug,欢迎反馈!
1.86.0 稳定版亮点
Trait 向上转型(Trait upcasting)
本次发布带来了期盼已久的 Trait 对象向上转型 功能。若某个 trait 拥有 supertrait ,即可将对其 trait 对象的引用自动协变为 supertrait 的 trait 对象引用:
rust
trait Trait: Supertrait {}
trait Supertrait {}
fn upcast(x: &dyn Trait) -> &dyn Supertrait {
x
}
同理,Arc 可转为 Arc,*const dyn Trait 可转为 *const dyn Supertrait,等等。
此前常见的变通做法是在 Trait 内添加 fn as_supertrait(&self) -> &dyn Supertrait,且只能处理一种指针类型;如今皆无需再写样板代码。
需注意:裸指针指向的 vtable 必须有效;泄露带无效 vtable 的裸指针到安全代码会触发 未定义行为。在可控语境下临时创建此类裸指针是否立即 UB,仍待进一步规范,因此应避免任何情况下创建它们(Miri 亦会检查)。
此特性对 Any trait 尤其有用:可先将自定义 trait 对象向上转型为 dyn Any,再调用 Any::downcast*,无需增添额外 trait 方法或依赖第三方 crate。
rust
use std::any::Any;
trait MyAny: Any {}
impl dyn MyAny {
fn downcast_ref<T>(&self) -> Option<&T> {
(self as &dyn Any).downcast_ref()
}
}
您可以在 Rust 参考中了解有关特征向上转型的更多信息。
HashMap 与切片支持 可变多元素索引
由于借用检查规则,重复调用 get_mut 取到的可变引用不能并存。为安全地同时借多处元素,标准库现新增 get_disjoint_mut(切片与 HashMap 均提供)。示例(节选自 slice::get_disjoint_mut: 文档):
rust
let v = &mut [1, 2, 3];
if let Ok([a, b]) = v.get_disjoint_mut([0, 2]) {
*a = 413;
*b = 612;
}
assert_eq!(v, &[413, 2, 612]);
if let Ok([a, b]) = v.get_disjoint_mut([0..1, 1..3]) {
a[0] = 8;
b[0] = 88;
b[1] = 888;
}
assert_eq!(v, &[8, 88, 888]);
if let Ok([a, b]) = v.get_disjoint_mut([1..=2, 0..=0]) {
a[0] = 11;
a[1] = 111;
b[0] = 1;
}
assert_eq!(v, &[1, 11, 111]);
允许 安全函数 使用 #[target_feature]
此前仅 unsafe fn 可标记 #[target_feature],因为若在未启用目标指令集时调用会造成未定义行为。本次稳定 target_feature_11,允许 安全函数 标记该属性。
带 #[target_feature(...)] 的安全函数,只能在 同样标记 的函数体内安全调用。 若在未标记函数中调用,必须置于 unsafe 块并自行检测特性是否可用。
rust
#[target_feature(enable = "avx2")]
fn requires_avx2() {
// ... snip
}
#[target_feature(enable = "avx2")]
fn safe_callsite() {
// Calling `requires_avx2` here is safe as `safe_callsite`
// requires the `avx2` feature itself.
requires_avx2();
}
fn unsafe_callsite() {
// Calling `requires_avx2` here is unsafe, as we must
// ensure that the `avx2` feature is available first.
if is_x86_feature_detected!("avx2") {
unsafe { requires_avx2() };
}
}
您可以查看target_features_11RFC 来获取更多信息。
调试断言:指针空值检查
编译器现会在调试断言开启时,为指针解引用(非零大小读写)或重新借用为引用时插入 非空检查。例如:
rust
let _x = *std::ptr::null::<u8>();
let _x = &*std::ptr::null::<u8>();
类似警告自 1.53.0 起已存在;如今不论代码复杂度,运行时均能捕获。 注意:仅在开启 debug_assertions 的构建中插入检查,不能依赖其保证内存安全。
missing_abi 现默认为 warn
省略 extern 块/函数的 ABI(如 extern {}、extern fn)现会触发 missing_abi 警告。推荐显式写成 extern "C" {} 或 extern "C" fn。 背景可见 Explicit Extern ABIs RFC。
1.87.0 将移除目标 i586-pc-windows-msvc
Tier-2 目标 i586-pc-windows-msvc 将于 下一个版本 Rust 1.87.0 移除。区别在于该目标 不要求 SSE2,但 Windows 10(所有 windows 目标的最低支持版本,win7 系列除外)自身已依赖 SSE2。 请所有使用该目标的项目迁移至 i686-pc-windows-msvc。详见重大变更提案。
稳定的 API
-
{float}::next_down
-
{float}::next_up
-
<[_]>::get_disjoint_mut
-
<[_]>::get_disjoint_unchecked_mut
-
slice::GetDisjointMutError
-
HashMap::get_disjoint_mut
-
HashMap::get_disjoint_unchecked_mut
-
NonZero::count_ones
-
Vec::pop_if
-
sync::Once::wait
-
sync::Once::wait_force
-
sync::OnceLock::wait 这些 API 现在在 const 上下文中是稳定的:
-
hint::black_box
-
io::Cursor::get_mut
-
io::Cursor::set_position
-
str::is_char_boundary
-
str::split_at
-
str::split_at_checked
-
str::split_at_mut
-
str::split_at_mut_checked 其他变化 查看Rust、Cargo和Clippy中发生的所有变化。
1.86.0 的贡献者 Rust 1.86.0 的诞生离不开众多开发者的共同努力。没有你们,我们不可能完成这一切。谢谢!