本文永久链接https://tonybai.com/2026/08/20/rust-polonius-alpha-borrow-checker-nightly

大家好,我是Tony Bai。

【导读】

Rust 最让人又爱又恨的「借用检查器」,这次真的要迎来十年来最大的一次升级了。北京时间 8 月 4 日,Rust 官方博客宣布:下一代借用检查器 Polonius Alpha 已经登陆 Nightly 版本,预计将在今年年底转正为 Stable。这意味着,那些曾经被编译器无情拒绝、却明明「逻辑上完全安全」的代码,很快就能顺利通过编译。

【文章重点】

  • Rust 现在的借用检查器 NLL(Non-Lexical Lifetimes)是「流不敏感」的,会误杀一批实际上安全的代码;
  • 新一代借用检查器 Polonius 历经2018 年首次提出 → 性能翻车 → 2023 年推倒重来,终于在 2026 年迎来 Alpha 版本;
  • Polonius Alpha 的核心能力是「流敏感」(flow-sensitive)分析,能够理解借用在不同代码分支中的真实生命周期;
  • 它不是万能的:一些老版本 Polonius 能编译的代码,Alpha 反而编译不过,官方也坦承这只是一个「子集」;
  • 官方公布了对 crates.io 上万级热门库的性能测试数据,绝大多数库的编译时间几乎不受影响;
  • 目前只在 Nightly 上开启,Stable 用户不受影响;开发者可以通过 -Zpolonius=off 一键关闭。


一个曾被借用检查器「冤枉」的场景

写过 Rust 的人,多少都经历过这样的瞬间:明明代码逻辑上完全没问题,编译器却坚决不放行,报出一长串关于生命周期(lifetime)的错误信息。你不得不加一堆看起来多余的克隆(clone)、重构函数结构,甚至绕一个大圈子,才能让编译器「满意」。

这种体验,很大程度上要归咎于 Rust 现有借用检查器的一个先天局限:它只会「机械地」看一个变量的生命周期跨度,却不会「聪明地」根据代码的执行路径去判断这个借用到底还有没有在用。

而 Rust 官方博客在 2026 年 8 月 4 日发布的文章《Enabling the next iteration of the borrow checker on nightly》,宣布的正是解决这个老问题的方案:新一代借用检查器 Polonius,其阶段性成果 Polonius Alpha,已经在 Nightly 版本上开启,目标是在今年年底前转正为 Stable。

借用检查器简史:一场跨越十年的接力赛

要理解 Polonius Alpha 的意义,得先简单回顾一下 Rust 借用检查器的演进历史。

简单来说:

  • AST borrowck(2015 年 Rust 1.0 起):Rust 最早期的借用检查器,规则非常保守,很多安全代码都无法通过,2019 年被正式淘汰;
  • NLL(Non-Lexical Lifetimes):2019 年起成为默认检查器,2022 年彻底取代 AST borrowck,是我们今天在 Stable Rust 上用的检查器;
  • Polonius(原始版本):2018 年从 NLL 项目中分离出来的研究方向,采用了一种基于别名(alias-based)的全新形式化方案。它确实能编译通过一些 NLL 拒绝的安全代码,但性能是硬伤——不少程序的检查速度比 NLL 慢得多,慢到根本没法在生产环境使用;
  • Polonius(2023 年新方案):官方推倒重来,设计了一套「基于现有 NLL 实现做最小改动」的新公式化方案,既能获得更强的表达能力,又不至于伤筋动骨影响性能;
  • Polonius Alpha(2026 年):新方案中已经验证「没有已知遗留问题」的一个子集,率先在 Nightly 上开放测试,冲刺年底 Stable。

值得一提的是,Rust 团队原本计划在 2024 年就完成这次新方案的稳定化,但由于各种优先级调整被推迟了两年——这也从侧面说明,编译器底层机制的升级,远比表面上看起来要复杂得多。

Polonius Alpha 到底新在哪:从「流不敏感」到「流敏感」

Polonius Alpha 相对 NLL 最核心的能力提升,官方用一句话概括:对生命周期的「outlives」关系做流敏感(flow-sensitive)分析

这句话听起来有点抽象,我们用两个官方给出的代码例子来直观感受一下。

例子一:最小复现

fn reborrow(a: &mut u8) -> &mut u8 {
    let b = &mut *a;
    if true { b } else { a }
}

这段代码在当前 Stable Rust(NLL)下会编译失败,但在 Polonius Alpha 下可以顺利通过。原因在于:b 是从 a 重新借用出来的,NLL 没办法精确地区分「if 分支用 b」和「else 分支用 a」这两条路径上借用关系的差异,只能保守地报错。

例子二:更贴近真实业务的场景

fn get_mut_or_default<'r, K: Hash + Eq + Copy, V: Default>(
    map: &'r mut HashMap<K, V>,
    key: K,
) -> &'r mut V {
    match map.get_mut(&key) {
        Some(value) => value,
        None => {
            map.insert(key, V::default());
            map.get_mut(&key).unwrap()
        }
    }
}

这是一个「有则取值、无则插入默认值再取值」的经典模式(类似 entry API 想手写实现的场景)。在 NLL 下,这段代码会编译失败,报错原因是:map.get_mut(&key) 产生的可变借用,由于返回类型标注了 &'r mut V,编译器会认为这个借用「活」到了整个函数结束——哪怕它其实只在 Some(value) 分支里被用到。既然编译器认为这个借用还「活着」,那 None 分支里再次调用 map.insertmap.get_mut 就会被判定为「借用冲突」,从而报错。

用一张示意图来说明这个问题:

简单说:NLL 只会看一个借用「理论上可能活多久」,而 Polonius Alpha 会真正跟踪这个借用在每一条具体执行路径上「实际有没有在用」。这正是「流敏感」和「流不敏感」的差别,也是 Polonius Alpha 真正的价值所在。

对大量 Rust 开发者来说,这个改动最直接的感受会是:以前那些「你必须重构成两个函数」、「你必须多克隆一次」、「你必须用 entry API 而不能手写等价逻辑」的场景,很多都会被解锁。

不是全能选手:Polonius Alpha 依然会拒绝的代码

需要泼一盆冷水的是,Polonius Alpha 并不是终极形态,官方也在博客里非常坦诚地指出了它的局限。

早期那个「基于别名」的原始 Polonius 实现(也就是文中说的 legacy Polonius),虽然性能不达标,但它的表达能力其实更强,能编译通过一些 Polonius Alpha 依然会拒绝的代码。官方举了这样一个例子:

struct X { next: Option<Box<X>> }

fn conditional() {
    let mut b = Some(Box::new(X { next: None }));
    let mut p = &mut b;
    while let Some(now) = p {
        if true {
            p = &mut now.next;
        }
    }
}

这段涉及链表结构反复重新借用的代码,legacy Polonius 能够编译通过,但 Polonius Alpha 目前还不行。这也是为什么它被命名为「Alpha」而不是「正式版 Polonius」——它是新公式化方案里,官方评估「已经没有已知遗留问题、可以安全稳定化」的一个子集,而不是 Polonius 理论上能力的完全体。

有意思的是,官方也补充说明:反过来的情况同样存在,有一些代码是 Polonius Alpha 能编译通过、但 legacy Polonius 编译不了的。所以严格来说,Polonius Alpha 并不是 legacy Polonius 的一个真子集,而是两套并不完全重合的能力集合。

性能怎么样:万级 crates 实测数据

「流敏感」分析听起来工作量更大,会不会拖慢编译速度?这是社区最关心的问题之一,官方也专门用了一个章节来回应。

结论是:Polonius Alpha 在计算量上肯定不会比 NLL 少(只会相等或更多),因此团队重点关注了潜在的性能回归风险

官方对 crates.io 下载量最高的一万个 crate 做了实测对比,结果显示,出现「显著」编译耗时回归的库占比很低,即便被判定为「显著回归」的库,回归幅度通常也相当有限。

Top 10000 crates 编译耗时回归分布散点图

图中每个点代表一万个下载量最高的 crate 之一;黑线是官方设定的「显著回归」阈值(30 秒以内按二次曲线缩放、相当于 1% 的回归幅度);红点为超过该阈值的 crate;横轴为该 crate 在 NLL 下的(仅自身、不含依赖的)编译耗时,纵轴为 Polonius Alpha 相对 NLL 的耗时比值。

回归幅度最大的 5 个 crate 明细表

除了这一万个热门库之外,官方还专门排查了「借用数量特别多」的一批代码,这类极端场景下观察到的最差回归幅度是 2 到 3 倍。团队已经对这些回归的成因做了初步排查,并在评估修复方案;不过即便部分回归短期内无法修复,考虑到这类场景本身相当罕见,且 Polonius Alpha 带来的能力提升足够可观,官方认为这个取舍是合理的。

现在能用了吗:如何试用、如何一键关闭

需要再次强调:这次变更目前只在 Nightly 版本上开启,Stable 用户完全不受影响,可以放心继续使用现有工作流。

如果你正在用 Nightly,并且不想启用 Polonius Alpha,只想继续使用 Stable 版本的 NLL,可以通过以下任意一种方式关闭:

方式一:命令行参数

rustc -Zpolonius=off

方式二:环境变量

RUSTFLAGS=-Zpolonius=off

方式三:项目级配置(.cargo/config.toml

[target.x86_64-unknown-linux-gnu]
rustflags = ["-Zpolonius=off"]

官方也特别提到:如果你确实因为某些原因不得不关闭 Polonius Alpha,非常欢迎到 GitHub issueZulip 讨论区 反馈原因,这些反馈将直接影响正式稳定化前的打磨方向。

接下来的计划

按照官方的规划,未来几个月团队会重点做三件事:

  1. 持续监控 GitHub 和 Zulip 上关于 Polonius Alpha 的问题反馈;
  2. 着手修复已知的性能回归;
  3. 补齐关于 Polonius 实现的内部文档。

以上工作全部完成之后,团队的目标是在今年年底前完成 Stable 稳定化

同时官方也很坦诚地表态:虽然目前仍有一些「大家希望能编译通过、但 NLL 和 Polonius Alpha 现在都还编译不过」的代码模式存在,但在 Polonius Alpha 稳定化之后,团队近期并没有继续在 Polonius 上做新功能开发的具体计划。团队会在一段时间内继续做性能优化和回归修复,但会把更多精力转向其他优先级更高的工作。换句话说,Polonius 后续会不会有「Beta」「更完整版」,目前官方的表态是「未来某个时间点会回来做,但不是现在」。

小结:这对普通 Rust 开发者意味着什么

对绝大多数 Rust 开发者而言,Polonius Alpha 稳定化之后,最直观的感受会是:一部分曾经写起来别扭、需要绕路才能通过编译的代码,会变得更自然。尤其是涉及 matchif-else 分支中可变借用「按路径取用」的场景(比如上文的 get_mut_or_default 模式),会有实打实的体验提升。

而对于关心底层原理的开发者来说,这次升级也是一个很好的窗口,去理解 Rust 借用检查器背后「流不敏感」与「流敏感」这两种分析范式的本质区别,以及一门系统级语言的核心机制,是如何在长达十年的时间里,被一步步打磨到今天这个程度的。

Polonius Alpha 现在已经可以在 Nightly 上尝鲜,如果你的项目恰好有相关代码模式的诉求,不妨去试一试,说不定能帮官方团队提前发现一个隐藏的坑。

参考资料:


还在为写 Agent 框架频频死循环、上下文爆炸而束手无策?我的新专栏 从0 开始构建 Agent Harness 将带你:

  • 抛弃臃肿框架,回归“驾驭工程 (Harness Engineering)”的第一性原理
  • 用 Go 语言手写 ReAct 循环、并发拦截与上下文压缩引擎等,复刻极简OpenClaw
  • 构建坚不可摧的 Safety Middleware 与飞书人工审批防线
  • 在底层实现 Token 成本审计、链路追踪与自动化跑分评估
  • 从“调包侠”进化为掌控大模型边界的“AI 操作系统架构师”

扫描下方二维码,开启从 0 开始构建Agent Harness 的实战之旅。


「Go & AI 精进营」已全面升级为「Go, Rust & AI 精进营」知识星球,快来加入星球,开启你的技术跃迁之旅吧!

我们致力于打造一个高品质的 现代系统级开发(Go / Rust)前沿 Agentic AI 工程实践 平台。在这里,你将获得:

  • 体系化 Go 核心进阶内容: 深入「Go原理课」、「Go进阶课」、「Go避坑课」等独家深度专栏,夯实你的 Go 语言内功。
  • 硬核 Rust 专项实战赋能: 同步解锁全年 54 讲独家专栏「事不过三:Rust 系统级入门实战课」,通过 4 个里程碑项目(命令行工具、KV引擎、多线程Web服务、异步Redis),带你彻底攻克所有权与并发高山,拿下 Rust 核心壁垒。
  • 前沿 Agentic AI 落地实践: 紧跟时代步伐,系统学习「Agent开发实战课」、「Agentic软件工程课」、「Claude Code开发工作流实战」、「Harness工程设计」等,掌握 AI 时代的系统架构新技能。
  • 星主 Tony Bai 亲自答疑: 遇到疑难杂症?星主第一时间为你深度解析,扫清 Go、Rust 与 AI 实践中的学习与工程障碍。
  • 高活跃 Gopher & Rustacean 交流圈: 与众多优秀的技术极客探讨系统设计、分享前沿心得、碰撞思想火花。
  • 独家资源与专栏首发: 博客深度长文、专栏教程更新、精选技术资源,星球会员第一时间触达,加入星球即可免费阅读全套进阶专栏!

衷心希望**「Go, Rust & AI 精进营」**能成为你拓宽技术边界、持续精进与交流的温暖港湾。让我们在此相聚,享受代码与工程之美以及技术精进的快乐!欢迎你的加入!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。