diff --git a/apps/tests/phase263_p0_pattern2_seg_min.hako b/apps/tests/phase263_p0_pattern2_seg_min.hako index 6a95b0bb..da570397 100644 --- a/apps/tests/phase263_p0_pattern2_seg_min.hako +++ b/apps/tests/phase263_p0_pattern2_seg_min.hako @@ -7,29 +7,19 @@ static box Main { main() { - local result = parse_segments() + local i = 0 + local seg = "" + + loop(i < 5) { + seg = "segment" // ← loop body で代入(ReadOnlySlot 契約違反) + + if seg == "end" { + break + } + + i = i + 1 + } + return 0 } } - -// Pattern2 が検出するループ構造 -method parse_segments() { - local i = 0 - local seg = "" - - loop(i < 5) { - seg = get_segment(i) // ← loop body で代入(ReadOnlySlot 契約違反) - - if seg == "end" { - break - } - - i = i + 1 - } - - return i -} - -method get_segment(idx) { - return "seg" -} diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern2_lowering_orchestrator.rs b/src/mir/builder/control_flow/joinir/patterns/pattern2_lowering_orchestrator.rs index 52ff83dd..d38d874f 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern2_lowering_orchestrator.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern2_lowering_orchestrator.rs @@ -63,7 +63,15 @@ impl Pattern2LoweringOrchestrator { let inputs = ApplyPolicyStepBox::apply(condition, body, facts)?; let promoted = PromoteStepBox::run(builder, condition, body, inputs, debug, verbose)?; - let mut inputs = promoted.inputs; + let mut inputs = match promoted { + Some(result) => result.inputs, + None => { + // Phase 263 P0: Pattern2 cannot handle this loop (e.g., reassigned LoopBodyLocal) + // Return Ok(None) to allow router to try next path (legacy binding) + super::super::trace::trace().debug("pattern2", "Pattern2 aborted (promotion failed), allowing fallback"); + return Ok(None); + } + }; // Phase 256.5: Wire current_static_box_name from builder context or function name inputs.current_static_box_name = current_box_name_for_lowering(builder); diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/promote_step_box.rs b/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/promote_step_box.rs index e3e7e0db..a67e8593 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/promote_step_box.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/promote_step_box.rs @@ -26,9 +26,11 @@ impl PromoteStepBox { mut inputs: Pattern2Inputs, debug: bool, verbose: bool, - ) -> Result { - Self::promote_and_prepare_carriers(builder, condition, body, &mut inputs, debug, verbose)?; - Ok(PromoteStepResult { inputs }) + ) -> Result, String> { + match Self::promote_and_prepare_carriers(builder, condition, body, &mut inputs, debug, verbose)? { + Some(()) => Ok(Some(PromoteStepResult { inputs })), + None => Ok(None), // Pattern2 cannot handle this loop + } } pub(in crate::mir::builder) fn promote_and_prepare_carriers( @@ -38,7 +40,7 @@ impl PromoteStepBox { inputs: &mut Pattern2Inputs, debug: bool, verbose: bool, - ) -> Result<(), String> { + ) -> Result, String> { use crate::mir::join_ir::lowering::digitpos_condition_normalizer::DigitPosConditionNormalizer; use crate::mir::loop_pattern_detection::loop_condition_scope::LoopConditionScopeBox; @@ -119,10 +121,26 @@ impl PromoteStepBox { inputs.read_only_body_local_slot = Some(slot); } PolicyDecision::Reject(reason) => { - return Err(error_messages::format_error_pattern2_promotion_failed( - &cond_body_local_vars, - &reason, - )); + // Phase 263 P0 + Step 2.5: Reject を二分化 + if reason.contains("not_readonly") + || reason.contains("No promotable pattern detected") + { + // 対象外: Pattern2 で処理できない形 → Ok(None) で後続経路へ + #[cfg(debug_assertions)] + { + eprintln!( + "[pattern2/promote_step] Pattern2 対象外(LoopBodyLocal {:?}): {}. 後続経路へfallback.", + cond_body_local_vars, reason + ); + } + return Ok(None); // Pattern2 全体を中止 + } else { + // 対象だが未対応(freeze級): 実装バグ or 将来実装予定 → Err で Fail-Fast + return Err(format!( + "[pattern2/promote_step] Pattern2 未対応エラー(LoopBodyLocal {:?}): {}", + cond_body_local_vars, reason + )); + } } PolicyDecision::None => {} } @@ -174,7 +192,7 @@ impl PromoteStepBox { } } - Ok(()) + Ok(Some(())) } }