後端工坊 2026 年 8 月 5 日

2026-08-05 — Rust 借用檢查器換代 Polonius Alpha 與 Linux process-builder API 首次現身

primary=https://blog.rust-lang.org/2026/08/04/enabling-polonius-alpha-on-nightly/ primary=https://github.com/rust-lang/rust/issues/160456 primary=https://lwn.net/Articles/1086330/ primary=https://lwn.net/Articles/1076018/

Rust 借用檢查器換代:Polonius Alpha 登上 nightly

Rust Blog · 2026-08-04

2026 年 8 月 4 日,Rust 官方部落格宣布在 nightly 編譯器上啟用 Polonius Alpha,這是借用檢查器自 2018 年非詞法生命週期(NLL)之後最大幅度的一次重寫。此變更目前只在 nightly 生效,團隊目標是在 2026 年底前完成穩定化。啟用後預設開啟,可透過 -Zpolonius=off 停用。

背景

NLL 讓借用檢查改採流程無關(flow-insensitive)的生命週期外插分析,解決了詞法生命週期時代大量誤判的問題,但仍會拒絕部分實際安全的程式。Polonius 專案由 NLL 拆分而出,2023 年提出的新表述被稱為「Polonius Revisited」,關鍵在於只需對既有 NLL 實作做最小幅度的重新架構,就能支援流程敏感(flow-sensitive)的外插關係檢查。

核心改動

流程敏感分析讓借用檢查器能區分同一個借用在不同執行路徑上的存續期間,不再把 matchif 的所有分支視為同一條生命週期。以下函式在 NLL 下會被拒絕,因為編譯器假設 map.get_mut(&key) 借出的參照貫穿兩個分支,但 Polonius Alpha 能正確編譯它

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

效能與限制

團隊對下載量前 10,000 個 crate 做了編譯測試,發現顯著效能倒退的案例相對少見;在前 10,000 名之外,借用數量特別多的 crate 觀察到最差 2–3 倍的編譯時間倒退。Polonius Alpha 並非在所有情況下都優於原始 NLL,部分過去能通過早期 Polonius 原型的程式,在 Alpha 版本下反而無法編譯,例如以下走訪鏈結串列的寫法:

struct X { next: Option> }

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;
        }
    }
}

影響範圍

後續工作集中在追蹤 nightly 上回報的借用檢查錯誤與效能倒退,進度記錄在追蹤議題 #160456;啟用本身由 rust-lang/rust#159343 這個 PR 完成,並經編譯器團隊的主要變更提案(MCP)#1015 核准。團隊目前沒有在穩定化之後立即擴充 Polonius 新功能的計畫,穩定化前的首要目標是把既有回歸與效能問題處理完。

原始來源:Rust BlogTracking Issue #160456


Linux 核心浮現首版 process-builder API 雛形

LWN.net · 2026-08-04

2026 年 8 月 4 日,LWN 報導 Linux 核心開發者 Li Chen 提出一組新的 patch series,示範 process-builder API 在 Linux 上可能的樣貌。這延續今年 6 月〈Moving beyond fork() + exec()〉一文中,Chen 的 spawn-template 提案遭拒後,依核心維護者 Christian Brauner 建議方向重新設計的成果。這組 patch series 目前仍是初版,尚未進入合併討論。

背景

傳統 fork()+exec() 模式的問題在於 fork() 必須複製整個父行程狀態(包含記憶體),而這份複製資料在 exec() 覆蓋掉行程影像後立刻被丟棄。Chen 較早提出的 spawn-template 方案spawn_template_create() 建立可重複使用的可執行檔快取,再透過 spawn_template_spawn() 搭配 spawn_template_action 陣列指定每次呼叫要調整的檔案描述符與訊號處理,實測效能提升約 2%,但最終被核心維護者否決。

核心改動

Brauner 當時提出的替代方向,是把行程建立包裝成建構器(builder)風格的 API,建立在既有的 pidfd 抽象之上:先擴充 pidfd_open() 使其能建立一個空的行程,再透過類似 fsconfig() 的新系統呼叫 pidfd_config() 逐步設定這個行程的環境變數、可執行影像等內容。這個設計的目標之一是讓 posix_spawn() 終於能在使用者空間有原生實作,不必再靠包裝 fork()/exec() 完成。Chen 隨後同意這個方向並表示會依此繼續開發,八月發出的這組 patch series 就是這條路線下的第一次具體實作嘗試。

影響範圍

由於是初版提案,spawn-template 系列的三個系統呼叫不會進入核心;若 Chen 這條路線後續成熟,Linux 有機會第一次擁有不假手 fork()/exec() 的原生 posix_spawn() 實作,也會讓 glibc 等使用者空間函式庫的行程建立程式碼得以簡化。目前這組 patch 仍在 mailing list 討論階段,pidfd_config() 的完整參數配置項目、以及訊號與命名空間等進階設定要如何逐步疊加,都還未定案。

原始來源:The beginning of a process-builder APIMoving beyond fork() + exec()


End of article
0
Would love your thoughts, please comment.x
()
x