後端工坊 2026 年 9 月 9 日

2026-09-09 — Rust Never Type 十年落地穩定、LLVM 23.1.1 跨架構修補、NGINX Predicate Routing 原生化 API 路由

primary=https://github.com/rust-lang/rust/pull/155499 primary=https://github.com/rust-lang/rust/issues/35121 primary=https://github.com/llvm/llvm-project/releases/tag/llvmorg-23.1.1 primary=https://github.com/llvm/llvm-project/compare/llvmorg-23.1.0...llvmorg-23.1.1 primary=https://blog.nginx.org/blog/predicate-routing-for-native-handling-of-api-traffic primary=https://nginx.org/en/docs/http/ngx_http_core_module.html#location primary=https://nginx.org/en/docs/http/ngx_http_json_module.html

Rust 敲定十年懸案:Never Type ! 正式穩定,Fallback 語意全面轉向

rust-lang/rust PR #155499 · 2026-08-24

Rust 語言團隊已於 2026 年 8 月 24 日合併 rust-lang/rustPR #155499,正式將 never type(用驚嘆號 ! 表示、代表「永不返回」的型別)升級為穩定語言特性,預計隨 Rust 1.100.0 發布。這項改動同時把 never type 的型別推導 fallback 行為從 () 全面改為 !,並讓標準函式庫中的 Infallible 變成 ! 的型別別名。此提案源自 2016 年的 RFC 1216(追蹤議題 #35121),歷經十年、五次失敗的穩定化嘗試才落地。

背景:十年五次失敗的穩定化嘗試

Never type 用來標注「不可能回傳」的函式,例如 panic!() 或無窮迴圈,其型別可以無條件強制轉換(coerce)成任何其他型別。穩定化的真正難點不在型別本身,而在型別推導 fallback:當編譯器需要為一個完全未受約束的型別變數選擇具體型別時(例如某分支永不返回、另一分支又無上下文可推斷),舊版 Rust 一律 fallback 回 ()。這個舊行為與 never type 語意衝突,曾在 2018 年因相容性問題(#49593)導致一次穩定化被回退(PR #50121)。此後語言團隊改採漸進式做法,先透過 #148922 追蹤 fallback 改為 ! 的個別影響,才在今年完整合併。

核心改動:型別、Fallback 與 Infallible 三者一次到位

PR #155499 一次處理了三個互相牽連的變更。!」現在可以出現在任何型別位置並成為穩定特性,不再需要 #![feature(never_type)]。型別推導 fallback 目標也從 () 改成 !,且此改動不分 edition,對 2015 到 2024 全部版本一致生效,而非如原先 RFC 規劃僅在新 edition 生效。

第三個變更牽涉標準函式庫的型別關係。std::convert::Infallible 從獨立的空 enum 改為 ! 的型別別名,讓兩者語意徹底統一,不再是「同構但不同型別」的關係。作為配套,先前用來警示舊 () fallback 依賴的 dependency_on_unit_never_type_fallback lint 也隨之移除,因為新語意下該 lint 已無存在必要。

// 舊行為(fallback 到 ()):
fn diverges() -> ! { panic!() }
fn ambiguous<T: Default>() -> T { T::default() }

let x = if true { ambiguous() } else { diverges() };
// 型別無法從上下文推斷時,舊版一律當作 x: ()

// 新行為(fallback 到 !,Rust 1.100.0 起):
// 同一情境下 x 會被推斷為 !,
// 後續若把 x 當成具體型別使用,會在編譯期直接報錯,
// 而不是靜默套用 ()
項目舊行為新行為(PR #155499 後)
型別推導 fallback回退到 ()回退到 !,不分 edition
Infallible獨立空 enum! 的型別別名
相關 lintdependency_on_unit_never_type_fallback 存在該 lint 移除

影響範圍:生態系相容性與破壞性變更

語言團隊在合併前針對整個 crates.io 生態系執行 crater 相容性測試,結果顯示有 3,277 個套件出現迴歸,但團隊評估後認定這是可接受、且長期有益的破壞性變更。最直接受影響的是透過 use std::convert::Infallible::{self} 之類寫法明確匯入 Infallible 變體的程式碼,因為它從 enum 變成型別別名後不再具備可匹配的 variant。這項改動也會影響任何依賴舊 () fallback 的型別推導程式,相關案例可透過 #148922 追蹤。

原始來源:rust-lang/rust PR #155499Tracking Issue #35121 (RFC 1216)


LLVM 23.1.1 釋出:54 個修正涵蓋 X86、AArch64、LoongArch 與 Clang 前端

LLVM Project (GitHub Releases) · 2026-09-08

LLVM 專案於 2026 年 9 月 8 日發布 LLVM 23.1.1,是 23.1 系列的第一個修補版本(patch release)。此版本沒有新功能,只從 release/23.x 分支回攜(cherry-pick)了 54 個提交,涵蓋後端程式碼產生、Clang 前端與周邊工具鏈的錯誤修正。此版本與 23.1.0 之間的完整差異可見 GitHub 比較頁面

後端與程式碼產生修正

多個目標架構的程式碼產生器都收到獨立的正確性修正。X86 後端修正了 minimumnum/maximumnum 內建函式在零值修正(zero fixup)時的 NaN 處理錯誤,以及 LowerAVXCONCAT_VECTORS 在呼叫 ReplaceAllUsesWith 前未先收集所有子向量運算元的問題。AArch64 則修正向量轉純量位元遮罩(vectorToScalarBitmask)的型別使用,並為 SME 指令加上正確的排程述詞。LoongArch 修正了帶常數條件的 BRCOND 選擇邏輯,並補上 LASX 向量擴展所缺的模式;SPARC 則修正 inline assembly 重定位修飾符與一元補數立即值的剖析。

Clang 前端與工具鏈修正

Clang 前端方面,協程(coroutine)相關的 -Wunused-parameter 誤判被修正,C++20 modules 在合併來自 std 模組的預先定義宣告時的邊界情況也一併處理。針對 musl 平台,Driver 修正了搭配 stack protector 時未連結 libssp_nonshared.a 的問題;此外還從主線回攜了 C++26 fold expression 對 PackIndexingExpr 正規化的修正。工具鏈部分,clang-format 強化了星號與 & 符號的語意標註判斷,clang-tidy 修正了 readability-trailing-comma 對 designated initializer 的誤報,lldb 則修正了 SBEnvironmentSBFrame::GetValueForVariablePath 等多個 API 在特定輸入下的當機問題。

分類代表性修正
X86 / AArch64NaN 零值修正、AVX 向量合併、SME 排程述詞
LoongArch / SPARC / WebAssemblyBRCOND 選擇、inline asm 修飾符、RegStackify 支配走訪
Clang 前端協程警告誤判、C++20 modules 合併、C++26 fold expression
工具鏈(lldb / clang-format / clang-tidy)API 當機修正、格式化標註強化、lint 誤報修正

影響範圍

作為 patch release,23.1.1 不含任何新增功能或行為變更,僅回攜經釋出管理者(release manager)審核過的錯誤修正,適合已使用 23.1.0 的專案直接升級。此版本同時包含兩筆 revert:一筆撤銷了「在 -Wall 下重新啟用 -Wunused-template」的重新合併,另一筆則撤銷了先前「在 Darwin 停用 flang」的撤銷,顯示部分實驗性變更仍在來回調整中。受影響最廣的是同時針對 X86、AArch64、LoongArch、SPARC、WebAssembly、Mips 等多目標架構交叉編譯的專案,以及依賴 lldb Python/Swift API 做除錯自動化的工具鏈。

原始來源:LLVM 23.1.1 Release23.1.0...23.1.1 Diff


NGINX 1.31.5 推出 Predicate Routing:用變數斷言取代 njs 腳本判斷 API 流量

NGINX 官方部落格 · 2026-09-08

NGINX 1.31.5 已於 2026 年 9 月 2 日發布,新增 predicate location(斷言型 location),讓 location 區塊除了比對 URI 前綴或正則表達式外,也能直接比對任意 nginx 變數。同版本一併推出 ngx_http_json_moduleclient_body_early_read 指令,三者搭配可讓 API 流量依 HTTP 方法、標頭或 JSON 請求內文原生路由,不必再靠 njs 腳本判斷。

核心改動:location 語法新增第三種比對方式

location 指令原本只支援前綴字串、正則表達式(~/~*)與具名 location 三種形式,1.31.5 新增第三種比對邏輯:在變數前加 $ 前綴即成為 predicate location,例如 location $restricted_methods { ... }。比對規則是「變數值非空字串且不等於 0」即視為命中。比對優先順序維持既有邏輯:先找最長前綴比對,再依序檢查正則表達式,全部不命中才輪到 predicate location;若最長前綴帶有 ^~ 修飾符,則正則與 predicate location 都會被跳過。

map $request_method $restricted_methods {
    POST    1;
    PUT     1;
    DELETE  1;
    default 0;
}

location $restricted_methods {
    # 命中條件:非 GET/HEAD 等方法
    deny all;
}

搭配 JSON 模組解析請求內文

新加入的 ngx_http_json_module 提供 json_set $variable $source path; 指令,可從存放在某變數中的 JSON 文件依路徑取出欄位值並存成新變數,文件在每個請求中只會被解析一次,實際解析時機延遲到任一對應變數第一次被讀取為止。由於請求內文預設要到內容處理階段才可讀,搭配路由判斷時需另外開啟 client_body_early_read on;,讓 nginx 在 location 比對前就先讀入 request body,predicate 才能拿到由 $request_body 衍生出的變數值。

client_body_early_read on;
json_set $vip $request_body user.params.vip;

location $vip {
    return 200 "VIP user\n";
}

影響範圍

此改動的直接效果是把過去只能靠 njs 腳本或第三方模組完成的內容路由邏輯,收斂進原生設定檔語法。過去要依 HTTP 方法、自訂標頭或請求內文欄位分流,通常得寫 js_content/js_set 腳本再手動 returnproxy_pass;現在可直接用 map 搭配 json_set 產生的變數當作 location 條件。ngx_http_json_module 預設不隨標準包編譯,需要在編譯時加上 --with-http_json_module 參數才能啟用。1.31.5 同版本另包含控制 API(control API)功能,以及多項 HTTP/2、HTTP/3、slice、memcached 模組的錯誤修正。

原始來源:NGINX 官方部落格ngx_http_core_module 文件ngx_http_json_module 文件


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