Rust: 1.86.0 新版本发布。

原文链接 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 的诞生离不开众多开发者的共同努力。没有你们,我们不可能完成这一切。谢谢!

相关推荐
1nv1s1ble4 小时前
记录rust滥用lazy_static导致的一个bug
算法·rust·bug
华科云商xiao徐10 小时前
用Rust如何构建高性能爬虫
爬虫·rust
景天科技苑11 小时前
【Rust UDP编程】rust udp编程方法解析与应用实战
开发语言·rust·udp·udp编程·rust udp
火柴就是我1 天前
Rust学习之 所有权理解
rust
火柴就是我1 天前
Rust 学习之变量的可变与不可变
rust
维维酱1 天前
Rust - Futures
rust
Pomelo_刘金1 天前
发布 Rust 1.87.0 —— 以及 Rust 十周年!
rust
susnm1 天前
你的第一个组件
rust·全栈
该用户已不存在2 天前
OpenAI 用 Rust 重写 AI 工具,你的本地开发环境跟上了吗?
前端·javascript·rust