80 lines
3.5 KiB
Markdown
80 lines
3.5 KiB
Markdown
|
|
# 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.rs`
|
|||
|
|
- `src/mir/builder/control_flow/joinir/patterns/extractors/pattern5.rs`
|
|||
|
|
- `return` を 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 に固定
|
|||
|
|
|
|||
|
|
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 なし)
|
|||
|
|
|