2025-12-27 11:05:40 +09:00
|
|
|
|
# Phase 287 P2: `merge/contract_checks.rs` 分割指示書(意味論不変)
|
|
|
|
|
|
|
|
|
|
|
|
**Date**: 2025-12-27
|
2025-12-27 12:17:47 +09:00
|
|
|
|
**Status**: Completed ✅
|
2025-12-27 11:05:40 +09:00
|
|
|
|
**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 だけ更新(どちらでも可)
|
|
|
|
|
|
|
|
|
|
|
|
新規テストは原則不要(既存で十分)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 検証手順(受け入れ基準)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
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 原則に反するため)
|