feat(joinir): Phase 142 P2 Step 3-A - Pattern4 early return fail-fast

This commit is contained in:
nyash-codex
2025-12-16 13:48:30 +09:00
parent 42339ca77f
commit 2674e074b6
8 changed files with 1029 additions and 30 deletions

View File

@ -363,3 +363,107 @@ Phase 142 P1 successfully extends the Canonicalizer to recognize continue patter
- Follows existing re-export pattern from Phase 140-P4-A
All acceptance criteria met. ✅
---
## P2: Pattern4 Lowering Extension (IN PROGRESS)
### Objective
Extend Pattern4 lowering to handle "continue + return" patterns found in parse_string/array/object.
### Target Pattern
- `tools/selfhost/test_pattern4_parse_string.hako` - Parse string with continue (escape) + return (quote)
### Pattern4 Lowering Contract (Phase 142 P2)
#### Accepted Minimum Structure
**Return Handling**:
- **Position**: Early return inside one or more if blocks
- **Type**: Scalar return values (complex returns are out of scope)
- **Constraint**: Only the last return in loop body is processed
**Continue Side Updates**:
- **Pattern**: `if cond { carrier = carrier ± 1; continue }`
- **Update**: Constant step only (+1, -1, +2, -2, etc.)
- **Constraint**: Multiple carriers not yet supported
**Carrier and Payload**:
- **Carrier**: Loop variable used in loop condition
- **Payload**: State updated on non-continue path (e.g., result string)
**Exit Contract**:
- `has_continue = true` (continue pattern exists)
- `has_return = true` (early return exists)
- Both must coexist
#### Unsupported (Fail-Fast)
The following patterns are rejected with explicit error messages:
- [ ] Multiple continue patterns (2+ continue statements)
- [ ] Nested continue-return (continue inside if inside if)
- [ ] Complex return values (returning multiple fields)
- [ ] Variable step updates (escape sequence handling, etc.)
### Implementation Strategy
**Step 1**: Clarify Pattern4 contract (this document)
**Step 2**: Add E2E test case
**Step 3**: Extend Pattern4 lowerer
**Step 4**: Consider box-ification / modularization
**Step 5**: Implementation and verification
### Progress
- [x] Step 1: Contract clarification
- [ ] Step 2: Add test case
- [ ] Step 3: Extend lowerer
- [ ] Step 4: Consider box-ification
- [ ] Step 5: Verification complete
### Acceptance Criteria
- ✅ Representative test (parse_string or simple_continue) passes JoinIR lowering
- ✅ Execution results are correct in both VM and LLVM (scope to be determined)
- ✅ No regression in existing tests (phase132_exit_phi_parity, etc.)
- ✅ Unsupported patterns fail fast with reason (error_tags)
- ✅ No new environment variables added (dev-only observation only)
- ✅ Documentation updated
### Files to Modify
1. `docs/development/current/main/phases/phase-142/README.md` - Contract documentation
2. `tools/selfhost/test_pattern4_parse_string_lowering.hako` - Minimal E2E test (new)
3. `src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs` - Lowerer extension
4. `src/mir/builder/control_flow/joinir/patterns/pattern4_carrier_analyzer.rs` - Carrier analysis (if needed)
### Step 3-A: Early Return Fail-Fast (COMPLETE ✅)
**Status**: ✅ COMPLETE - Return detection and explicit error implemented
**Implementation**: Added `has_return_in_body()` helper function to Pattern4 lowerer
- Recursively scans loop body for return statements
- Returns explicit Fail-Fast error when return is detected
- Error message references Phase 142 P2 for future lowering
**Test Results**: All 14 canonicalizer tests PASS (no regressions)
**Key Achievement**: Unsafe silent acceptance is now prevented - early returns explicitly surface as errors with actionable messages.
### Step 3-B: Return Path JoinIR Generation (DEFERRED)
**Status**: 🔄 DEFERRED for separate session - Large-scale implementation requires careful design
**Why separate**: JoinIR generation involves responsibility boundary decisions (Pattern4 direct vs delegation to Pattern5) and ExitMeta/payload handling. Separating ensures cleaner cause analysis.
**Design questions to resolve first**:
1. Should return be handled directly in Pattern4 lowerer, or delegated to Pattern5?
2. How to transport return payload through exit/boundary/ExitMeta (can we reuse ContinueReturn assets)?
### SSOT References
- **Design**: `docs/development/current/main/design/loop-canonicalizer.md`
- **JoinIR Architecture**: `docs/development/current/main/joinir-architecture-overview.md`
- **Pattern4 Implementation**: `src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs`