
2026/09/09 20:57
Rust のニバー型を安定化する
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Rust 2024 は、
!(「never」型) を安定化させることで大きな転換点となります。これは存在しない値を示すこの型の導入により、以前のデフォルトの戻り値である() (ユニット型)が置換され、到達不可能なエラー分岐を最適化しコード生成を簡素化することを目的としています。Rust 1.99 以降からは、曖昧な式に対して推論されるデフォルトが ! に変更されるため破壊的変更が発生します。これにより、古いデフォルト挙動に依存していた既存の汎用型コードが機能しなくなる可能性があります。これらの問題に対処するためには、プログラマーは明示的にジェネリックを使用して戻り値の型を指定するか、暗黙的な推論に頼らずパターンのマッチングを利用する必要があります。当初テスト段階で数千の crates が検出されましたが、実際に修正が必要な破壊的変更は僅かでした。コミュニティは主要なライブラリへのバッチバックポートを進めており、この移行を円滑に行っています。開発者は以下のどちらかを選ぶ必要があります:以前の Rust 1.98 を继续使用するか、新しい標準を採用してデッドコードエリミネーションを簡素化し、将来的な汎用型プログラミングタスクにおけるコンパイル効率を向上させるためにプロジェクトを更新することです。
Text to translate:
Rust 2024 marks a major shift by stabilizing the "never" type (
!), which signifies that a value never exists. This change replaces the previous default fallback type, (), specifically to optimize unreachable error branches and simplify code generation. Starting with Rust 1.99, developers can expect breaking changes where ambiguous expressions now infer ! instead of (). Consequently, existing generic code may fail if it relies on the old default behavior. To resolve these issues, programmers must explicitly specify return types using generics or utilize pattern matching rather than relying on implicit inference. While thousands of crates were initially flagged during testing, only a handful required full breaks to be fixed. The community is actively backporting updates to popular libraries to smooth this transition. Developers face a choice: stick with the previous version, Rust 1.98, or update their projects to embrace the new standard that streamlines dead code elimination and enhances compiler efficiency for future generic programming tasks.本文
Rust で「永らえない型(!)」が安定化された背景と課題
概要
- 2024 年 8 月 24 日、Rust コンパイラーへの寄稿者「waffle」により、長らく内部利用のみだった**「永らえない型(never type, !)」**が正式に安定化されました。
- これまでに2 年以上の議論と検証を経ての実現です。
- 前世代のエディション互換性を損なう可能性や、既存コードへの影響を慎重に検討し、Craterなどのツールを用いて壊れるライブラリを特定・修正するプロセスを踏みました。
なぜ「永らえない型」が必要なのか?
1. 実用的な理由:効率的なジェネリックコード
トrait などの変換処理において、**変換が常に成功する(不墜)**ケースを表現できます。FromStr- Before: エラーハンドリング用として
を使わざるを得なかった。Result<T, !> - After: 型推論によりエラー分岐が存在しないことをコンパイラーに理解させ、不要なコードを最適化・削除できる。
impl FromStr for ByteString { type Err = !; // 永らえない型を使用 fn from_str(s: &str) -> Result<Self, !> { /* ... */ } } // コンパイラーが自動的にこれを fn from_str(s: &str) -> Self に最適化可能
2. 哲学的な理由:一貫性のある型推論
やif
のように式(Expression)として扱う構造において、無終ループが発生した場合の結果型を推論しやすくする。while- 永らえない型の特性: 任意の型に自動的に変換される。
- コードが永らえない型の値を持つと判断した場所は**到達不可能(Dead Code)**となり、安全に削除・最適化できる。
- これにより、型推論システムを簡素化できている。
技術的課題:Never Fallback と Never Infallible
Never Fallback(永らえないフォールバック)の問題
- 明示的な戻り型が指定されていない非公開関数で無終ループが発生した場合、コンパイラーは型を推論できない。
- Rust 2024 エディション以前: フォールバック型は
(単位型)だった。() - Rust 2024 エディション以降: フォールバック型が
に変更され、暗黙変換が事実上止まった。!
影響:
// Rust 2024 以前:コンパイル可能(T を () と推論) let f: fn() -> Result<T, E> = || loop {} ?; // Rust 2024 以降:コンパイルエラー(T が ! になり、Default を実装できないため) let f: fn() -> Result<T, E> = || loop {} ?;
Never Infallible(永らえない不墜)の問題
- 過去に
という不安定な型がありましたが、最適化には対応していなかった。Infallible
を安定化し、!
をInfallible
のエイリアスにする計画があったが、既存コードとの互換性問題が生じた。!
は暗黙変換を持つため、定義変更で既存コードの型推論が変わるリスクがある。!
破壊的影響の検証:Crater と修正活動
Craterによる分析
- waffle が実行した
ツール(全公開 Rust ライブラリのコンパイルチェック)の結果:crater- 影響を受けた Crate(パッケージ):3,300 件
- 完全に壊れた(修正なしで使えない)Crate: 7 件のみ
- 残りは古いライブラリバージョン依存であり、更新可能なものが多い。
主な原因:ジェネリック関数の型推論
- 明示的な戻り型が指定されていない場合にフォールバック型が変わることでエラーになるケースが多数。
// 問題の典型的なパターン fn foo<T: Default>() -> Result<T, Error> { ... } foo()?; // コンパイルエラー:T が ! になり、Default を実装できないため
修正のアプローチ
- バックポート版の提供:
- ライブラリメンテナーに対し、壊れたコードを修復したパッチバージョン(例:
)を提供。v1.0.1 - ビルド環境が自動的に新しいバージョンを検出・採用する仕組みを利用。
- ライブラリメンテナーに対し、壊れたコードを修復したパッチバージョン(例:
- 成功例:
- 協力によって1,553 の失敗した Crateに対処し、互換性を保ちつつ更新可能にした。
- 拒否されたケース:
- ライフサイクルを終えた古いバージョンへの対応を拒んだ場合もあるが、ユーザー自身がアップグレードする必要があると説明。
結論:安定化と今後の対応
正式な導入
- Rust 1.99以降で「永らえない型」が公式に安定化し、「
」はInfallible
のエイリアスとなる。! - これにより、より簡潔で安全なジェネリックコードの記述が可能になる。
ユーザーへの選択肢
破壊的な影響を受ける場合の 3 つの対応策:
- Rust バージョン 1.98 に留まる(ただし新機能は使えない)。
- 依存関係をサポートされた最新版に更新する。
- 問題関数呼び出しで戻り型を明示的に指定するパッチを適用する。
互換性へのコミットメント
- この変更は破壊的であり、一見後方互換性の違反に見えますが:
- 比較的低頻度な発生ケースである。
- 何年も前から警告され計画されていた。
- コミュニティと協力し、壊れるコードを特定・修正するためのバックポート版提供まで行った。
- このプロセス全体は、Rust の後方互換性への真のコミットメントを示す事例と言えます。
注意: 「永らえない型」を使う際は、その特殊な挙動(到達不可能性の表現など)を理解した上で記述してください。