# Phase 282 P9a 完了 (Scope-Limited Integration) ## 実装内容 - **common_helpers.rs 作成**: 4グループの共通ヘルパー統合 (316行) - Group 1: Control Flow Counting (count_control_flow - 汎用カウンター) - Group 2: Control Flow Detection (has_break/continue/return_statement) - Group 3: Condition Validation (extract_loop_variable, is_true_literal) - Group 4: Pattern5専用ヘルパー (validate_continue_at_end, validate_break_in_simple_if) - **Pattern統合完了**: Pattern5 → Pattern4 → Pattern2 → Pattern1 - Pattern5: ~90行削減 (5 tests PASS) - Pattern4: ~66行削減 (5 tests PASS) - Pattern2: ~67行削減 (4 tests PASS) - Pattern1: ~28行削減 (3 tests PASS) - Pattern3: 別フェーズに延期(pattern固有ロジック除外) ## 成果 - **コード削減**: ~251行(Pattern3除く、total ~400行見込み) - **テスト**: 40 unit tests PASS (23 common_helpers + 17 extractors) - **スモークテスト**: 45 PASS, 1 pre-existing FAIL(退行ゼロ) - **ビルド警告**: 130 → 120 (-10) ## USER CORRECTIONS適用済み 1. ✅ スコープ限定(共通ロジックのみ、pattern固有除外) 2. ✅ Placeholder禁止(SSOT違反排除) 3. ✅ 統合順序変更(Pattern3を最後/別フェーズへ) ## 追加ドキュメント - Phase 284 計画追加(Return as ExitKind SSOT) - 10-Now.md, 30-Backlog.md 更新 🎯 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
3.5 KiB
3.5 KiB
Phase 284 P1(code): Return as ExitKind SSOT(実装)
目的: return を pattern 固有の特例にせず、ExitKind::Return と compose::* / emit_frag() へ収束させる。
前提SSOT(P0):
docs/development/current/main/phases/phase-284/README.md- Phase 282 の境界ルール(SSOT=extract / close-but-unsupported=Err):
docs/development/current/main/phases/phase-282/README.md
実装方針(最小)
1) 返り値の運搬(ExitKind::Return + args)
return <expr>はExitKind::Returnの edgeとして表現する。- Return edge が持つ値は
EdgeArgsで運ぶ(Return terminator の operand)。 - terminator は
emit_frag()が生成する(pattern/box が直に Return 命令を生やさない)。
2) 「移行期間の穴」を消す
現状は Pattern4/5 などが return を Err(close-but-unsupported) にしている。
P1 のゴールは:
returnを含む loop-body が “別パターンへ静かに流れる” 状態をなくす- SSOT 経路で
ExitKind::Returnに落ちるようにする
実装タスク(推奨順)
Step 1: 現状の return ハンドリングを棚卸し(read-only)
-
joinir patterns extractors:
src/mir/builder/control_flow/joinir/patterns/extractors/pattern4.rssrc/mir/builder/control_flow/joinir/patterns/extractors/pattern5.rsreturnを Err にしている箇所(close-but-unsupported の根拠)を列挙する
-
control-flow lowering:
emit_frag()が Return edge をどう生成しているか確認する(target=None の Return wire/exit)compose::cleanup()の Return wiring が想定どおりか確認する
成果物: docs/development/current/main/phases/phase-284/P1-NOTES.md(短い箇条書きでOK)
Step 2: return を ExitKind に落とす “単一入口” を作る(root fix)
狙い:
- loop body のどの位置でも
returnが現れたらExitKind::Returnで外へ出せること - これを 1 箇所に寄せる(pattern 側に増やさない)
実装候補(どれか 1 つに決める):
- A) loop lowering(Frag 構築)段で Return edge を first-class で追加
- B) JoinIR conversion の merge 段で Return を ExitKind に正規化
要件:
- Fail-Fast: “表現できない return” は Err(silent fallback 禁止)
- 既定挙動は変えない(return を含む既存 fixture があれば、その期待値は明示して更新)
Step 3: extractor の return ポリシーを更新(穴を埋める)
P1 で Return SSOT が通るようになったら、以下を更新する:
- Pattern4/5 の extractor で
returnを Err にしない(close-but-unsupported ではなくなるため) - ただし “return があるせいでパターン形状が曖昧になる” 場合は Err を維持(Fail-Fast)
Step 4: fixture + smoke(VM/LLVM)で SSOT を固定
最小 fixture の要件:
returnが loop の then/else どちらかに現れる- exit code が安定(stdout 抑制の LLVM でも確認できる)
例(案):
apps/tests/phase284_p1_return_in_loop_min.hako- loop 内で条件により
return 7/continue等 - 最終 exit code を 7 に固定
- loop 内で条件により
smoke:
- VM: stdout/exit code を検証
- LLVM: exit code + harness の
Result: <code>を検証(stdout が出ない想定)
受け入れ基準
returnを含む loop fixture が VM/LLVM で同一動作- pattern 側に “return の特例 if” が増えていない(root fix のみ)
Ok(None)/Errの境界が崩れていない(silent fallback なし)