後端工坊 2026 年 8 月 22 日

2026-08-22 — Rust 編譯器雙重進展:新一代 trait solver 上 nightly、函式多載進入試驗

primary=https://blog.rust-lang.org/2026/08/21/enabling-next-solver-on-nightly/ primary=https://github.com/rust-lang/rust/issues/160895 primary=https://blog.rust-lang.org/inside-rust/2026/08/19/overloading-experiment/ primary=https://github.com/rust-lang/rust/issues/153629 primary=https://github.com/rust-lang/rust/pull/160882 primary=https://github.com/rust-lang/rust/pull/158645

Rust 新一代 trait solver 登上 nightly,四年重寫牽動編譯器核心

Rust Blog · 2026-08-21

2026 年 8 月 21 日,Rust 官方部落格宣布新一代 trait solver(next-generation trait solver)已在 nightly 編譯器上以 -Znext-solver=globally 預設啟用。這項工作源自 rust-lang/trait-system-refactor-initiative 專案近四年的重寫,取代原本負責證明 where-clause、正規化 associated type 的型別系統元件。追蹤議題 #160895 將此形容為「Rust 穩定發布以來對編譯器最大規模的單一改動」。

背景

trait solver 是編譯器判斷「某型別是否滿足某個 trait bound」的核心元件,每次呼叫泛型函式、每次型別推導都要經過它證明。舊 solver 採遞迴式證明,遇到高階生命週期(HRTB)、遞迴 trait bound 或 associated type 正規化時容易出現不精確甚至錯誤的判定,也難以擴充新特性。新 solver 改用可重跑、可快取的求解迴圈(fixpoint 迭代),讓證明過程更接近形式化邏輯求解器,並統一原本分散在多處的正規化邏輯。

核心改動

新 solver 帶來數項可觀察的行為差異,多數屬於修正舊 solver 的不精確推導:

  • higher-ranked associated type 在 for<'a> binder 下的推導修正
  • trait solver 的 cycle(循環證明)處理方式調整
  • 遞迴呼叫下 return-position impl Trait 的處理修正
  • 遞迴深度追蹤變嚴格,暫以 future-compatibility warning 形式提示

編譯器提供旗標控制新舊行為的套用範圍,可寫入 .cargo/config.toml

# 全域啟用新 solver(nightly 目前預設值)
-Znext-solver=globally

# 僅在 coherence 檢查沿用新 solver,等同停用新行為
-Znext-solver=coherence

影響範圍

追蹤議題盤點了目前受影響的套件,其中部分需等待上游修補:

套件現象
bevy_ecs編譯失敗
minijinja編譯失敗
wgpu編譯失敗
generic-arrayfuture-incompat warning

效能方面多數 crate 未見退化,但重度依賴 trait 求解的專案如 datafusion,第三方 benchmark 顯示編譯時間有 8 倍以上加速。開發者可執行 rustup update nightly 立即測試,遇到不相容行為可依 bug report template 回報至 issue tracker。

原始來源:Rust BlogTracking Issue #160895


Rust 以 splat attribute 試驗有限多載,鎖定 FFI 呼叫的自然寫法

Inside Rust Blog · 2026-08-19

2026 年 8 月 19 日,Inside Rust Blog 宣布 Rust 語言團隊與 Rust Foundation 的 Rust-C++ Interop Initiative 合作,開放社群在 nightly 編譯器上試驗一種有限的函式多載機制,內部代號 rustc_splat,正式 feature gate 為 splat。目標情境是 FFI 綁定:讓呼叫端能寫成 hypot(2.0, 3.0, 6.0),而非目前需靠 trait 技巧包裝成的 hypot((2.0, 3.0, 6.0))。追蹤議題為 #153629,狀態標記 S-tracking-impl-incomplete

規格細節

機制建立在既有 tuple trait 之上,以 attribute 標記某個 tuple 型別參數可在呼叫端攤平:

fn foo(#[splat] (t, u, v): (T, U, V)) { ... }

// 呼叫端可直接攤平參數,而非傳入 tuple
foo(2.0, 3.0, 6.0);

編譯器依 tuple-based dispatch 從多個多載中選出「多數開發者會預期」的版本,而不必像現行做法一樣,讓函式作者手動實作多個 trait 再靠型別推導分派。這對 FFI 特別重要:許多 C/C++ 函式庫本身就以多載或不同參數個數提供同名函式(例如 libm 的 hypot 系列),過去 Rust 綁定只能各自取不同名稱,現在可以在 splat 語法下對應同一個呼叫端寫法。啟用需在 crate 層級加上 #![feature(splat)],目前功能仍不完整,尚未經過 RFC 審核。

  • 已落地:no-op feature gate 與實驗語法
  • 已落地:僅限 tuple 的 splatting 與型別檢查
  • 已併入:rustdoc 支援(PR #160882,8 月 12 日)
  • 已併入:函式指標支援(PR #158645
  • 待辦:codegen 階段的 de-tupling 最佳化、v0 symbol mangling 文件化、最終命名定案

影響範圍

此功能自 2026-07-31 起隨 nightly 提供,目前僅限實驗用途,不影響 stable/beta 通道。社群可透過 rustfoundation/overloading-macros、overloading-examples 兩個 repo 測試巨集面向的改寫效果,回饋管道為 rust-lang/rust 的 issue 或 Zulip #t-lang/interop 頻道。

原始來源:Inside Rust BlogTracking Issue #153629


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