feat(joinir): Phase 61-1 If-in-loop JoinIR化インフラ整備完了

## 実装内容

### 新規ファイル
- `if_phi_context.rs`: If-in-loop用PHIコンテキスト構造体 (135行)
  - `IfPhiContext::for_loop_body()`: ループ内if用コンストラクタ
  - `is_carrier()`: ループキャリア変数判定
  - 単体テスト2個完全動作

### 既存ファイル拡張
- `if_select.rs`, `if_merge.rs`: context パラメータ追加 (+68行)
  - `with_context()` コンストラクタ実装
  - Pure If との完全互換性維持
- `mod.rs`: `try_lower_if_to_joinir()` シグネチャ拡張 (+25行)
  - `context: Option<&IfPhiContext>` パラメータ追加
  - 既存呼び出し箇所6箇所修正完了
- `loop_builder.rs`: JoinIR経路実装 (+43行)
  - `NYASH_JOINIR_IF_SELECT=1` で試行
  - フォールバック設計(PhiBuilderBox経路保持)
  - デバッグログ完備

## テスト結果
-  loopform テスト 14/14 PASS(退行なし)
-  ビルド成功(エラー0件)
-  Borrow Checker 問題解決

## コード変更量
- 新規: +135行
- 拡張: +136行
- 削除: -18行
- 純増: +253行(インフラ投資、Phase 61-3で-226行削減予定)

## 次のステップ
Phase 61-2: join_inst dry-run実装で実際の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 11:53:57 +09:00
parent 540f503c24
commit 3ea397fd3e
8 changed files with 292 additions and 33 deletions

View File

@ -133,7 +133,7 @@ mod tests {
let func = create_simple_pattern_mir();
let entry_block = func.entry_block;
let result = try_lower_if_to_joinir(&func, entry_block, true);
let result = try_lower_if_to_joinir(&func, entry_block, true, None); // Phase 61-1: Pure If
assert!(
result.is_some(),
@ -159,7 +159,7 @@ mod tests {
// ==== 2. Local pattern (env ON) ====
let func = create_local_pattern_mir();
let entry_block = func.entry_block;
let result = try_lower_if_to_joinir(&func, entry_block, true);
let result = try_lower_if_to_joinir(&func, entry_block, true, None); // Phase 61-1: Pure If
assert!(
result.is_some(),
@ -187,7 +187,7 @@ mod tests {
let func = create_simple_pattern_mir();
let entry_block = func.entry_block;
let result = try_lower_if_to_joinir(&func, entry_block, false);
let result = try_lower_if_to_joinir(&func, entry_block, false, None); // Phase 61-1: Pure If
assert!(
result.is_none(),
@ -202,7 +202,7 @@ mod tests {
let mut func = create_simple_pattern_mir();
func.signature.name = "WrongName.test/1".to_string();
let entry_block = func.entry_block;
let result = try_lower_if_to_joinir(&func, entry_block, true);
let result = try_lower_if_to_joinir(&func, entry_block, true, None); // Phase 61-1: Pure If
assert!(
result.is_none(),
@ -519,7 +519,7 @@ mod tests {
let func = create_if_merge_simple_pattern_mir();
let entry_block = func.entry_block;
let result = try_lower_if_to_joinir(&func, entry_block, true);
let result = try_lower_if_to_joinir(&func, entry_block, true, None); // Phase 61-1: Pure If
assert!(
result.is_some(),
@ -560,7 +560,7 @@ mod tests {
let func = create_if_merge_multiple_pattern_mir();
let entry_block = func.entry_block;
let result = try_lower_if_to_joinir(&func, entry_block, true);
let result = try_lower_if_to_joinir(&func, entry_block, true, None); // Phase 61-1: Pure If
assert!(
result.is_some(),