3.9 KiB
3.9 KiB
Phase 287 P2: merge/contract_checks.rs 分割指示書(意味論不変)
Date: 2025-12-27
Status: Completed ✅
Scope: src/mir/builder/control_flow/joinir/merge/contract_checks.rs(~846行)を facade 化し、契約検証を “1 module = 1 契約” に分割
Non-goals: エラータグ変更、検証条件の追加/緩和、merge/instruction_rewriter.rs の分割、silent fallback 追加
目的(SSOT)
- merge の “Fail-Fast 契約” を 構造で見える化する。
contract_checks.rsを facade(re-export + glue)に寄せ、検証ロジックを責務分離する。- 既存の呼び出し点を壊さない(public 関数名/シグネチャを基本維持)。
現状
src/mir/builder/control_flow/joinir/merge/contract_checks.rs は複数契約を同居させており、読む側が “どの契約がどこにあるか” を追いにくい。
代表的な契約(例):
- terminator target existence
- exit_bindings ↔ exit_phis
- carrier_inputs completeness
- boundary contract at creation(B1/C2)
- entry params consistency
目標の構造(案)
src/mir/builder/control_flow/joinir/merge/
├── contract_checks.rs # facade(旧名維持 / re-export)
└── contract_checks/ # NEW
├── mod.rs
├── terminator_targets.rs # verify_all_terminator_targets_exist
├── exit_bindings.rs # verify_exit_bindings_have_exit_phis
├── carrier_inputs.rs # verify_carrier_inputs_complete
├── boundary_creation.rs # verify_boundary_contract_at_creation(B1/C2)
└── entry_params.rs # verify_boundary_entry_params
ルール:
contract_checks.rsは 呼び出し側互換のための facade に徹する。- 新規の “総合入口” を作るなら
contract_checks::run_all_pipeline_checks()のみ(既存があるなら整理だけ)。
手順(安全な順序)
Step 1: contract_checks/ を追加し facade を作る
contract_checks/mod.rsに各 module をpub(super)で生やすsrc/mir/builder/control_flow/joinir/merge/contract_checks.rsからpub(super) use ...で既存 API を re-export
Step 2: 低依存の契約から移す
優先:
verify_all_terminator_targets_exist()(依存が少ない)verify_exit_bindings_have_exit_phis()
Step 3: verify_carrier_inputs_complete() を移す
- ここは “エラータグ/ヒント文” が契約なので、文言変更は避ける。
Step 4: boundary creation(B1/C2)を移す
verify_boundary_contract_at_creation()は “入口で fail-fast する” という意味で重要なので、移設後も呼び出し位置を変えない。
Step 5: entry params を移す
verify_boundary_entry_params()は “param 順序” の SSOT なので、テストがあるなら位置だけ追従させる。
テスト(仕様固定)
P2 は意味論不変が主目的なので、原則 “既存テストを壊さない” を優先する。
- 既存の
#[cfg(test)]がcontract_checks.rsにある場合:- 最小差分で
contract_checks/の該当 module へ移動 - もしくは facade 側に残して import だけ更新(どちらでも可)
- 最小差分で
新規テストは原則不要(既存で十分)。
検証手順(受け入れ基準)
cargo build --release
./target/release/hakorune --backend vm apps/tests/phase1883_nested_minimal.hako # RC=9
./tools/smokes/v2/run.sh --profile quick
受け入れ:
- Build: 0 errors
- quick: 154/154 PASS
- Pattern6: RC=9 維持
- 恒常ログ増加なし
Out of Scope(重要)
src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rsの物理分割- エラータグの変更、契約の意味変更、条件追加による挙動変化
- “便利な fallback” の追加(Fail-Fast 原則に反するため)