docs(joinir): Phase 63 - AST ownership analyzer (dev-only)

ASTNode → OwnershipPlan の解析器を追加(analysis-only, normalized_dev)。

Key changes:
- New ast_analyzer.rs (~370 lines):
  - AstOwnershipAnalyzer: AST → Vec<OwnershipPlan>
  - ScopeKind: Function/Loop/If/Block
  - Invariants: owned_vars/relay_writes/captures/condition_captures

Design:
- JSON v0 "Local=rebind" を使わず、AST の Statement::Local を正しく扱う
- "読むのは自由、管理は直下だけ" アーキテクチャ維持

Tests: 3 unit tests + 47/47 normalized_dev PASS
- loop_local_carrier_is_owned_and_written
- condition_capture_is_reported_for_loop
- relay_write_detected_for_outer_owned_var

Next: Phase 64 - P3(if-sum) 本番ルートへ dev-only で接続

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-12 22:51:21 +09:00
parent acb6720d9b
commit 0ff96612cf
6 changed files with 951 additions and 1 deletions

View File

@ -53,4 +53,5 @@ Phase 61 は「Break(P2) に P3 固有ロジックを混ぜない」を達成し
## Next Candidates
- Phase 62: P3(if-sum) の「本番 MIR→JoinIR ルート」へ OwnershipPlan を渡す設計AST-based ownership 解析の接続点を設計 → dev-only で段階接続)。
- Phase 63: ASTNode → OwnershipPlan の analyzer を追加analysis-only, dev-only
- Phase 63+: multi-hop / merge relay の意味論設計Fail-Fast を解除する前に SSOT と不変条件を明文化)。

View File

@ -0,0 +1,28 @@
# Phase 63 Summary: Ownership AST Analyzer (dev-only)
## Goal
本番ルートMIR builderの入力である `crate::ast::ASTNode` から、Ownership-Relay の解析結果(`OwnershipPlan`)を生成できるようにする。
- JSON v0 専用の「Local=rebind」扱いは使わない
- `normalized_dev` feature 下でのみ有効analysis-only
## Changes
- 追加: `src/mir/join_ir/ownership/ast_analyzer.rs`
- `AstOwnershipAnalyzer` を実装AST → `Vec<OwnershipPlan>`
- ScopeKind: Function / Loop / If / Block
- 不変条件: `owned_vars / relay_writes / captures / condition_captures``OwnershipPlan` として出力
- 導線: `src/mir/join_ir/ownership/mod.rs`
- `#[cfg(feature = "normalized_dev")] pub use ast_analyzer::*;` を追加
## Tests
- `src/mir/join_ir/ownership/ast_analyzer.rs` 内にユニットテストを追加:
- loop-local owned + writecarrier 相当)
- condition capturecondition_captures ⊆ captures
- relay write外側 owned への更新)
## Notes
- Phase 64 で、本番 P3(if-sum) ルート(`pattern3_with_if_phi.rs`)へ dev-only で接続し、carrier order / boundary inputs の SSOT 化を開始する。

View File

@ -0,0 +1,105 @@
# Phase 62: Ownership → P3 (if-sum) Production Route Design (dev-only)
## Goal
本番の MIR→JoinIR ルート(`src/mir/builder/control_flow/joinir/patterns/pattern3_with_if_phi.rs`)に対して、
Ownership-Relay の契約owned / captures / relay_writesを SSOT として差し込み、
P3(if-sum) の boundary inputshost_inputs / join_inputsと carrier set を「推測」から「解析結果」へ移行する。
前提: 既定挙動は不変。`normalized_dev` feature + dev 実行ガード下で段階接続する。
## Context
- Phase 5660: OwnershipPlan / relay / plan_to_lowering を整備し、fixtures ルートで段階的に接続済み。
- Phase 61: Break(P2) への by-name 混入を撤去し、if-sum+break は別箱で構造的に導入した。
- Phase 63: 本番 AST`ASTNode`)から OwnershipPlan を生成できる `AstOwnershipAnalyzer` を追加したdev-only, analysis-only
本番の P3(if-sum) lowering は、OwnershipPlan を受け取らず、carrier set/inputs が解析 SSOT で固定されていない。
## Scope (This Phase)
このフェーズは **設計のみ**SSOT 文書)。コード変更は Phase 64 で行う。
### In scope
- 本番 P3(if-sum) ルートで OwnershipPlan を導入する「接続点」の決定
- OwnershipPlan と既存コンポーネントConditionEnv / ExitMeta / CarrierInfoの責務境界を明文化
- dev-only の段階接続計画Fail-Fast 条件/回帰テスト方針)を決める
### Out of scope
- multi-hop relay / merge relay別フェーズで意味論設計が必要
- 新しい言語仕様・パターン拡張
- 既定挙動変更canonical への昇格など)
## Current Production Route (P3 if-sum)
入口: `src/mir/builder/control_flow/joinir/patterns/pattern3_with_if_phi.rs`
現状の流れ(簡略):
1. `build_pattern_context(...)``PatternPipelineContext` を構築
2. `ctx.is_if_sum_pattern()` のとき `lower_pattern3_if_sum(...)` を実行
3. `ConditionEnvBuilder``ConditionEnv + condition_bindings` を構築
4. `lower_if_sum_pattern(...)` が JoinIR を生成し、`fragment_meta.exit_meta` を返す
5. `ExitMetaCollector::collect(..., Some(&ctx.carrier_info), ...)` で exit_bindings を作る
6. `JoinInlineBoundaryBuilder``with_inputs(...)` / `with_condition_bindings(...)` / `with_exit_bindings(...)` を渡して conversion pipeline を実行
課題:
- carrier set が OwnershipPlanowned/relay/captureと一致する保証がない
- 解析 SSOT が無い状態で境界 inputs が構築され、混線を早期に検出しづらい
## Target Architecture (Ownership as SSOT)
### SSOT
- **OwnershipPlan** を SSOT とし、P3(if-sum) の「管理carrier」と「参照capture」を固定する。
- `carriers = writes ∩ owned`Ownership-Relay の不変条件)を P3 本番ルートでも維持する。
### Key Idea
P3(if-sum) で必要なのは次の 2 点:
1. **carrier set**: boundary inputs / exit bindings の対象集合を固定する
2. **capture set**: 条件式が読むだけの外部値を condition_bindings に限定し、carrier と混ぜない
carrier order は JoinIR 側の exit_meta / 既存 carrier_info と整合チェックで段階的に移行する)
## Integration Point (Where to Compute OwnershipPlan)
候補は 1 点に絞る:
- `cf_loop_pattern3_with_if_phi` 内で `build_pattern_context(...)` の直後
- `PatternPipelineContext` は loop_varname/idと bodyASTを持ち、P3 判定も済んでいる
- ここで OwnershipPlan を生成し、以後の boundary 構築の整合チェックに使う
## Required Interface (Already available)
- `AstOwnershipAnalyzer`Phase 63: `ASTNode` から `Vec<OwnershipPlan>` を生成
- 実装サマリ: `docs/development/current/main/PHASE_63_SUMMARY.md`
## Fail-Fast Contracts (Production Route, dev-only)
OwnershipPlan を導入する際、次を Fail-Fast で固定する:
1. **Single-hop relay only**: `relay_path.len() > 1` は Err段階移行の安全策
2. **Carrier set alignment**:
- OwnershipPlan から得た carriers 集合が、`ctx.carrier_info` および `exit_meta.exit_values` の集合と一致しない場合は Err
3. **No by-name switching**:
- 関数名/Box名で意味論を変える分岐は禁止
- ルートの切替は既存の pattern 判定(`ctx.is_if_sum_pattern()`)と構造チェックのみ
## Migration Plan (Next Phase)
### Phase 64: P3 本番ルートへ dev-only 接続
- `pattern3_with_if_phi.rs` に dev-only で OwnershipPlan を導入
- boundary inputs / exit bindings に対して carrier set の整合チェックを追加し、混線を Fail-Fast で検出可能にする
- carrier order は既存の exit_meta / carrier_info と一致することを前提にし、順序の SSOT 化は後続フェーズで行う
## References
- Ownership SSOT: `docs/development/current/main/phase56-ownership-relay-design.md`
- Phase 61 summary: `docs/development/current/main/PHASE_61_SUMMARY.md`
- Phase 63 summary: `docs/development/current/main/PHASE_63_SUMMARY.md`
- Production P3 route: `src/mir/builder/control_flow/joinir/patterns/pattern3_with_if_phi.rs`