Rust 2025H2 项目目标收官:字段投影、BorrowSanitizer、Polonius 即将稳定

2026-05-18 22 预计阅读时间:1 分钟
来源:blog.rust-lang.org AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:11 分钟

2025 下半年的 Rust 项目目标周期已经结束——41 个目标、13 个旗舰目标,从语言设计到编译器基础设施全面推进。不少目标将延续到 2026 周期,但有几个已经交出了阶段性答卷。本文挑出最值得关注的进展,逐个拆解。

字段投影:t-lang 设计会议获极高评价

字段投影(Field Projections)是本轮更新中信息量最大的目标。Benno Lossin 推动的 "virtual places" 方案在 4 月 2 日的 t-lang 设计会议上收获了近乎一致的好评:

  • Josh Triplett:"I adore this! 我预感它会成为 Rust 中一个广受喜爱、无处不在的特性。"
  • TC:"我特别喜欢那些能减少库 API 表面积的语言特性,这正是其中之一。"
  • Tyler Mandry:"这个方向有效地建立在 Rust 已有的概念之上,同时让它们更具表达力。"

核心思路是引入 Field Representing Types(FRTs)——每个字段拥有一个唯一类型,通过 field_of! 宏获取。第一个实验性 PR(rust-lang/rust#152730)已经合并,开启了 #![feature(field_projections)]。下面是当前 nightly 上可以跑的示例:

#![feature(field_projections)]

use std::field::{Field, field_of};
use std::ptr;

fn project_ref<'a, T, F: Field<Base = T>>(r: &'a T) -> &'a F::Type {
    // SAFETY: Field trait 保证这是安全的
    unsafe { &*ptr::from_ref(r).byte_add(F::OFFSET).cast() }
}

struct Struct {
    field: i32,
    other: u32,
}

fn main() {
    let s = Struct { field: 42, other: 24 };
    let r = &s;
    let field = project_ref::<_, field_of!(Struct, field)>(r);
    let other = project_ref::<_, field_of!(Struct, other)>(r);
    println!("field: {field}"); // 42
    println!("other: {other}"); // 24
}

FRT 的关键能力:如果你拥有基础类型,可以为 FRT 实现自定义 trait。这意味着可以用 trait 标注字段的属性——比如"结构化固定(structurally pinned)"字段。Benno 在更新中给出了 PinnableField trait 的完整示例:对 Unpin 字段返回普通 &mut,对非 Unpin 字段返回 Pin<&mut>,全部在类型系统层面保证安全。

2026 年的三步走计划已经明确:a-mir-formality 形式化建模 → 编译器实现(先库后语法)→ 在 Linux 内核和 crubit 中实测。会议也提出了几个待解的设计问题:能否穿透 Option 投影?能否支持 Cell<[T]>[Cell<T>] 的重组?@ 还是 & 作为语法 sigil 更合适?这些都需要后续实验验证。

BorrowSanitizer:从研究原型走向实用工具

BorrowSanitizer(原 "Emit Retags in Codegen")目标已被新的 2026 目标接管。Ian McCormack 的团队交出了几项硬进展:

  • 影子栈(shadow stack):采用与其他 LLVM sanitizer 不同的策略,在运行时追踪元数据,为垃圾回收铺路。
  • 错误报告:已能输出类似 Miri 的详细别名违规信息。
  • Miri 测试套件:80% 通过。
  • 使用方式简化:不再需要编译器插件,只需 -Zsanitizer=borrow 即可启用。
  • RustConf 演讲已获接受,9 月将公开分享结果。
# 未来预期用法(当前仍为实验性,API 未最终确定)
cargo bsan run --target x86_64-unknown-linux-gnu
# 或直接通过 rustc
rustc -Zsanitizer=borrow -Zsanitizer=borrow your_crate.rs

性能方面,初步测试显示 BorrowSanitizer 比 Miri 快一些但仍在同一量级。团队计划 2026 年先上游 LLVM 组件,再走 RFC 流程。

Polonius:"感觉可以稳定了"

Rémy Rakic 的措辞很直接:"#150551 已经落地,它感觉可以稳定了。当然,'stabilizable' 不等于 'stable',但这个目标已经达成。"

团队计划在 2026 年正式推进 Polonius 的稳定化。当前 alpha 版本在 crates.io 上最差的案例是一个 5K 行函数(42K loans、255K statements、125K outlives 约束),比 NLL 慢 60%。优化方向已明确:限制双向边的传播范围、统一仅赋值一次的局部变量的不变生命周期、简化 reservation 的 invalidation。

Pin 语义与借用检查

&pin 的借用检查算法正在迭代。Frank King 发现当前处理 pinned borrow 的方式可能有问题——无法区分"真正的 pinned borrow"和"从普通引用到 pinned 引用的 coercion"。后者不应阻止 T: Unpin 类型的移动,前者应该。这个区分对 pin coercion 的正确性至关重要。

已合并的工作包括:&pin (mut|const) T&(mut) T 之间的 coercion(当 T: Unpin),以及 Drop::pin_drop 的评审。

Reborrow Traits:等待评审与 derive 宏

Aapo Alasuutari 的 ReborrowCoerceShared traits 首个工作版本 PR 已提交。评审中浮现了一个大改动机会:将 Rvalue::Ref / ExprKind::Ref 泛化为同时覆盖引用和用户自定义引用类型。如果这成为阻塞项,目标将长期停滞。

团队希望有人帮忙实现 derive 宏,把以下重复代码简化:

// 当前需要手动实现
impl<'a> Reborrow for CustomMarker<'a> { }
impl<'a> CoerceShared<CustomMarkerRef<'a>> for CustomMarker<'a> { }
impl<'a, T> Reborrow for CustomMut<'a, T> { }
impl<'a, T> CoerceShared<CustomRef<'a, T>> for CustomMut<'a, T> { }

// 期望的 derive 形式
#[derive(Reborrow, CoerceShared(CustomMarkerRef))]
struct CustomMarker<'a> { ... }

#[derive(Reborrow, CoerceShared(CustomRef))]
struct CustomMut<'a, T> { ... }

derive 宏不需要做有效性检查(trait 本身会做),只需要生成正确的 impl 块。

Rust for Linux:编译器特性逐步稳定

Rust for Linux 的编译器特性目标有多项进入稳定化流程:

特性 状态
-Zdebuginfo-compression 稳定化提议已提交,有反馈待处理
-Zdirect-access-external-data 修复 PR 已合并,文档更新后即可稳定
-Zsanitize=kernel-hwaddress PR 已合并,文档清单待完成
--emit=noreturn 发现 rustc 层面信息不足,需 LLVM 提供
#![register_tool] RFC 在 Lang 团队讨论中,氛围积极

语言特性方面,arbitrary_self_types 的 autoderef chain 拆分 PR 正在评审;derive(CoercePointee) 在修复意外特化问题;cold_path 即将稳定,likely/unlikely 可能随之移除。团队还讨论了 niche 优化(指针低位嵌入数据)和 zerocopy vendoring 的方案。

其他值得留意的进展

  • cargo-script:FCP 已结束,edition 策略是最后的阻塞项。
  • build-std:RFC #3874 FCP 完成,即将合并;RFC #3875 还在处理反馈;Cargo 侧已有早期实现草图(cargo#16675)。
  • Reflection/comptime:MVP 已落地,社区贡献者正在添加数组、切片、原始指针、函数指针、struct/enum/union 等类型信息。
  • Const Generics:mGCA 大量改进(新表达式支持、dyn Trait<ASSOC=10> 兼容、ICE 修复);min_adt_const_params 接近 RFC 最终规格。
  • SVE/SME on AArch64:可伸缩向量类型已在 nightly 定义;stdarch intrinsics 补丁正在 CI 中;Sized Hierarchy RFC 在 Lang 团队设计会议中讨论了语法和迁移策略,倾向 "only bounds" 语法和 SizeOfVal 命名。
  • Unsafe Fields:RFC 已接受,Clippy 支持 PR 等待评审。
  • MIR move elimination:RFC 发布,移除了 activation/deactivation 概念,增加了 byref/byval 参数传递说明。
  • Cargo Build Dir Layout:细粒度锁定已合并到 nightly(-Zfine-grain-locking),目标已完成。
  • Cargo Build Analysis:原型完成,cargo report sessions/timings/rebuilds 可用,稳定化前需解决日志 schema、命令命名、嵌套 Cargo 调用等问题。
  • MemorySanitizer / ThreadSanitizer:MSan 和 TSan 的 Tier 2 target 已合并,下一步是稳定化。
  • std::offload:在 NVIDIA、AMD GPU 和 AMD APU 上测试,基准测试性能出色;新增调用 GPU vendor 库(如 cuBLAS)的 helper intrinsic。
  • std::autodiff:部分进入 CI,macOS 上因 LLVM 分发方式变更导致两次回退,进展较慢。

采纳建议与关注清单

如果你是库作者或底层开发者,以下几项值得现在就开始跟踪:

  1. 字段投影:在 nightly 上用 #![feature(field_projections)] 实验 FRT,思考你的类型是否需要 PinnableField 或其他字段级 trait。但注意该特性高度实验性,API 可能变动。
  2. BorrowSanitizer:如果你的库涉及复杂的别名模式(自引用、侵入式数据结构),关注 -Zsanitizer=borrow 的可用性,未来可作为 Miri 之外的运行时检查工具。
  3. Polonius 稳定化:2026 年可能进入 nightly 默认选项,届时某些目前被 NLL 拒绝的合法借用模式将能通过。
  4. build-std:RFC 即将合并,一旦落地,不再需要 -Zbuild-std hack 就能重建标准库,对嵌入式和自定义目标意义重大。
  5. Sized Hierarchy:如果你维护涉及 ?Sized 的泛型代码,关注 RFC #3729 的语法和命名讨论——SizeOfVal / MetaSized / Pointee 的最终选择会影响你的 API。

完整的目标状态列表和每个目标的跟踪 issue 可在 Rust 官方博客原文中查阅。许多目标已延续到 2026 周期,接下来的半年会看到更多从"实验"走向"可用"的转折。


相关推荐