Rust 開放實驗版 Generic Const Args,用 gca! 把泛型參數寫進 const 引數
Inside Rust Blog(Const Generics Project Group,BoxyUwU 代筆)· 2026-10-02
Rust 的 const generics 長年只允許兩種 const 引數:裸的泛型參數 { N },或完全具體的常數 { 1 + 1 }。Generic Const Args(GCA)是一組 nightly 實驗功能,要讓 [u8; T::NUM_BYTES] 這類「含泛型參數的表達式」成為合法的 const 引數,並打算取代 generic_const_exprs。
Const Generics Project Group 在 2026-10-02 於 Inside Rust 發文介紹各個 feature gate 目前能做什麼、不能做什麼。文中明說這些功能還離穩定化很遠。
原本的問題
穩定版的 const 引數幾乎不能組合。想寫 [u8; N + 1] 或 [u8; T::NUM_BYTES],穩定版一律拒絕,只能繞路:把長度當額外參數傳入,或改用 Vec。
既有的 generic_const_exprs 自 2021 年 min_const_generics 穩定化後就一直存在,文章稱 GCA 的設計深受它的經驗影響,但 GCA 會讓它成為多餘。
核心改動:三個 feature gate
GCA 以 gca!(..) 巨集標出「這是一個含泛型參數的 const 引數」,再用不同 gate 控制能放什麼進去。
gca_adts:可在 const 引數裡建構陣列、tuple 與 struct/enum,內容可含泛型參數。gca_const_items:允許 associated、free、inherent 的 const item 出現在型別系統中,等於間接容納任意表達式。需要不穩定旗標-Znext-solver。gca_min_const_items:只接受右手邊是gca!(..)的 const item,不需要-Znext-solver。不透明的 const(右手邊不是gca!(..))會被拒絕。
以下是 gca_adts 與 gca_const_items 的用法對照:
// gca_adts:把泛型參數裝進 struct / 陣列再當 const 引數
#![feature(gca_adts, adt_const_params)]
accepts::<gca!(TupleStruct(N))>();
accepts_arrays::<gca!([N1, 12])>();
// gca_const_items:用 associated const 當陣列長度
fn example<T: Trait>() -> [u8; gca!(T::ASSOC)] { [0x1; _] }另有屬性 #[rustc_always_gca],可強制 trait 的 associated const 必須以 gca!(..) 實作。文章也提到 gca_const_items 能支援 associated const binding,以及帶 associated const 的 trait 與 dyn 相容。
目前的限制
gca!(..) 內目前不能做算術或函式呼叫。允許的是泛型參數,以及 struct、enum、陣列、tuple 的建構;gca!(1 + 1)、gca!(foo()) 與陣列 repeat 寫法 [N1; 2] 都不行。
| 寫法 | 目前狀態 |
|---|---|
gca!(TupleStruct(N)) | 可用(gca_adts) |
gca!([N1, 12]) | 可用(gca_adts) |
gca!([N1; 2]) | 不支援 |
gca!(1 + 1)、gca!(foo()) | 不允許 |
文章給的繞法是:把不支援的表達式寫進一個 const item,再靠 gca_const_items 在型別中引用它。
為什麼還需要巨集
實驗性的 gca_macroless_args 與 gca_macroless_items 想省掉 gca!(..),讓 [u8; T::ASSOC] 直接成立。團隊自承這兩者「很實驗」且運作不佳。
根本困難在語法歧義,下例中兩個呼叫形式相同、需求卻相反:
fn Bar(_: usize) -> usize { 1 }
// Bar(ONE) 是函式呼叫,不能是 gca!(..)
// Foo(N) 是建構子,必須是 gca!(..)編譯器在解析階段分不出 Bar(ONE) 與 Foo(N),所以目前需要明確標記。
影響範圍
- 依賴
generic_const_exprs的 nightly crate(例如以[u8; N + 1]做 buffer 的庫):GCA 預定取代它,可開始用gca_min_const_items試改,並依文章提供的 experience report 範本回報使用心得。 - 穩定版使用者:不受影響,文章表示短期內還不會提出 RFC,離穩定化還有一段時間。
- 想把 trait 的 associated const 當長度的人:需用
gca_const_items,並承擔-Znext-solver的不穩定性;只想先試的話,用gca_min_const_items並讓 const 右手邊寫成gca!(..)。
文章把完整設計目標列在 Const Generics project goal,初始實作者為 @camelid,後續實作與設計由 @khyperia 負責。此設計首度討論於 2024 年 6 月的 RustFest Zürich。
原始來源:Generic Const Args and You、Const Generics project goal、GCA experience report