Phase 287: KeepAlive/ReleaseStrong 命令分離
## 変更内容(2つの側面)
### 1. 命令セマンティクスの分離
- KeepAlive { values, drop_after: bool } を2命令に分離
- KeepAlive { values }: スコープ終了での生存維持(PURE)
- ReleaseStrong { values }: 変数上書き時の強参照解放(WRITE)
- 効果分析の明確化: PURE vs WRITE の境界確定
### 2. VM実行サポート
- handlers/mod.rs: KeepAlive → 完全 no-op
- handlers/mod.rs: ReleaseStrong → release_strong_refs() 呼び出し
- handlers/lifecycle.rs: handle_keepalive() 削除
## 影響範囲
- 10 ファイル修正(31箇所の出現を全変換)
- instruction.rs, builder.rs, lexical_scope.rs, methods.rs,
display.rs, printer_helpers.rs, query.rs, joinir_id_remapper.rs,
handlers/mod.rs, handlers/lifecycle.rs
## 検証
- 154/154 quick smoke PASS
- weak テスト回帰なし(weak_upgrade_fail, weak_basic)
- rg -n drop_after src → 0 件(完全除去確認)
- MIRダンプで release_strong/keepalive 正常表示
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
mir::builder::vars(変数/スコープ系の小箱)
このディレクトリは「MIR ビルダ内の変数・スコープ」に関する小さな責務を分離するための層だよ。
責務(この層がやる)
- レキシカルスコープ:
{...}/ScopeBoxの境界でlocalのシャドウイングを復元する。 - AST 走査ユーティリティ: free vars 収集など、純粋な走査処理。
- 代入の宣言ポリシー: 未宣言名への代入を Fail-Fast にする(
AssignmentResolverBox)。
非責務(この層がやらない)
- JoinIR lowering 側の名前解決(
join_ir/lowering/*のScopeManagerが担当)。 - ループパターン/PHI/境界生成(
control_flow/joinir/*が担当)。 - 言語仕様の追加(この層は既存仕様の実装に限定)。
スコープ/名前解決の境界(SSOT)
同じ「名前」を扱っていても、層ごとに “解いている問題” が違うので混ぜない。
- MIR(この層):
variable_map+LexicalScopeGuardで「束縛の寿命・シャドウイング」を管理する(SSA 変換のため)。 - JoinIR lowering:
src/mir/join_ir/lowering/scope_manager.rsは JoinIR 内のname → ValueIdを解決する。ExprLowererは ScopeManager 経由のみ で名前解決する(env を直参照しない)。
- 解析箱:
LoopConditionScopeBox/LoopBodyLocalEnvは「禁止/許可」「スケジュール」などの補助情報で、束縛そのものではない。
この境界を跨ぐ “便利メソッド” を作るのは原則禁止(責務混線の温床)。