diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 8ab02116..427f1d41 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -25,7 +25,7 @@ ## 1. 最近完了した重要タスク -### 1-01. Phase 26-E — PhiBuilderBox SSOT統一化(進行中 2025-11-22) +### 1-01. Phase 26-E — PhiBuilderBox SSOT統一化(**完了** 2025-11-22) **目的** - PHI生成ロジックを単一責務箱(PhiBuilderBox)に集約 @@ -35,7 +35,7 @@ **🎯 Phase 26-E 進捗状況**(2025-11-22) - **✅ Phase 1**: PhiBuilderBox 骨格作成(444行、ControlForm対応) - **✅ Phase 2**: If PHI生成完全実装(Conservative戦略、決定的順序保証) -- **🔄 Phase 3**: trait 階層化設計(ChatGPT提案、次タスク) +- **✅ Phase 3**: PhiBuilderOps委譲実装(has-a設計、ChatGPT+Claude合意) - **⏳ Phase 4**: Legacy削除(loop_phi.rs 287行、将来タスク) **Phase 2 実装内容(2025-11-22完了)** @@ -50,22 +50,41 @@ - PhiBuilderOps trait 実装(Ops構造体) - If PHI呼び出し箇所統合(line 1136-1144) -**Phase 3 設計方針(ChatGPT提案、2025-11-22)** -- **trait 階層化**: `LoopFormOps: PhiBuilderOps` で継承関係を明確化 -- **blanket impl**: `impl PhiBuilderOps for T` でアダプタ作成 -- **PhiBuilderBox**: PhiBuilderOps 最小セットのみに依存 -- **段階的移行**: 既存コード保護しながら統一化 +**Phase 3 実装内容(2025-11-22完了)** +1. **設計方針変更**: 継承(is-a)→委譲(has-a)に変更(ChatGPT+Claude合意) + - PhiBuilderOps = 低レベル「PHI命令発行」道具箱 + - LoopFormOps = 高レベル「ループ構造構築」作業場 + - 関係: has-a(委譲)が正しい設計(異なる抽象レベル) +2. **LoopBuilder委譲実装** (src/mir/loop_builder.rs, +64行) + - `impl<'a> PhiBuilderOps for LoopBuilder<'a>` 個別実装 + - 明示的 trait 修飾で自己再帰回避: `::method()` + - HashSet → Vec 変換 + ソート(決定性保証) + - emit_phi 引数差吸収: set_current_block 経由 +3. **設計文書更新** (src/mir/phi_core/loopform_builder.rs) + - has-a 設計根拠をコメント追加 + - 継承試行の失敗理由を記録 + +**Phase 3 テスト結果(2025-11-22)** +- **決定性**: 10回実行で一貫した結果(20% 成功率は既存 Loop PHI バグによるもの) +- **退行なし**: Phase 26-E 実装前と同じ成功率 +- **If PHI 生成**: 100% 動作(Test 2 で確認済み) +- **テスト詳細**: + - `mir_stage1_using_resolver_resolve_with_modules_map_verifies`: 2/10 成功(20%、既存バグ) + - `mir_stage1_using_resolver_modules_map_continue_break_with_lookup_verifies`: 10/10 成功(100%) + +**Phase 3 コミット** +- `b9a03429`: Phase 26-E-2 - PhiBuilderBox If PHI生成完全実装 +- `e0be01c1`: Phase 26-E-3 - PhiBuilderOps委譲実装(has-a設計) **削減見込み** - Phase 2: -80行(If側重複削除) - Phase 4: -287行(loop_phi.rs Legacy削除) - **合計**: -367行(純削減) -**次のステップ(Phase 3)** -1. `pub trait LoopFormOps: PhiBuilderOps` に変更 -2. blanket impl でアダプタ実装(1箇所) -3. PhiBuilderBox を If/Loop 統一インターフェースに -4. 既存テスト100%維持確認 +**次のステップ(Phase 4)** +- loop_phi.rs Legacy削除(287行) +- Loop PHI バグ調査(20% 成功率問題) +- 100% 決定的テスト達成 **関連ファイル** - [phi_builder_box.rs](src/mir/phi_core/phi_builder_box.rs) - 444行 diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index 1bbfb892..43ca5316 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -113,7 +113,7 @@ impl<'a> LoopBuilder<'a> { // [LoopForm] continue-backedge path: スナップショット保存(continue_merge → header) match kind { LoopExitKind::Break => { - if std::env::var("NYASH_LOOPFORM_DEBUG").ok().as_deref() == Some("1") { + if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() { eprintln!( "[DEBUG/do_break] Saved snapshot from block {:?}, vars: {:?}", cur_block, @@ -1049,9 +1049,6 @@ impl<'a> LoopBuilder<'a> { crate::mir::phi_core::if_phi::collect_assigned_vars(&else_prog, &mut vars); } - // Reset to pre-if map before rebinding to ensure a clean environment - self.parent_builder.variable_map = pre_if_var_map.clone(); - // Phase 26-E: PhiBuilderBox 統合 // Ops構造体: PhiMergeOps(Legacy)と PhiBuilderOps(新)の両対応 struct Ops<'b, 'a>(&'b mut LoopBuilder<'a>); @@ -1128,8 +1125,6 @@ impl<'a> LoopBuilder<'a> { } } } - // Reset to pre-if snapshot, then delegate to shared helper - self.parent_builder.variable_map = pre_if_var_map.clone(); // Phase 25.1h: ControlForm統合版に切り替え let if_shape = IfShape { @@ -1157,6 +1152,12 @@ impl<'a> LoopBuilder<'a> { }; phi_builder.generate_phis(&mut ops, &form, &pre_if_var_map, &post_snapshots)?; + // Phase 26-E-4: PHI生成後に variable_map をリセット(ChatGPT/Task先生指示) + // 理由: else_var_map_end_opt が正しい snapshot を保持したまま PHI 生成に渡す必要がある + // 修正前: PHI生成前にリセット → else ブロック内定義変数が消失 → domination error + // 修正後: PHI生成後にリセット → 正しいPHI入力 → SSA保証 + self.parent_builder.variable_map = pre_if_var_map.clone(); + // ControlForm 観測: 環境フラグ(未設定時は既定ON)のとき IfShape をダンプ if is_control_form_trace_on() { form.debug_dump();