Files
hakorune/docs/private/roadmap/phases/phase-31.2/legacy-loop-deletion-plan.md

27 KiB
Raw Blame History

Legacy Loop Builder削除プラン

Phase: 31.2 - Legacy Loop Builder経路の完全削除 目的: build_loop_legacy() (372行) および Legacy専用ヘルパー関数を削除し、LoopFormBox経路のみに統一 背景: Phase 31完了により、LoopFormBox経路が安定版として確立。Legacy経路は不要になった。


1. 削除対象サマリー

ファイル 関数/メソッド 行数 使用箇所 削除可否
build.rs build_loop_legacy 372行 1箇所build_loop Line 33のみ 削除
build.rs build_loop の Legacy分岐 15行 - 削除
phi.rs prepare_loop_variables 29行 1箇所build_loop_legacy Line 102のみ 削除
phi.rs seal_block 14行 1箇所build_loop_legacy Line 214のみ 削除
phi.rs mark_block_unsealed 5行 1箇所build_loop_legacy Line 89のみ 削除
mod.rs build_expression_with_phis 4行 1箇所build_loop_legacy Line 127のみ 削除
mod.rs block_var_maps フィールド - Legacy専用 削除
mod.rs incomplete_phis フィールド - Legacy専用 削除
phi_core/loop_phi.rs prepare_loop_variables_with 21行 1箇所prepare_loop_variables Line 35のみ 削除
phi_core/loop_phi.rs seal_incomplete_phis_with 26行 1箇所seal_block Line 49のみ 削除
phi_core/loop_phi.rs save_block_snapshot 7行 2箇所両方Legacy内 削除
phi_core/loop_phi.rs IncompletePhi - Legacy専用 削除

共通使用関数 (削除対象外):

  • collect_carrier_assigns - LoopCarrierAnalyzerBoxが使用継続使用
  • build_exit_phis_with - PhiBuilderBoxが使用継続使用

合計削除見込み: 493行 (build.rs: 387行 + phi.rs: 48行 + mod.rs: 4行 + loop_phi.rs: 54行)


2. 詳細分析

2.1 build_loop_legacy() (build.rs Line 45-417)

使用箇所: build_loop() Line 33 のみ(HAKO_FORCE_LEGACY_LOOP=1 時)

依存関数:

  • prepare_loop_variables() (phi.rs) - Legacy専用
  • seal_block() (phi.rs) - Legacy専用
  • mark_block_unsealed() (phi.rs) - Legacy専用
  • build_expression_with_phis() (mod.rs) - Legacy専用
  • create_exit_phis() (phi.rs) - 共通使用PhiBuilderBox経由
  • materialize_branch_entry_phis() (build.rs) - 共通使用if-in-loop用
  • execute_branch_body() (build.rs) - 共通使用if-in-loop用

削除可否: 安全に削除可能

理由:

  1. HAKO_FORCE_LEGACY_LOOP=1 環境変数でのみ有効化される非推奨パス
  2. デフォルトは build_loop_with_loopform() を使用Phase 31完了、安定版
  3. #[deprecated] アトリビュート付き(明示的な削除予定)

2.2 build_loop() のLegacy分岐 (build.rs Line 19-38)

現在のコード:

pub fn build_loop(
    &mut self,
    condition: ASTNode,
    body: Vec<ASTNode>,
) -> Result<ValueId, String> {
    // P0 Refactoring: ロジック逆転LoopFormBox = デフォルト、Legacy = 明示要求のみ)
    let force_legacy = crate::runtime::env_gate_box::bool_any(&[
        "HAKO_FORCE_LEGACY_LOOP",
        "NYASH_FORCE_LEGACY_LOOP",
    ]);

    if force_legacy {
        // Legacy path (DEPRECATED, will be removed in future)
        eprintln!("[DEPRECATED] Using legacy loop builder (HAKO_FORCE_LEGACY_LOOP=1). This will be removed in future versions.");
        return self.build_loop_legacy(condition, body);
    }

    // Default: Use LoopFormBox path (Phase 31 stable)
    self.build_loop_with_loopform(condition, body)
}

削除後のコード:

pub fn build_loop(
    &mut self,
    condition: ASTNode,
    body: Vec<ASTNode>,
) -> Result<ValueId, String> {
    // LoopFormBox経路のみPhase 31完了、Legacy経路削除済み
    self.build_loop_with_loopform(condition, body)
}

削除可否: 削除15行削減


2.3 prepare_loop_variables() (phi.rs Line 14-43)

使用箇所: build_loop_legacy() Line 102 のみ

依存関数:

  • crate::mir::phi_core::loop_phi::save_block_snapshot() - Legacy専用
  • crate::mir::phi_core::loop_phi::prepare_loop_variables_with() - Legacy専用

削除可否: 安全に削除可能

理由: build_loop_legacy() の内部でのみ呼ばれている。LoopFormBoxは独自のPHI生成ロジックを持つPhiBuilderBox経由


2.4 seal_block() (phi.rs Line 46-59)

使用箇所: build_loop_legacy() Line 214 のみ

依存関数:

  • crate::mir::phi_core::loop_phi::seal_incomplete_phis_with() - Legacy専用

削除可否: 安全に削除可能

理由: build_loop_legacy() の内部でのみ呼ばれている。LoopFormBoxは事前確定PHI方式でsealing不要。

注意: LLVM backend (src/backend/llvm/compiler/codegen/instructions/flow.rs) に同名関数 seal_block() があるが、これは別物LLVM SSA構築用で削除対象外。


2.5 mark_block_unsealed() (phi.rs Line 78-82)

使用箇所: build_loop_legacy() Line 89 のみ

実装:

pub(super) fn mark_block_unsealed(&mut self, _block_id: BasicBlockId) -> Result<(), String> {
    // ブロックはデフォルトでunsealedなので、特に何もしない
    // 既にBasicBlock::newでsealed: falseに初期化されている
    Ok(())
}

削除可否: 安全に削除可能

理由: no-op実装何もしない。Legacy経路でのみ呼ばれている。


2.6 build_expression_with_phis() (mod.rs Line 333-336)

使用箇所: build_loop_legacy() Line 127 のみ

実装:

pub(super) fn build_expression_with_phis(&mut self, expr: ASTNode) -> Result<ValueId, String> {
    // Phi nodeの結果を考慮しながら式を構築
    self.parent_builder.build_expression(expr)
}

削除可否: 安全に削除可能

理由: parent_builder.build_expression() への単純な委譲。Legacy経路でのみ呼ばれている。


2.7 block_var_maps / incomplete_phis フィールド (mod.rs Line 34-36)

現在のコード:

/// ブロックごとの変数マップ(スコープ管理)
#[allow(dead_code)] // TTL (Phase-20.5 finale): remove after LoopFormBox owns per-block maps
pub(super) block_var_maps: HashMap<BasicBlockId, HashMap<String, ValueId>>,

/// ループ内で追跡する変数の不完全Phi node
pub(super) incomplete_phis: HashMap<BasicBlockId, Vec<IncompletePhi>>,

使用箇所:

  • block_var_maps: Legacy経路内のみcontinue snapshot用
  • incomplete_phis: Legacy経路内のみPHI sealing用

削除可否: 安全に削除可能

理由: LoopFormBoxは独自の変数管理方式を持つ事前確定PHI。Legacy経路削除後は不要。


2.8 phi_core/loop_phi.rs の Legacy専用関数

prepare_loop_variables_with() (Line 136-157)

使用箇所: prepare_loop_variables() Line 35 のみ

削除可否: 安全に削除可能

理由: prepare_loop_variables() がLegacy専用なので、この委譲先も削除可能。


seal_incomplete_phis_with() (Line 105-131)

使用箇所: seal_block() Line 49 のみ

削除可否: 安全に削除可能

理由: seal_block() がLegacy専用なので、この委譲先も削除可能。


save_block_snapshot() (Line 187-193)

使用箇所: 2箇所両方Legacy内

  1. build_loop_legacy() Line 185 (latch snapshot)
  2. prepare_loop_variables() Line 30 (preheader snapshot)

削除可否: 安全に削除可能

理由: すべての呼び出し元がLegacy経路内にある。


IncompletePhi 型 (Line 13-18)

定義:

#[derive(Debug, Clone)]
pub struct IncompletePhi {
    pub phi_id: ValueId,
    pub var_name: String,
    pub known_inputs: Vec<(BasicBlockId, ValueId)>,
}

使用箇所: Legacy経路のPHI sealing専用

削除可否: 安全に削除可能

理由: LoopFormBoxは事前確定PHI方式で IncompletePhi を使わない。


2.9 共通使用関数(削除対象外)

collect_carrier_assigns() (phi_core/loop_phi.rs Line 161-184)

使用箇所:

  1. build_loop_legacy() Line 56 (carrier hint用)
  2. LoopCarrierAnalyzerBox::analyze() (carrier_analyzer.rs Line 75) ← LoopFormBox経路で使用

削除可否: 保持LoopFormBox経路で必要


build_exit_phis_with() (phi_core/loop_phi.rs Line 55-101)

使用箇所:

  1. PhiBuilderBox::build_exit_phis() (phi_builder_box.rs) ← LoopFormBox経路で使用

削除可否: 保持LoopFormBox経路で必要


3. 削除手順

Step 1: build.rs の修正

3.1 build_loop_legacy() メソッド削除Line 40-417

-    /// Legacy loop builder (DEPRECATED)
-    ///
-    /// This method will be removed after full migration to LoopFormBox.
-    /// To use legacy path, set `HAKO_FORCE_LEGACY_LOOP=1`.
-    #[deprecated(note = "Use build_loop_with_loopform instead. Legacy path will be removed.")]
-    fn build_loop_legacy(
-        &mut self,
-        condition: ASTNode,
-        body: Vec<ASTNode>,
-    ) -> Result<ValueId, String> {
-        // ... 372行削除 ...
-    }

削減: 378行 (メソッド本体372行 + ドキュメント6行)


3.2 build_loop() メソッドの簡略化Line 15-38

Before:

/// SSA形式でループを構築
///
/// **デフォルト**: LoopFormBox経路を使用Phase 31完了、安定版
/// **Legacy経路**: `HAKO_FORCE_LEGACY_LOOP=1` で明示的に有効化(非推奨、将来削除予定)
pub fn build_loop(
    &mut self,
    condition: ASTNode,
    body: Vec<ASTNode>,
) -> Result<ValueId, String> {
    // P0 Refactoring: ロジック逆転LoopFormBox = デフォルト、Legacy = 明示要求のみ)
    let force_legacy = crate::runtime::env_gate_box::bool_any(&[
        "HAKO_FORCE_LEGACY_LOOP",
        "NYASH_FORCE_LEGACY_LOOP",
    ]);

    if force_legacy {
        // Legacy path (DEPRECATED, will be removed in future)
        eprintln!("[DEPRECATED] Using legacy loop builder (HAKO_FORCE_LEGACY_LOOP=1). This will be removed in future versions.");
        return self.build_loop_legacy(condition, body);
    }

    // Default: Use LoopFormBox path (Phase 31 stable)
    self.build_loop_with_loopform(condition, body)
}

After:

/// SSA形式でループを構築LoopFormBox経路
///
/// Phase 31.2以降、Legacy経路は削除され、LoopFormBox経路のみをサポート。
pub fn build_loop(
    &mut self,
    condition: ASTNode,
    body: Vec<ASTNode>,
) -> Result<ValueId, String> {
    // LoopFormBox経路のみLegacy経路は削除済み
    self.build_loop_with_loopform(condition, body)
}

削減: 15行 (Legacy分岐コード + 環境変数チェック)


Step 2: phi.rs の修正

2.1 prepare_loop_variables() 削除Line 14-43

-    /// ループ変数の準備(事前検出または遅延生成)
-    pub(super) fn prepare_loop_variables(
-        &mut self,
-        header_id: BasicBlockId,
-        preheader_id: BasicBlockId,
-        loop_carried_vars: &std::collections::HashSet<String>,
-    ) -> Result<(), String> {
-        // ... 29行削除 ...
-    }

削減: 30行


2.2 seal_block() 削除Line 46-59

-    /// ブロックをシールし、不完全なPhi nodeを完成させる
-    pub(super) fn seal_block(&mut self, block_id: BasicBlockId, latch_id: BasicBlockId) -> Result<(), String> {
-        // ... 14行削除 ...
-    }

削減: 14行


2.3 mark_block_unsealed() 削除Line 78-82

-    pub(super) fn mark_block_unsealed(&mut self, _block_id: BasicBlockId) -> Result<(), String> {
-        // ブロックはデフォルトでunsealedなので、特に何もしない
-        // 既にBasicBlock::newでsealed: falseに初期化されている
-        Ok(())
-    }

削減: 5行


phi.rs 合計削減: 49行 (30+14+5)


Step 3: mod.rs の修正

3.1 build_expression_with_phis() 削除Line 333-336

-    pub(super) fn build_expression_with_phis(&mut self, expr: ASTNode) -> Result<ValueId, String> {
-        // Phi nodeの結果を考慮しながら式を構築
-        self.parent_builder.build_expression(expr)
-    }

削減: 4行


3.2 LoopBuilder struct フィールド削除Line 34-36, 31-32

Before:

pub struct LoopBuilder<'a> {
    /// 親のMIRビルダーへの参照
    pub(super) parent_builder: &'a mut super::builder::MirBuilder,

    /// ループ内で追跡する変数の不完全Phi node
    pub(super) incomplete_phis: HashMap<BasicBlockId, Vec<IncompletePhi>>,

    /// ブロックごとの変数マップ(スコープ管理)
    #[allow(dead_code)] // TTL (Phase-20.5 finale): remove after LoopFormBox owns per-block maps
    pub(super) block_var_maps: HashMap<BasicBlockId, HashMap<String, ValueId>>,

    /// ループヘッダーIDcontinueで使用
    pub(super) loop_header: Option<BasicBlockId>,

    /// ループラッチIDLoopFormBox経路でのcontinue用
    pub(super) loop_latch: Option<BasicBlockId>,

    /// ループ出口IDLoopFormBox経路でのbreak用
    pub(super) loop_exit: Option<BasicBlockId>,

    /// continue文からの変数スナップショット
    pub(super) continue_snapshots: Vec<(BasicBlockId, HashMap<String, ValueId>)>,

    /// break文からの変数スナップショットexit PHI生成用
    pub(super) exit_snapshots: Vec<(BasicBlockId, HashMap<String, ValueId>)>,
}

After:

pub struct LoopBuilder<'a> {
    /// 親のMIRビルダーへの参照
    pub(super) parent_builder: &'a mut super::builder::MirBuilder,

    /// ループヘッダーIDcontinueで使用、Legacy互換のため保持
    pub(super) loop_header: Option<BasicBlockId>,

    /// ループラッチIDLoopFormBox経路でのcontinue用
    pub(super) loop_latch: Option<BasicBlockId>,

    /// ループ出口IDLoopFormBox経路でのbreak用
    pub(super) loop_exit: Option<BasicBlockId>,

    /// continue文からの変数スナップショットLegacy互換のため保持
    pub(super) continue_snapshots: Vec<(BasicBlockId, HashMap<String, ValueId>)>,

    /// break文からの変数スナップショットexit PHI生成用
    pub(super) exit_snapshots: Vec<(BasicBlockId, HashMap<String, ValueId>)>,
}

削除フィールド:

  • incomplete_phis - Legacy専用
  • block_var_maps - Legacy専用

保持フィールド:

  • loop_header - Legacy互換のため保持将来的に loop_latch に統一検討)
  • continue_snapshots - Legacy互換のため保持将来的に削除検討
  • exit_snapshots - LoopFormBox経路で使用保持必須

削減: 6行 (フィールド定義2行 + コメント4行)


3.3 LoopBuilder::new() 初期化削除Line 133-144

Before:

pub fn new(parent: &'a mut super::builder::MirBuilder) -> Self {
    Self {
        parent_builder: parent,
        incomplete_phis: HashMap::new(),
        block_var_maps: HashMap::new(),
        loop_header: None,
        loop_latch: None,  // LoopFormBox経路でのcontinue用
        loop_exit: None,   // LoopFormBox経路でのbreak用
        continue_snapshots: Vec::new(),
        exit_snapshots: Vec::new(),  // exit PHI用のスナップショット
    }
}

After:

pub fn new(parent: &'a mut super::builder::MirBuilder) -> Self {
    Self {
        parent_builder: parent,
        loop_header: None,
        loop_latch: None,
        loop_exit: None,
        continue_snapshots: Vec::new(),
        exit_snapshots: Vec::new(),
    }
}

削減: 2行 (初期化コード)


mod.rs 合計削減: 12行 (4+6+2)


Step 4: phi_core/loop_phi.rs の修正

4.1 prepare_loop_variables_with() 削除Line 133-157

-/// Prepare loop header PHIs by declaring one IncompletePhi per variable found
-/// in `current_vars` (preheader snapshot), seeding each with (preheader_id, val)
-/// and rebinding the variable to the newly allocated Phi result in the builder.
-pub fn prepare_loop_variables_with<O: LoopPhiOps>(
-    ops: &mut O,
-    header_id: BasicBlockId,
-    preheader_id: BasicBlockId,
-    current_vars: &std::collections::HashMap<String, ValueId>,
-) -> Result<Vec<IncompletePhi>, String> {
-    // ... 21行削除 ...
-}

削減: 25行 (ドキュメント4行 + 本体21行)


4.2 seal_incomplete_phis_with() 削除Line 103-131

-/// Seal a header block by completing its incomplete PHIs with values from
-/// continue snapshots and the latch block.
-pub fn seal_incomplete_phis_with<O: LoopPhiOps>(
-    ops: &mut O,
-    block_id: BasicBlockId,
-    latch_id: BasicBlockId,
-    mut incomplete_phis: Vec<IncompletePhi>,
-    continue_snapshots: &[(BasicBlockId, VarSnapshot)],
-) -> Result<(), String> {
-    // ... 26行削除 ...
-}

削減: 29行 (ドキュメント3行 + 本体26行)


4.3 save_block_snapshot() 削除Line 186-193

-/// Save a block-local variable snapshot into the provided store.
-pub fn save_block_snapshot(
-    store: &mut std::collections::HashMap<BasicBlockId, VarSnapshot>,
-    block: BasicBlockId,
-    snapshot: &VarSnapshot,
-) {
-    store.insert(block, snapshot.clone());
-}

削減: 8行 (ドキュメント1行 + 本体7行)


4.4 IncompletePhi 型削除Line 11-18

-/// Loop-local placeholder of an incomplete PHI (header-time declaration).
-/// Moved from loop_builder to centralize PHI-related types.
-#[derive(Debug, Clone)]
-pub struct IncompletePhi {
-    pub phi_id: ValueId,
-    pub var_name: String,
-    pub known_inputs: Vec<(BasicBlockId, ValueId)>,
-}

削減: 8行


phi_core/loop_phi.rs 合計削減: 70行 (25+29+8+8)


Step 5: ドキュメント更新

5.1 env-variables.md の修正

削除対象 (docs/guides/env-variables.md Line 31-35):

-- `HAKO_FORCE_LEGACY_LOOP` — **DEPRECATED** Legacy loop builder を強制使用(非推奨、将来削除予定)
-  - Alias: `NYASH_FORCE_LEGACY_LOOP`
-  - 既定: `0`OFF。**デフォルトでLoopFormBox経路を使用**Phase 31完了、安定版
-  - `1` で明示的にLegacy経路を使用非推奨警告が表示されます
-  - **注意**: Legacy経路は将来のバージョンで削除されます。LoopFormBoxへの移行を推奨。

削減: 5行


Step 6: テスト削除

6.1 Legacy経路の明示的なテスト削除

検索: HAKO_FORCE_LEGACY_LOOP=1 または NYASH_FORCE_LEGACY_LOOP=1 を使用するテスト

予想: 専用テストは存在しない可能性が高い(環境変数は開発者用デバッグ機能)

確認方法:

grep -r "FORCE_LEGACY_LOOP" tools/smokes/
grep -r "FORCE_LEGACY_LOOP" apps/

4. テスト計画

4.1 ビルドテスト

# Step 1: クリーンビルド
cargo clean
cargo build --release

# 期待結果: ビルド成功、警告なし

4.2 スモークテストQuick Profile

# Step 2: Quick profile実行
tools/smokes/v2/run.sh --profile quick

# 期待結果: 全テストPASS現在のベースライン: 272/296 PASS

4.3 スモークテストIntegration Profile

# Step 3: Integration profile実行
tools/smokes/v2/run.sh --profile integration

# 期待結果: 全テストPASS

4.4 Legacy経路の削除確認

# Step 4: Legacy環境変数を設定しても動作確認
HAKO_FORCE_LEGACY_LOOP=1 ./target/release/hakorune apps/tests/loop_min_while.nyash

# 期待結果:
# - エラーなく実行(環境変数は無視される)
# - 非推奨警告は表示されないLegacy経路が存在しないため

4.5 LoopFormBox経路の動作確認

# Step 5: LoopFormBox経路で複雑なループテスト
./target/release/hakorune apps/tests/loop_nested.nyash
./target/release/hakorune apps/tests/loop_break_continue.nyash
./target/release/hakorune apps/examples/json_query/main.nyash

# 期待結果: すべて正常実行

5. Rollback計画

5.1 Git Reset

# オプション1: Stash一時退避
git stash save "Legacy loop builder deletion - rollback point"

# オプション2: Commit後にRevert
git revert <commit_hash>

# オプション3: Hard Reset危険
git reset --hard HEAD~1

5.2 ファイル単位のRollback

# 特定ファイルのみ復元
git checkout HEAD -- src/mir/loop_builder/build.rs
git checkout HEAD -- src/mir/loop_builder/phi.rs
git checkout HEAD -- src/mir/loop_builder/mod.rs
git checkout HEAD -- src/mir/phi_core/loop_phi.rs
git checkout HEAD -- docs/guides/env-variables.md

6. リスク分析

6.1 高リスクRollback必須レベル

リスク: LoopFormBox経路にバグがあり、Legacy経路が実は必要だった

確率: ⚠️Phase 31で十分にテスト済み

影響: スモークテスト全体が失敗する可能性

軽減策:

  1. 削除前にスモークテスト全PASS確認Quick + Integration
  2. 削除後も段階的にコミットStep 1-3を別々にコミット
  3. 問題発見時は即座にRollback

6.2 中リスク(修正可能レベル)

リスク1: loop_header フィールドの削除漏れでLegacy互換性が残る

確率: ⚠️

影響: デッドコード残存(機能的には問題なし)

軽減策: Step 3.2で loop_header フィールドの保持理由を明確化(コメント追加)


リスク2: continue_snapshots がLegacy専用かLoopFormBox共通か不明確

確率: ⚠️

影響: 必要なフィールドを削除してしまう可能性

軽減策:

  1. continue_snapshots の使用箇所を再確認
  2. LoopFormBox経路でも使用されている場合は保持

6.3 低リスク(軽微な影響)

リスク1: ドキュメント更新漏れ

確率:

影響: ユーザー混乱(機能的には問題なし)

軽減策: Step 5でドキュメント一括更新


リスク2: collect_carrier_assigns() の削除誤判定

確率: 極低(確認済み: LoopCarrierAnalyzerBoxが使用

影響: LoopFormBox経路が壊れる

軽減策: Step 4で明示的に保持削除対象外リストに記載


7. 推奨実行順序

Phase 1: 事前確認1日

# 1. 現在のベースライン確認
tools/smokes/v2/run.sh --profile quick > baseline_quick.log
tools/smokes/v2/run.sh --profile integration > baseline_integration.log

# 2. 依存関係の最終確認
grep -r "build_loop_legacy\|prepare_loop_variables\|seal_block\|mark_block_unsealed\|build_expression_with_phis" src/mir/loop_builder/
grep -r "prepare_loop_variables_with\|seal_incomplete_phis_with\|save_block_snapshot\|IncompletePhi" src/mir/phi_core/

# 3. Git branch作成
git checkout -b phase31.2-legacy-loop-deletion

Phase 2: Step 1-3実装1日

# Step 1: build.rs 修正
# - build_loop_legacy() 削除 (Line 40-417)
# - build_loop() 簡略化 (Line 15-38)

# Step 2: phi.rs 修正
# - prepare_loop_variables() 削除 (Line 14-43)
# - seal_block() 削除 (Line 46-59)
# - mark_block_unsealed() 削除 (Line 78-82)

# Step 3: mod.rs 修正
# - build_expression_with_phis() 削除 (Line 333-336)
# - LoopBuilder struct フィールド削除
# - LoopBuilder::new() 初期化削除

# 中間テスト
cargo build --release
tools/smokes/v2/run.sh --profile quick

Phase 3: Step 4-5実装0.5日)

# Step 4: phi_core/loop_phi.rs 修正
# - prepare_loop_variables_with() 削除
# - seal_incomplete_phis_with() 削除
# - save_block_snapshot() 削除
# - IncompletePhi 型削除

# Step 5: ドキュメント更新
# - docs/guides/env-variables.md 修正

# 最終テスト
cargo build --release
tools/smokes/v2/run.sh --profile quick
tools/smokes/v2/run.sh --profile integration

Phase 4: レビューコミット0.5日)

# 1. 変更内容確認
git diff --stat
git diff src/mir/loop_builder/
git diff src/mir/phi_core/

# 2. コミット
git add src/mir/loop_builder/build.rs
git add src/mir/loop_builder/phi.rs
git add src/mir/loop_builder/mod.rs
git add src/mir/phi_core/loop_phi.rs
git add docs/guides/env-variables.md

git commit -m "refactor(phase31.2): Delete Legacy loop builder path (-493 lines)

- Delete build_loop_legacy() and 5 helper methods
- Simplify build_loop() to LoopFormBox-only
- Remove Legacy-specific fields (incomplete_phis, block_var_maps)
- Delete 4 phi_core helpers (prepare/seal/save/IncompletePhi)
- Update env-variables.md (remove HAKO_FORCE_LEGACY_LOOP)

Total reduction: 493 lines
Smoke tests: 272/296 PASS (baseline maintained)"

# 3. Push
git push origin phase31.2-legacy-loop-deletion

8. 成功基準

8.1 定量的基準

  • コード削減: 最低 450行 削減(目標: 493行
  • ビルド成功: cargo build --release 警告なし
  • Quick Profile: 272/296 PASS以上ベースライン維持
  • Integration Profile: 全PASS

8.2 定性的基準

  • コードの単純化: build_loop() がシンプルになるLegacy分岐削除
  • 保守性向上: Legacy経路のメンテナンスコストがゼロになる
  • 将来性: LoopFormBox経路のみに集中できる

9. Next Steps将来の最適化候補

9.1 loop_header フィールドの削除検討

現状: Legacy互換のため保持

将来: loop_latch に統一して loop_header を削除

削減見込み: 5-10行


9.2 continue_snapshots の削除検討

現状: Legacy互換のため保持

調査: LoopFormBox経路で本当に必要か確認

削減見込み: 10-15行


9.3 block_var_maps 削除の波及効果

影響: get_variable_at_block() メソッドが不要になる可能性

削減見込み: 15-20行


10. まとめ

削除対象サマリー(再掲)

カテゴリ ファイル 削減見込み
Legacy main build.rs 393行
Legacy helpers phi.rs 49行
Legacy helpers mod.rs 12行
Legacy core phi_core/loop_phi.rs 70行
Documentation env-variables.md 5行
合計 529行

: 実際の削減は 493行 を見込み(空行・コメント含む調整)


リスク・軽減策サマリー

リスク 確率 影響 軽減策
LoopFormBoxバグ 事前スモークテスト全PASS確認
フィールド削除漏れ コメント明確化・段階的コミット
ドキュメント漏れ 一括更新チェックリスト

推奨アプローチ

戦略: 段階的削除Step 1-3 → Step 4-5

理由:

  1. 問題発見時のRollback範囲を最小化
  2. 中間テストで早期検証
  3. レビューしやすい

期間: 合計 2-3日実装2日、レビュー0.5日、予備0.5日)


Prepared by: Claude (AI Agent) Date: 2025-10-19 Phase: 31.2 - Legacy Loop Builder Deletion