diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 378a4a24..836e2949 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -1,5 +1,59 @@ # Current Task +## ✅ Phase 185: JoinIR Strict Mode Semantics Cleanup (Completed - 2025-12-04) + +**Status**: ✅ **All Tasks Completed** → Clean Architecture Established + +**Key Achievement**: Strict mode semantics unified between Loop/If lowering. If lowering now has SINGLE strict check point (like Loop), eliminating double/triple-invocation problem. + +### Completed Tasks + +✅ **Task 1-2**: Strict flow inventory and design +- Created comprehensive flow inventory document +- Identified problem: If lowering had 3 strict check points vs Loop's 1 +- Document: `docs/private/roadmap2/phases/phase-185-joinir-strict-mode/strict_flow_inventory.md` + +✅ **Task 3**: If lowering strict check consolidation +- **Removed 2 strict checks** from `try_lower_if_to_joinir()` (lines 296, 314) +- **Kept 1 strict check** at caller level in `if_form.rs` (line 311) +- Pattern now matches Loop lowering: Result-returning box + single check at router + +✅ **Task 4**: Representative strict tests verified +- Loop (reference): `loop_min_while.hako` ✅ Passes with NYASH_JOINIR_STRICT=1 +- If Select: `joinir_if_select_simple.hako` ✅ Passes with NYASH_JOINIR_STRICT=1 +- If Merge: `joinir_if_merge_simple.hako` ✅ Passes with NYASH_JOINIR_STRICT=1 +- Fallback: All tests pass without strict mode (backward compatibility maintained) + +✅ **Task 5**: Documentation updated +- Phase 185 implementation complete +- Phase 184 Known Issues resolved (double-invocation problem fixed) +- CURRENT_TASK.md updated with completion status + +### Implementation Summary + +**Architecture Change**: Strict check consolidation + +| Component | Before (Problem) | After (Fixed) | +|-----------|-----------------|---------------| +| **try_lower_if_to_joinir** | 2 panic points (lines 296, 314) | 0 panic points (thin Result box) | +| **if_form.rs caller** | 1 panic point (line 311) | 1 panic point (SINGLE source) | +| **Total** | **3 check points** ❌ | **1 check point** ✅ | + +**Pattern Now Matches Loop Lowering**: +- Loop: `LoopToJoinLowerer::lower()` → Result → Single check in `join_ir_vm_bridge_dispatch` +- If: `try_lower_if_to_joinir()` → Option → Single check in `if_form.rs` + +**Modified Files**: +- `src/mir/join_ir/lowering/mod.rs` (removed 2 strict checks, -8 lines) +- `src/mir/builder/if_form.rs` (kept 1 strict check at caller level, 0 changes) + +**Semantic Guarantee**: +- strict=OFF: Lowering failure → fallback to traditional path (dev/test) +- strict=ON: Lowering failure → panic with clear message (production gate) +- Fail-Fast principle: ONE check point = ONE source of truth + +--- + ## ✅ Phase 184: JoinIR If Lowering Mainline (Completed - 2025-12-04) **Status**: ✅ **All Tasks Completed** → Phase 185+ Ready @@ -54,7 +108,7 @@ ### Known Issues (Non-blocking) -1. **Double-invocation in strict mode**: NYASH_JOINIR_STRICT=1 can panic even when lowering succeeds (skeleton + lowering passes). Workaround: use NYASH_JOINIR_DEBUG=1 instead. +1. ~~**Double-invocation in strict mode**: NYASH_JOINIR_STRICT=1 can panic even when lowering succeeds (skeleton + lowering passes). Workaround: use NYASH_JOINIR_DEBUG=1 instead.~~ ✅ **FIXED in Phase 185** 2. **Test output formatting**: Tests show "RC: 0" instead of expected print output (unrelated to If lowering infrastructure). ### Verification Commands diff --git a/src/mir/join_ir/lowering/mod.rs b/src/mir/join_ir/lowering/mod.rs index ad8322b3..c5503cb0 100644 --- a/src/mir/join_ir/lowering/mod.rs +++ b/src/mir/join_ir/lowering/mod.rs @@ -202,7 +202,8 @@ pub fn try_lower_if_to_joinir( return None; } let core_on = crate::config::env::joinir_core_enabled(); - let strict_on = crate::config::env::joinir_strict_enabled(); + // Phase 185: strict check moved to caller (if_form.rs) + // let strict_on = crate::config::env::joinir_strict_enabled(); // Phase 33-9.1: Loop専任関数の除外(Loop/If責務分離) // Loop lowering対象関数はIf loweringの対象外にすることで、 @@ -248,7 +249,7 @@ pub fn try_lower_if_to_joinir( return None; } } - let strict_allowed = strict_on && core_on && is_allowed; + // Phase 185: strict_allowed removed (strict check moved to caller: if_form.rs) if debug_level >= 1 { eprintln!( @@ -286,6 +287,8 @@ pub fn try_lower_if_to_joinir( if_select::IfSelectLowerer::new(debug_level) }; + // Phase 185: Remove strict checks from lowerer (thin Result-returning box) + // Strict mode panic should happen at caller level (if_form.rs), not here if !if_select_lowerer.can_lower_to_select(func, block_id) { if debug_level >= 1 { eprintln!( @@ -293,12 +296,6 @@ pub fn try_lower_if_to_joinir( func.signature.name ); } - if strict_allowed { - panic!( - "[joinir/if] strict mode: pattern not matched for {}", - func.signature.name - ); - } return None; } @@ -311,13 +308,6 @@ pub fn try_lower_if_to_joinir( ); } - if result.is_none() && strict_allowed { - panic!( - "[joinir/if] strict mode: lowering failed for {}", - func.signature.name - ); - } - result }