feat(joinir): Phase 61-2 If-in-loop JoinIR dry-run検証インフラ実装

## 実装内容

### 61-2.1: dry-runフラグ追加
- `src/config/env.rs`: joinir_if_in_loop_dryrun_enabled() 追加 (+11行)
- `HAKO_JOINIR_IF_IN_LOOP_DRYRUN=1` でdry-runモード有効化

### 61-2.2: loop_builder.rs dry-run統合
- `src/mir/loop_builder.rs`: JoinIR PhiSpec計算とA/B比較実装 (+47行)
- JoinInst取得時にPhiSpec保存、PhiBuilderBox実行後に比較

### 61-2.3: PhiSpec計算ロジック実装
- `src/mir/join_ir/lowering/if_phi_spec.rs`: 新規作成 (+203行)
  - PhiSpec構造体(header_phis/exit_phis)
  - compute_phi_spec_from_joinir(): JoinInstからPHI仕様計算
  - extract_phi_spec_from_builder(): PhiBuilderBox結果抽出
  - compare_and_log_phi_specs(): A/B比較とログ出力
- BTreeMap/BTreeSet使用(決定的イテレーション保証)

### 61-2.4: A/B比較テスト実装
- `src/tests/phase61_if_in_loop_dryrun.rs`: 新規作成 (+49行)
  - phase61_2_dry_run_flag_available: フラグ動作確認
  - phase61_2_phi_spec_creation: PhiSpec構造体テスト
- テスト結果:  2/2 PASS

## テスト結果

- Phase 61-2新規テスト:  2/2 PASS
- 既存loopformテスト:  14/14 PASS(退行なし)
- ビルド:  成功(エラー0件)

## コード変更量

+312行(env.rs: +11, if_phi_spec.rs: +203, loop_builder.rs: +47, tests: +49, その他: +2)

## 技術的成果

1. PhiSpec構造体完成(JoinIR/PhiBuilderBox統一表現)
2. dry-run検証インフラ(本番動作に影響なし)
3. BTreeMap統一(Option C知見活用)

## 次のステップ(Phase 61-3)

- dry-run → 本番経路への昇格
- PhiBuilderBox If側メソッド削除(-226行)
- JoinIR経路のみでif-in-loop PHI生成

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-29 12:26:02 +09:00
parent f104725a81
commit 68615e72fb
6 changed files with 315 additions and 8 deletions

View File

@ -17,6 +17,7 @@ pub mod mir;
pub mod namingbox_static_method_id; // Phase 21.7++ Phase 1: StaticMethodId structure tests
pub mod nyash_abi_basic;
pub mod parser;
pub mod phase61_if_in_loop_dryrun; // Phase 61-2: If-in-loop JoinIR dry-run tests
pub mod plugin_hygiene;
pub mod policy_mutdeny;
pub mod refcell_assignment_test;

View File

@ -0,0 +1,48 @@
//! Phase 61-2: If-in-loop JoinIR dry-run + PHI生成 A/B比較テスト
//!
//! 目的: JoinIR経路でPHI仕様を計算し、PhiBuilderBox経路との一致を検証
//!
//! 注意: Phase 61-2はdry-run検証のみ。実行結果は変わらない。
//! JoinIRパターンマッチは Phase 33の厳格な条件に依存する。
#[cfg(test)]
mod tests {
#[test]
fn phase61_2_dry_run_flag_available() {
// Phase 61-2: dry-runフラグが正しく読み取れることを確認
std::env::set_var("HAKO_JOINIR_IF_IN_LOOP_DRYRUN", "1");
assert_eq!(crate::config::env::joinir_if_in_loop_dryrun_enabled(), true);
std::env::remove_var("HAKO_JOINIR_IF_IN_LOOP_DRYRUN");
assert_eq!(
crate::config::env::joinir_if_in_loop_dryrun_enabled(),
false
);
eprintln!("[Test] phase61_2_dry_run_flag_available passed");
}
#[test]
fn phase61_2_phi_spec_creation() {
use crate::mir::join_ir::lowering::if_phi_spec::PhiSpec;
let mut spec1 = PhiSpec::new();
assert_eq!(spec1.header_count(), 0);
assert_eq!(spec1.exit_count(), 0);
spec1.header_phis.insert("x".to_string());
spec1.header_phis.insert("y".to_string());
assert_eq!(spec1.header_count(), 2);
let mut spec2 = PhiSpec::new();
spec2.header_phis.insert("x".to_string());
spec2.header_phis.insert("y".to_string());
assert!(spec1.matches(&spec2));
eprintln!("[Test] phase61_2_phi_spec_creation passed");
}
}
// Note: E2E tests for actual if-in-loop JoinIR lowering will be added in Phase 61-3
// when the production switch is made. Phase 61-2 focuses on dry-run infrastructure.