Files
hakorune/docs/development/roadmap/phases/phase-26-F
nyash-codex 8750186e55 chore: Phase 26-H セッション完了 - 全ドキュメント更新
Phase 26-H 完了内容:
 JoinIR 型定義実装(src/mir/join_ir.rs)
 MIR → JoinIR 自動変換実装(lower_min_loop_to_joinir)
 自動変換テスト実装(mir_joinir_min_auto_lowering)
 PHI/Loop箱 → JoinIR 移行対応表追加(loopform_ssot.md)

ドキュメント更新:
- Phase 27 JoinIR タスク計画追加
- Phase 26-H タスク完了記録
- 各種 README 更新(進捗反映)
- CURRENT_TASK.md 更新

コミット統計: $(git status --short | wc -l) files changed

次のステップ: Phase 27 一般化 MIR → JoinIR 変換
2025-11-23 05:53:27 +09:00
..

Phase 26-F — Loop Exit Liveness / BodyLocal PHI Guard Line

Status: planning設計 + 受け口整備。MIRスキャン本体は後続フェーズ

ゴール

  • LoopForm v2 / Exit PHI まわりで残っている BodyLocal 変数の未定義バグを、「箱」と「MIR スキャン」に分けて根治する。
  • すでに Phase 26-E までで固めた PHI SSOTPhiBuilderBox / IfForm / ExitPhiBuilder / BodyLocalPhiBuilderを前提に
    • 分類LoopVarClassBox
    • 実際の使用LoopExitLivenessBox, 将来の MIR スキャン) をきちんと分離する。
  • その上で FuncScanner / StageB / Stage1 入口で発生している use of undefined value を、構造から潰す足場を固める。

スコープ26-F でやること)

FA: Exit PHI 4箱構成の確定とガード

  • ファイル:
    • src/mir/phi_core/loop_var_classifier.rs
    • src/mir/phi_core/local_scope_inspector.rs
    • src/mir/phi_core/body_local_phi_builder.rs
    • src/mir/phi_core/loop_exit_liveness.rs(新設済み)
    • src/mir/phi_core/phi_invariants.rs
    • src/mir/phi_core/exit_phi_builder.rs
  • やること:
    • 4箱構成をドキュメントに固定するコードはほぼ出来ているので設計を追記する:
      • LoopVarClassBox: Pinned / Carrier / BodyLocalExit / BodyLocalInternal の分類専用。
      • LoopExitLivenessBox: ループ exit 後で「生きている変数」の集合を返す箱Phase 26-F 時点では保守的近似+環境変数ガード)。
      • BodyLocalPhiBuilder: 分類結果と live_at_exit を OR 判定し、「どの BodyLocal に exit PHI が必要か」だけを決める箱。
      • PhiInvariantsBox: 「全 pred で定義されているか」を FailFast でチェックする箱。
    • NYASH_EXIT_LIVE_ENABLE が未設定のときは 従来挙動Phase 26-F-3 相当) に固定されることを明文化。
    • NYASH_EXIT_LIVENESS_TRACE=1 で、将来の MIR スキャン実装時にトレースを出す方針を記録。

FB: MIR スキャン前提の ExitLiveness 受け口設計

  • ファイル:
    • src/mir/phi_core/loop_exit_liveness.rs
    • src/mir/phi_core/exit_phi_builder.rs
    • (将来)src/mir/loop_builder.rs / src/mir/function.rs
    • src/mir/query.rsMirQuery/MirQueryBox
  • やること:
    • ExitLiveness 用のトレイトを決める → 実装済み
      • ExitLivenessProvider::compute_live_at_exit(header_vals, exit_snapshots) -> BTreeSet<String>
      • 既定実装は LoopExitLivenessBoxPhase 26-F-3 と同じ空集合、env ガード付き)
      • Phase 2+ 用の MirScanExitLiveness を追加済み。現時点では「header_vals + exit_snapshots に出現する変数の union」を返す簡易スキャンで、NYASH_EXIT_LIVE_ENABLE=1 で opt-in。後続フェーズ26-G 以降)で MIR 命令列スキャンに差し替える想定。
    • Phase 26-F では「箱とインターフェース」だけ決めて、実装は保守的近似 or ダミーのままに留める。
    • ExitPhiBuilderExitLivenessProvider の結果だけを見るようにしたので、後続フェーズで MirScanExitLiveness に差し替え可能(依存逆転)。

FC: FuncScanner / parse_params / trim 用の再現ケース固定

  • ファイル:
    • lang/src/compiler/entry/func_scanner.hako
    • lang/src/compiler/tests/funcscanner_skip_ws_min.hako
    • lang/src/compiler/tests/funcscanner_parse_params_trim_min.hako
    • src/tests/mir_funcscanner_skip_ws.rs
    • src/tests/mir_funcscanner_parse_params_trim_min.rs
  • やること:
    • すでに作成済みの 2 本の Rust テストを「ExitLiveness / BodyLocal PHI のカナリア」として位置づける:
      • mir_funcscanner_skip_ws_direct_vm
      • mir_funcscanner_parse_params_trim_min_verify_and_vm
    • この 2 本が、今後の MIR スキャン実装Phase 26-G 相当で「ExitLiveness を差し込んだときに必ず緑になるべき」ターゲットであることを docs に固定。
    • _trim / skip_whitespace 本体には、__mir__.log ベースの軽量観測が既に仕込まれているので、その存在を mir-logs-observability.md 側にリンクしておく。

FD: 将来フェーズMIR スキャン本体)への橋渡し

  • ファイル候補:
    • docs/private/roadmap2/phases/phase-26-F/README.md(本ファイル)
    • docs/development/architecture/loops/loopform_ssot.md
  • やること:
    • Phase 26-F では「箱」と「受け口」と「環境変数ガード」までに留め、MIR 命令列の実スキャンは次フェーズ26-G など)に分離する方針を書き切る。
    • LoopFormOps を拡張して MIR 命令列にアクセスする案(get_block_instructions 等)を、設計レベルでメモしておく。
    • ExitLiveness の MIR スキャン実装は:
      • exit ブロック(必要ならその直後)での use/def を収集し、
      • 逆 RPO で固定点反復して live_in/ live_out を決める、 といった最小の liveness アルゴリズムで良いことを明記。

このフェーズで「やらない」こと

  • LoopFormOps / MirBuilder の広範な API 拡張や、大規模な構造変更。
    • MIR スキャン本体の導入は 26-F ではなく 26-G 以降に分離し、ここではあくまで箱と受け口とドキュメントに留める。
  • 既存の LoopForm v2 / Exit PHI ロジックの意味的変更。
    • NYASH_EXIT_LIVE_ENABLE が未設定のときの挙動は、Phase 26-F-3 と同等に保つ(テストもそれを期待する)。
  • StageB / Stage1 CLI / UsingResolver の本線仕様変更。
    • 26-F で触るのはあくまで PHI/SSA のインフラ層のみ。高レベル仕様は 25.x の各フェーズに従う。

受け入れ条件26-F

  • Docs:
    • docs/development/architecture/loops/loopform_ssot.md に 4箱構成LoopVarClassBox / LoopExitLivenessBox / BodyLocalPhiBuilder / PhiInvariantsBoxの役割が追記されている。
    • 本 README に ExitLiveness の受け口設計ExitLivenessProvider 相当と、MIR スキャン本体を次フェーズに送る方針が書かれている。
  • コード:
    • NYASH_EXIT_LIVE_ENABLE が未設定のとき、Phase 26-F-3 と同等かそれ以上のテスト結果PASS 増 / FAIL 減)を維持している。
    • LoopExitLivenessBox / BodyLocalPhiBuilder / PhiInvariantsBox / ExitPhiBuilder の依存関係が一方向(解析→判定→生成→検証)に整理されている。
  • テスト:
    • mir_funcscanner_skip_ws_direct_vm / mir_funcscanner_parse_params_trim_min_verify_and_vm が引き続き「ExitLiveness/BodyLocal PHI カナリア」として動作し、PHI/SSA の変更時に必ず確認される位置づけになっている。