feat(mir): Phase 92 P2-2 - Body-local variable support for ConditionalStep

Phase 92 P2-2完了:ConditionalStepのcondition(ch == '\\'など)でbody-local変数をサポート

## 主要変更

### 1. condition_lowerer.rs拡張
- `lower_condition_to_joinir`に`body_local_env`パラメータ追加
- 変数解決優先度:ConditionEnv → LoopBodyLocalEnv
- すべての再帰ヘルパー(comparison, logical_and, logical_or, not, value_expression)対応

### 2. conditional_step_emitter.rs修正
- `emit_conditional_step_update`に`body_local_env`パラメータ追加
- condition loweringにbody-local環境を渡す

### 3. loop_with_break_minimal.rs修正
- break condition loweringをbody-local init の**後**に移動(line 411)
- header_break_lowering::lower_break_conditionにbody_local_env渡す
- emit_conditional_step_updateにbody_local_env渡す(line 620)

### 4. header_break_lowering.rs修正
- `lower_break_condition`に`body_local_env`パラメータ追加
- scope_managerにbody-local環境を渡す

### 5. 全呼び出し箇所修正
- expr_lowerer.rs (2箇所)
- method_call_lowerer.rs (2箇所)
- loop_with_if_phi_if_sum.rs (3箇所)
- loop_with_continue_minimal.rs (1箇所)
- carrier_update_emitter.rs (1箇所・legacy)

## アーキテクチャ改善

### Break Condition Lowering順序修正
旧: Header → **Break Cond** → Body-local Init
新: Header → **Body-local Init** → Break Cond

理由:break conditionが`ch == '\"'`のようにbody-local変数を参照する場合、body-local initが先に必要

### 変数解決優先度(Phase 92 P2-2)
1. ConditionEnv(ループパラメータ、captured変数)
2. LoopBodyLocalEnv(body-local変数like `ch`)

## テスト

### ビルド
 cargo build --release成功(30 warnings、0 errors)

### E2E
⚠️ body-local promotion問題でブロック(Phase 92範囲外)
- Pattern2はbody-local変数をcarrier promotionする必要あり
- 既存パターン(A-3 Trim, A-4 DigitPos)に`ch = get_char(i)`が該当しない
- **Phase 92 P2-2目標(condition loweringでbody-local変数サポート)は達成**

## 次タスク(Phase 92 P3以降)
- body-local variable promotion拡張(Pattern2で`ch`のような変数を扱う)
- P5b E2Eテスト完全動作確認

## Phase 92 P2-2完了
 Body-local変数のcondition lowering対応完了
 ConditionalStepでbody-local変数参照可能
 Break condition lowering順序修正
This commit is contained in:
nyash-codex
2025-12-16 17:08:15 +09:00
parent 3093ac2ca4
commit 568619df89
18 changed files with 371 additions and 55 deletions

View File

@ -281,6 +281,25 @@ pub enum CarrierRole {
---
## 再帰設計Loop / If の境界)
目的: 「複雑な分岐を再帰的に扱いたい」欲求と、責務混在検出正規化配線PHIの爆発を両立させる。
原則(おすすめの境界):
- **Loop canonicalizer が再帰してよい範囲**は「構造の観測/収集」まで。
- loop body 内の if を再帰的に走査して、`break/continue/return/update` の存在・位置・個数・更新種別ConstStep/ConditionalStep 等)を抽出するのは OK。
- ただし **JoinIR/MIR の配線BlockId/ValueId/PHI/merge/exit_bindingsには踏み込まない**
- **if の値契約PHI 相当)**は別箱If canonicalize/lowerに閉じる。
- loop 側では「if が存在する」「if の中に exit がある」などを `notes` / `missing_caps` に落とし、`chosen` は最終 lowerer 選択結果として安定に保つ。
- **nested looploop 内 loop**は当面 capability で Fail-Fast将来の P6 で解禁)。
- これにより “再帰地獄” を設計で遮断できる。
- **PHI 排除env + 継続への正規化)**の本線は `Structured JoinIR → Normalized JoinIR` 側に置く。
- canonicalizer は「どの carrier/env フィールドが更新されるか」を契約として宣言するだけに留める。
将来案(必要になったら):
- LoopSkeleton を肥大化させず、制御だけの再帰ツリー(`ControlTree/StepTree`)を **別 SSOT** として新設し、`LoopSkeleton` は “loop の箱” のまま維持する。
## 実装の入口(現状)
実装Phase 12はここ