Phase 124: Reads Facts SSOT + Return(Variable) 解禁 (dev-only)
目的
StepTreeFacts に reads フィールドを追加し、Normalized側が「変数return/cond」を再解析なしで扱えるようにする。
背景
現在、Normalized builder は writes のみを env として持ち、Return(Variable(name)) が来たときに name が env に無いと処理できない。Phase 123 では Return(Unknown) を導入したが、これは "値が決まらない" 場合であり、「変数名は分かっているが env に無い」ケースとは異なる。
Phase 124 では、StepTreeFacts に reads を追加し、変数参照を明示的に記録することで、Normalized側が「この変数は読まれている」という情報を持てるようにする。
方針
reads の収集範囲
- Variable(name): 式中の変数参照は reads に追加
- Assign の RHS: 代入の右辺に出てくる Variable も reads に追加
- 条件式: cond_ast / cond_sig 内の Variable も reads に追加(式の意味解析は不要、構文木から拾う)
reads の扱い
- reads は「識別できた local 名だけ」でOK
- 不明な読み込みは capability/unknown-read に落とす(Phase 125以降で対応)
- reads は BTreeSet で決定的にソート
- StepTreeContract の signature に含める(basis string に影響)
Return(Variable) の実装
- Normalized builder で Return(Variable(name)) を処理
- name が env にあるなら env から値を取り
Ret(Some(v)) - env に無いが reads にあるなら Phase 124 では Fail-Fast にする
- dev-only:
NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1でのみ動作 - env に無い return var は strict モードで
freeze_with_hintを呼び出してエラー
- dev-only:
実装計画
P1: StepTreeFacts に reads を追加
-
src/mir/control_tree/step_tree_facts.rsreads: BTreeSet<String>追加- API:
add_read(name)/merge_reads()
-
src/mir/control_tree/step_tree.rs(または facts builder)- Variable(name) を見たら
add_read(name) - Assign は writes に入れるが、RHS 内の Variable は reads として拾う
- 条件式(cond_ast / cond_sig)も "Variable が出たら reads" に入れる
- Variable(name) を見たら
P2: StepTreeContractBox に reads を反映
src/mir/control_tree/step_tree_contract_box.rsStepTreeContractに reads を追加(順序は決定的)signature_basis_string()に reads を含める(BTreeSet の順で安定)
P3: Normalized builder で Return(Variable) を実装
src/mir/control_tree/normalized_shadow/builder.rs- Return(Variable(name)):
- name が env にあるなら env から値を取り
Ret(Some(v)) - env に無いが reads にあるなら Phase 124 では Fail-Fast にする
- dev-only:
NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1でのみ動作 - env に無い return var は strict モードで
freeze_with_hintを呼び出してエラー
- dev-only:
- name が env にあるなら env から値を取り
- unit test:
x=7; return xが生成できる
- Return(Variable(name)):
P4: integration smoke
- fixture:
apps/tests/phase124_if_only_return_var_min.hako(expected 7)local x = 7; return x
- smoke:
tools/smokes/v2/profiles/integration/apps/phase124_if_only_return_var_vm.shNYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1で PASS 固定
P5: docs 完了
docs/development/current/main/10-Now.md/ INDEX / backlog 更新
受け入れ基準
- StepTreeFacts に reads が追加される
- StepTreeContract の signature に reads が含まれる
- Normalized builder で Return(Variable) が処理できる(dev-only)
- integration smoke が PASS する
- 既存テストが全て PASS する(signature 変更によるテスト更新は許容)
制約事項
- dev-only:
NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1でのみ動作 - 既定挙動は不変: 環境変数無しでは従来通り(Phase 123 まで)
- Fail-Fast 原則: env に無い return var は strict モードでエラー
次のステップ(Phase 125以降)
- unknown-read capability の導入
- reads に基づく環境拡張(env に無い変数を reads から補完)
- loop との統合(loop 内の reads を継続的に追跡)
参照
- Phase 123: Return(Unknown) 導入
- Phase 121: Shadow If Only 基本実装
- Phase 118: Loop Nested If Merge