diff --git a/src/mir/builder/control_flow/joinir/patterns/router.rs b/src/mir/builder/control_flow/joinir/patterns/router.rs index 78878d18..3e9188c3 100644 --- a/src/mir/builder/control_flow/joinir/patterns/router.rs +++ b/src/mir/builder/control_flow/joinir/patterns/router.rs @@ -123,10 +123,6 @@ pub(crate) struct LoopPatternEntry { /// Human-readable pattern name for debugging pub(crate) name: &'static str, - /// Priority (lower = tried first). Pattern1=10, Pattern2=20, Pattern3=30 - #[allow(dead_code)] - pub(crate) priority: u8, - /// Detection function: returns true if this pattern matches pub(crate) detect: fn(&MirBuilder, &LoopPatternContext) -> bool, @@ -135,29 +131,32 @@ pub(crate) struct LoopPatternEntry { } /// Static table of all registered loop patterns. -/// Patterns are tried in priority order (lowest first). +/// +/// **IMPORTANT**: Patterns are tried in array order (SSOT). +/// Array order defines priority - earlier entries are tried first. +/// Pattern5 (most specific) → Pattern4 → Pattern3 → Pattern1 → Pattern2 /// /// # Current Patterns (Phase 131-11: Pattern 5 added) /// /// All patterns now use structure-based detection via LoopFeatures and classify(): /// -/// - Pattern 5 (priority 1): Infinite Loop with Early Exit (llvm_stage3_loop_only.hako) [Phase 131-11] +/// - Pattern 5: Infinite Loop with Early Exit (llvm_stage3_loop_only.hako) [Phase 131-11] /// - Detection: pattern_kind == InfiniteEarlyExit /// - Structure: is_infinite_loop && has_break && has_continue /// -/// - Pattern 4 (priority 5): Loop with Continue (loop_continue_pattern4.hako) +/// - Pattern 4: Loop with Continue (loop_continue_pattern4.hako) /// - Detection: pattern_kind == Pattern4Continue /// - Structure: has_continue && !has_break /// -/// - Pattern 3 (priority 30): Loop with If-Else PHI (loop_if_phi.hako) +/// - Pattern 3: Loop with If-Else PHI (loop_if_phi.hako) /// - Detection: pattern_kind == Pattern3IfPhi /// - Structure: has_if_else_phi && !has_break && !has_continue /// -/// - Pattern 1 (priority 10): Simple While Loop (loop_min_while.hako) +/// - Pattern 1: Simple While Loop (loop_min_while.hako) /// - Detection: pattern_kind == Pattern1SimpleWhile /// - Structure: !has_break && !has_continue && !has_if_else_phi /// -/// - Pattern 2 (priority 20): Loop with Conditional Break (joinir_min_loop.hako) +/// - Pattern 2: Loop with Conditional Break (joinir_min_loop.hako) /// - Detection: pattern_kind == Pattern2Break /// - Structure: has_break && !has_continue /// @@ -165,31 +164,26 @@ pub(crate) struct LoopPatternEntry { pub(crate) static LOOP_PATTERNS: &[LoopPatternEntry] = &[ LoopPatternEntry { name: "Pattern5_InfiniteEarlyExit", - priority: 1, // Highest priority - most specific (infinite loop with break+continue) detect: super::pattern5_infinite_early_exit::can_lower, lower: super::pattern5_infinite_early_exit::lower, }, LoopPatternEntry { name: "Pattern4_WithContinue", - priority: 5, // Second priority - continue without break detect: super::pattern4_with_continue::can_lower, lower: super::pattern4_with_continue::lower, }, LoopPatternEntry { name: "Pattern3_WithIfPhi", - priority: 30, // NOTE: Pattern 3 must be checked BEFORE Pattern 1 (both use "main") detect: super::pattern3_with_if_phi::can_lower, lower: super::pattern3_with_if_phi::lower, }, LoopPatternEntry { name: "Pattern1_Minimal", - priority: 10, detect: super::pattern1_minimal::can_lower, lower: super::pattern1_minimal::lower, }, LoopPatternEntry { name: "Pattern2_WithBreak", - priority: 20, detect: super::pattern2_with_break::can_lower, lower: super::pattern2_with_break::lower, }, diff --git a/src/mir/builder/control_flow/joinir/routing.rs b/src/mir/builder/control_flow/joinir/routing.rs index eb3f62bd..178002da 100644 --- a/src/mir/builder/control_flow/joinir/routing.rs +++ b/src/mir/builder/control_flow/joinir/routing.rs @@ -128,19 +128,19 @@ impl MirBuilder { // Phase 200-C: Pass fn_body_ast to LoopPatternContext if available // Clone fn_body_ast to avoid borrow checker issues let fn_body_clone = self.fn_body_ast.clone(); - eprintln!( - "[routing] fn_body_ast is {} for '{}'", - if fn_body_clone.is_some() { - "SOME" - } else { - "NONE" - }, - func_name + trace::trace().routing( + "router", + func_name, + &format!( + "fn_body_ast is {}", + if fn_body_clone.is_some() { "SOME" } else { "NONE" } + ), ); let ctx = if let Some(ref fn_body) = fn_body_clone { - eprintln!( - "[routing] Creating ctx with fn_body ({} nodes)", - fn_body.len() + trace::trace().routing( + "router", + func_name, + &format!("Creating ctx with fn_body ({} nodes)", fn_body.len()), ); LoopPatternContext::with_fn_body(condition, body, &func_name, debug, fn_body) } else { diff --git a/src/mir/builder/control_flow/joinir/routing_legacy_binding.rs b/src/mir/builder/control_flow/joinir/routing_legacy_binding.rs index b5da5bc7..3132f1aa 100644 --- a/src/mir/builder/control_flow/joinir/routing_legacy_binding.rs +++ b/src/mir/builder/control_flow/joinir/routing_legacy_binding.rs @@ -128,35 +128,16 @@ impl MirBuilder { ), ); - // Step 3: Lower to JoinIR with panic catch + // Step 3: Lower to JoinIR (Fail-Fast: no silent error swallowing) + // Phase 132-Post: Removed catch_unwind - panics should be fixed at the source let join_module = { let json_clone = program_json.clone(); - let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - let mut lowerer = AstToJoinIrLowerer::new(); - lowerer.lower_program_json(&json_clone) - })); + let mut lowerer = AstToJoinIrLowerer::new(); - match result { - Ok(module) => module, - Err(e) => { - let panic_msg = if let Some(s) = e.downcast_ref::<&str>() { - s.to_string() - } else if let Some(s) = e.downcast_ref::() { - s.clone() - } else { - "unknown panic".to_string() - }; - - trace::trace().debug( - "router", - &format!( - "JoinIR lowering failed for {}: {} (unsupported pattern)", - func_name, panic_msg - ), - ); - return Ok(None); - } - } + // If lower_program_json panics, the panic will propagate up + // This is intentional - we want to catch and fix panics at their source + // rather than silently swallowing them with Ok(None) + lowerer.lower_program_json(&json_clone) }; let join_meta = JoinFuncMetaMap::new();