写 Rust 的人,大概率都被借用检查器拦过:逻辑明明是对的,编译器就是不给过,最后只能改写法、加 clone(),或者捏着鼻子上 unsafe。8 月 4 日,Rust 官方博客宣布了一件事——下一代借用检查器 Polonius Alpha 在 nightly 通道默认启用了。博文第一句话是句憋不住兴奋的"You heard it right!"(你没听错)。知乎B站
这是自 2019 年 NLL 全量落地以来,Rust 编译器最重要的一次升级:一批被编译器拦了八年的"正确代码",终于能编译了。但这事在中文社区的讨论里也带着分歧——知乎相关提问下,点赞最高的评论直接发问:编译本来就慢得离谱,居然还要再慢 10-20%?知乎
到底值不值得关注?我把官方博客、项目目标文档、中文社区的深度梳理和 B 站的几期解读视频都翻了一遍,今天把三件事说清楚:它到底改了什么、代价有多大、你现在该不该动。
先说人话:借用检查器换代,换的是什么
Rust 的内存安全不靠垃圾回收,靠的是编译期的"借用"规则:只读引用可以多人同时持有,可变引用同一时间只能有一个。借用检查器就是执行这条规则的关卡。问题在于,这个关卡的"记性"有限,经常把安全的代码误判成危险的。
Rust 的借用检查器走过三代,一句话说清每一代的进化:
第一代 AST borrowck(2015 年随 1.0 发布):按代码块边界算借用活多久——只要还在块里,借用就算活着。非常保守,安全但烦人。
第二代 NLL(2019 年全量落地):把"活多久"细化到"最后一次使用点",一大批代码从此解锁。但它流不敏感:只要一个借用"有可能"活着,就认为它在所有分支路径上都活着。就像保安听说某个房间"可能"有人,就把整栋楼的走廊全锁了。
第三代 Polonius:流敏感分析,精确到每条分支分别计算。某个分支里根本不存在的借用,不再拖累另一条分支。

Polonius 这个项目 2018 年立项,提出者是 Rust 语言设计团队联合负责人 Niko Matsakis。理论其实 2018 年就齐了,中间卡了八年,卡的不是理论,是性能——早期用 Datalog 规则引擎实现,某些程序慢到没法用。2023 年团队换了新配方(在 NLL 之上做增量改造),2024 年做出位置敏感原型,2025 年 10 月 Polonius Alpha 合入编译器主分支,今年 7 月在 crates.io 下载量前 2 万的包上跑完性能测试后,终于拍板:8 月 4 日,nightly 默认启用。B站知乎
它解锁了什么:三类被拦了多年的"正确代码"
第一类,也是最经典的:get_or_insert 模式(官方叫 NLL Problem Case #3,学名"条件借用")。知乎写个函数:从 HashMap 里取一个值,取不到就插入默认值,然后返回这个值的可变引用。逻辑毫无问题,但 NLL 认为 get_mut 借出的引用在整条函数里都活着,于是插入那一步"和存活的借用冲突",编译不过。知乎这个坑有多普遍?社区甚至专门写了一个叫 polonius-the-crab 的库来绕它。B站Polonius 知道在"没取到"的那个分支里,那个借用根本不存在——直接放行。

第二类是随之打开的门:lending iterators(借出型迭代器,每次迭代返回指向容器内部元素的引用)。这种迭代器在别的语言里很常见,在 Rust 里因为借用检查过不去,几乎没法写。等 Polonius 稳定后,这类 API 设计才真正可行。
第三类是隐性收益:一批为绕开检查器而写的 unsafe 和别扭写法可以删掉了,API 设计也不用再为编译器扭曲。官方还特别说明:启用 Alpha 后,没有观察到任何诊断信息(报错提示)的变化——老用户不会看到陌生的报错。
大家最担心的代价:评论区说慢 10-20%,实测是 1.4%
先说那个吓人的数字哪来的:官方目标文档里确实写了,团队"愿意接受 10% 到 20% 的编译时间代价"来换表达能力。知乎这是预算上限,不是实测结果。
真正的实测数据,来自核心开发者 Rémy Rakic(网名 lqd)今年 7 月在 crates.io 下载量前 2 万的包上跑的一轮完整测试。知乎
平均编译时间增加 1.4%
75% 的包回归小于 2%
95% 的包回归小于 5%
绝大多数项目几乎无感。但坏消息也不藏着:99.9 分位的包慢 36%,最极端的个案——巨型函数、借用特别密集的代码——慢了 2.5 倍。团队也留了后手:未来可以先跑便宜的 NLL 分析,只有 NLL 判断不了的代码才动用更贵的 Polonius 分析,这种"分级"策略还能把代价继续往下压。
所以结论很清楚:如果你的项目是常规业务代码、CLI 工具、普通服务,编译时间的代价基本可以忽略;如果你的项目是借用密集的大型代码库(编译器、数据库内核这类),迁移前值得先量一把。

两个流传中的误会,顺手澄清一下
误会一:“rust-lang/polonius 这个仓库快一年没人提交了,项目是不是死了?” 恰恰相反——工作已经全部搬进了 rustc 主仓库,独立仓库只剩文档。知乎对一个实验项目来说,这是最好的结局:不再是"另一个项目",而是"编译器本身"。Reddit 上那个"Polonius 是不是死了"的帖子,可以散了。
误会二:“Alpha 就是完整版 Polonius?” 不是。Alpha 是团队选定的"要稳定的子集"。有些旧版完整版能编译的程序,Alpha 反而编不过——比如链表在 while let 循环里条件式地往下走。知乎反过来也有 Alpha 能过、旧版不能过的。它是权衡后的折中点,官方设计公理写得很直白:“别让完美成为优秀的敌人。”
你现在该做什么:分三种情况
如果你在 stable 上写代码(大多数人):什么都不用做,也不用为它切 nightly。等稳定版,但别把时间表当承诺——团队原本计划 2024 年就稳定,结果一路推迟,所以"2026 年底稳定"这个目标建议保持关注、别提前押注。观察信号:GitHub 追踪 issue #118 有逐月进展记录。
如果你本来就在用 nightly:你已经默认用上 Polonius Alpha 了。如果撞到了编译时间回归或行为问题,用 `-Zpolonius=off` 退回 NLL,并且建议把情况反馈给官方(GitHub 或 Zulip 社区)——这正是他们此刻最想收集的真实世界回归样本,你的反馈会直接影响稳定版的质量。知乎

如果你是库作者或维护借用密集的大型项目:不建议现在把 CI 切到 nightly,但可以在本地用 nightly 量一下编译时间,提前评估尾部风险。另外记住 polonius-the-crab 这类绕路库的存在——等 Polonius 稳定后,这些 workaround 就是可以删掉的技术债。
接下来值得盯的三件事
一是年底稳定能否兑现,这决定它什么时候真正进入所有人的默认工具链;二是性能分级优化的落地,决定那 0.1% 的尾部项目能不能被救回来;三是形式化进展——团队正在 a-mir-formality 项目里给 Polonius 建数学规范,还要写进 Rust 参考文档,这是 Rust "让规范可验证"的大方向。知乎
还有个容易被忽略的注脚:GCC 的 Rust 前端 gccrs 早就移植了旧版 Polonius 当借用检查器,2025 年 3 月随 GCC 15 的大补丁集合并。知乎B站一个编译器算法同时被两个编译器采用,本身就说明了它的地位。
最后说个彩蛋:Polonius 这名字来自莎士比亚《哈姆雷特》里的老臣波洛涅斯,他的名言是"Neither a borrower nor a lender be"——不要向人借钱,也别借钱给人。用在一个管"借用"的检查器身上,堪称完美命名。
八年,三轮实现方案,同一批人。借用检查器一直是 Rust 的护城河,也是它被诟病"难上手"的根源。Polonius Alpha 改变不了这条河的宽度,但它让过河的人少绕了很多路。值得蹲一个年底。