fix(pattern2): abort entire Pattern2 on unpromoted LoopBodyLocal instead of partial execution
Phase 263 P0: Pattern2 で処理できない LoopBodyLocal を検出したら Pattern2 全体を早期終了 Changes: - promote_step_box.rs: 戻り値を Result<Option<_>, String> に変更 - Reject を二分化: 対象外(not_readonly等)→ Ok(None)、対象だが未対応 → Err - pattern2_lowering_orchestrator.rs: Ok(None) 検出で早期 return - apps/tests/phase263_p0_pattern2_seg_min.hako: test simplification 後続経路(legacy binding等)へ fallback させる(detection→extract→lower SSOT 維持) Fail-Fast 原則: 対象外は Ok(None) で後続経路へ、対象だが未対応は Err で即座に失敗 Fixes: core_direct_array_oob_set_rc_vm smoke test FAIL 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -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"
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -26,9 +26,11 @@ impl PromoteStepBox {
|
||||
mut inputs: Pattern2Inputs,
|
||||
debug: bool,
|
||||
verbose: bool,
|
||||
) -> Result<PromoteStepResult, String> {
|
||||
Self::promote_and_prepare_carriers(builder, condition, body, &mut inputs, debug, verbose)?;
|
||||
Ok(PromoteStepResult { inputs })
|
||||
) -> Result<Option<PromoteStepResult>, 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<Option<()>, 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(()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user