--- Status: Active Scope: code(仕様不変、未接続のSSOT足場) Related: - docs/development/current/main/phases/phase-29an/README.md - docs/development/current/main/design/coreplan-skeleton-feature-model.md - docs/development/current/main/design/exitkind-cleanup-effect-contract-ssot.md - docs/development/current/main/phases/phase-29ae/README.md --- # Phase 29an P1: FeatureFacts SSOT(ExitMap/ValueJoin/Cleanup の材料) Date: 2025-12-29 Status: Ready for execution Scope: Facts に “Feature(特徴)” の材料を追加する(未接続、仕様不変) ## Objective - “complete pattern 列挙” を増やさず、**Skeleton に直交する Feature** を Facts 側へ寄せる足場を作る - まずは最小の **ExitUsage(break/continue/return の存在)** を SSOT として定義し、将来の ExitMap 合成へ繋げる ## Non-goals - ルーティング順序・観測・エラー文字列の変更 - 既存 planner-first/legacy extractor の削除 - 新 env var / 恒常ログ追加 - “対象っぽいのに不整合” を Ok(None) で隠す(P1 は **Freeze を増やさない**) ## Implementation(構造優先) ### Step 1: FeatureFacts 型を追加(SSOT) Add: - `src/mir/builder/control_flow/plan/facts/feature_facts.rs` Suggested vocabulary(最小・後拡張可能): - `LoopFeatureFacts` - `exit_usage: ExitUsageFacts`(実装する) - `value_join: Option`(P1 は placeholder = `None`) - `cleanup: Option`(P1 は placeholder = `None`) - `ExitUsageFacts { has_break, has_continue, has_return }` Extraction(保守的): - `break/continue/return` の **存在**だけ見る(位置/対応付けは P2+) - ネストした loop の exit は外側に数えない(外側の ExitMap を誤推論しない) - `if` の then/else の中は再帰で見る(ただし “未知ノード” は無視) 方針: - `ExitUsageFacts` は `Default` を持ち、使う側が簡単に埋められるようにする - ここは **Facts層**なので、Plan/Frag/emit を import しない ### Step 2: facts/mod.rs に module 登録 Update: - `src/mir/builder/control_flow/plan/facts/mod.rs` Add: - `pub(in crate::mir::builder) mod feature_facts;` ### Step 3: LoopFacts に optional で接続(既定挙動は不変) Update: - `src/mir/builder/control_flow/plan/facts/loop_facts.rs` Add: - `pub features: Option` Rules: - `Ok(None)` の gate(“何も取れないなら None”)は **そのまま** - 既存の pattern facts が 1 つでも取れた場合だけ `features: Some(...)` を埋める - “features だけ取れた” で `Ok(Some)` にしない(既定挙動を変えない) ### Step 4: planner/build.rs の unit tests を調整 Update: - `src/mir/builder/control_flow/plan/planner/build.rs` If tests construct `LoopFacts` directly, add: - `features: None`(または `Some(LoopFeatureFacts::default())` を許可するならそれでもよいが、P1 は `None` 推奨) ## Tests(最低限) Add unit tests: - `break/continue/return` が loop body(if を含む)にあると `ExitUsageFacts` が立つ - nested loop 内の break/continue は外側の `ExitUsageFacts` に影響しない ## Verification(required) - `cargo build --release` - `./tools/smokes/v2/run.sh --profile quick` - `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` ## Commit - `git add -A && git commit -m "phase29an(p1): add loop feature facts ssot (exit usage)"`