refactor(joinir): Box-First cleanup - trace unification + SSOT + Fail-Fast

## Changes

### 1. eprintln! to trace.rs unification
**File**: src/mir/builder/control_flow/joinir/routing.rs
- Replaced direct eprintln! with trace::trace().routing()
- Box-First principle: Log responsibility centralized in trace.rs
- Enables filtering via HAKO_JOINIR_DEBUG=1

### 2. Priority field removal (SSOT)
**File**: src/mir/builder/control_flow/joinir/patterns/router.rs
- Removed #[allow(dead_code)] priority field
- Array order is SSOT (Single Source of Truth) for pattern priority
- Pattern try order: Pattern5 → Pattern4 → Pattern3 → Pattern1 → Pattern2
- Eliminated dead code warning

### 3. catch_unwind removal (Fail-Fast)
**File**: src/mir/builder/control_flow/joinir/routing_legacy_binding.rs
- Removed catch_unwind + Ok(None) silent error swallowing
- Fail-Fast principle: Panics propagate explicitly
- Enables early detection of panic sources

## Verification

 Build: cargo build --release (0 errors)
 Tests: 71 JoinIR tests all PASS
 VM: /tmp/p1_return_i.hako → Result: 3
 LLVM: /tmp/p1_return_i.hako → Mock exit code: 0

## Design Principles Applied

- **Box-First**: Log responsibility → trace.rs
- **SSOT**: Array order defines priority (no redundant field)
- **Fail-Fast**: Explicit failures, no silent error swallowing

## Statistics

- 3 files changed
- 53 deletions, 28 insertions
- Net: -25 lines (code reduction)

🤖 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-15 03:27:47 +09:00
parent 447d4ea246
commit 18d56d5b88
3 changed files with 27 additions and 52 deletions

View File

@ -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 {