RFC-010b: パターンマッチング完備化(バリアント分解と網羅性)
本文書は RFC-010(統一型構文)の子 RFC である。バリアントの宣言・構築呼び出し形式とランタイム tagged union 表現(
variant_id宣言順序——本文書網羅性検査のバリアント集合入力を含む)は、RFC-010〔レコード风和型のバリアント構築(権威ある定義)〕節で定義される;本文書はその鏡像側を承载する:match 分解と網羅性検査。構築と分解は対となるため、ともに RFC-010 に帰属する。元の番号は RFC-039(2026-09-03 起稿);2026-09-25 に所有者決定により RFC-010 の子 RFC に統合・改番され RFC-010b となる。追跡 issue は引き続き #330。
概要
match のパターンマッチングを、現状の「字面量とワイルドカードのみ」から完備した能力へと補完する:Union バリアントパターン(ペイロード束縛を含む)、構造体/タプルパターン、Or パターンとガードの IR 着地、および網羅性検査(E1030/E1031 を空コードから実発射コードへ)。本 RFC は Error { kind: ErrorKind, message } 進化路線(RFC-013「ランタイムエラー値とコード貫通」進化節)の前置だが、動機は独立している——パターンマッチングは汎用的な言語能力であり、バリアントを持つすべての型に資する。
動機
現状の実証(2026-09-03、v0.7.12 コードベース)
- IR 層では字面量パターンのみが実在する。AST には完全なパターン集合が定義されている(
src/frontend/core/parser/ast.rs:578:Wildcard / Identifier / Literal / Tuple / Struct / Union / Or / Guard)。パーサはok(v)、err(e)等のバリアントパターン(Pattern::Union)を解析可能である。しかし IR 生成(src/middle/core/ir_gen.rs:5330以降)はLiteral分岐のみを実装しており、その他のパターンはスタブに落ちる——定数 0 をロードして等価比較に参加するため、決してマッチしない;さらに scrutinee が 0 の場合はスタブアームに誤マッチする(潜在的な誤動作)。 - stdlib.md の
match ok(v)/err(e)例は机上能力に過ぎない。仕様書(§1.3 Result)が示すバリアント分解の書き方は実際には実行できない;?演算子の実装は match の脱糖を経由しないため、この点が覆い隠されている。テストコーパスにはバリアント分解の用例が皆無である(match.yx/pattern_matching.yxは字面量とワイルドカードのみをカバー)。 - 網羅性検査は空コードのまま。E1030(Pattern non-exhaustive)、E1031(Unreachable pattern)がコード表に登録されているが発射点がない——match の意味論が未確定であるため。
- エラー処理の進化がブロックされている。ランタイム
Error値は現在{code, message}の文字列コードを唯一のプログラム可能な判定契約としている(RFC-013);構造化モデリング(match e.kind { file_not_found(path) => ... })は本 RFC のバリアント分解とペイロード束縛に依存する。
設計目標
- バリアント分解が使える:
match r { ok(v) => ..., err(e) => ... }と、ユーザ定義のバリアント集合(レコード風 sum type)の分解が 3 つの実行経路で意味論的に一貫する。 - 網羅性に依存できる:E1030/E1031 が実際に発射され、match の分岐漏れがコンパイルエラーとなる。
- スタブの除去:「0 をロードして決してマッチしない/誤マッチする」プレースホルダ動作を削除し、未対応パターンは沈黙して誤動作するのではなくコンパイル時にエラーとする。
提案(骨子レベル、本文の充实を待つ)
| 能力 | 説明 |
|---|---|
| Union バリアントパターン | VariantName / VariantName(binding) によるマッチとアームスコープへのペイロード束縛 |
| Struct / Tuple パターン | フィールドパターンとタプルパターンの着地(AST は既存、IR を補完) |
| Or パターンと Guard | p1 | p2 と p if cond の評価順序と束縛規則 |
| 網羅性検査 | E1030 の分岐漏れ、E1031 の到達不能。スコープはバリアント集合をカバー(Result/Option は現在 core 所属;判定は所属に依存しない。RFC-011b フェーズ 2 での std 移行を参照) |
| Identifier パターンの意味論確定 | 現行構文における裸識別子が束縛なのかバリアント比較なのか、確定が必要(ワイルドカード _ との関係) |
オープンな問題
- [ ] Identifier パターン:新しい変数を束縛するのか、既存の値にマッチするのか?(Rust の意味論 vs 既存の YaoXiang コーパス挙動)
- [ ] 網羅性の適用境界:動的インポート/インタフェースメソッドが返すバリアント集合は、網羅性判定にどう参加するか?
- [ ] non_exhaustive のような属性は必要か?(std のバリアント集合拡張がユーザの match に与える破壊半径に影響する)
- [ ] 修正前の過渡期において、スタブが 0 をロードして誤マッチする箇所をまずコンパイルエラーとして報告すべきか?
関連
- RFC-013「ランタイムエラー値とコード貫通」進化節(
Error { kind, message }は本 RFC に依存) - RFC-036 テストモデル(エラー分岐のアサーション時のマッチ記法)
- 既に閉じた個別ケースは不適用;本 RFC は能力の補完であり欠陥修正ではない
