Cleaned up unused imports after Phase 143 execution fix (5e662eaaf).
**Priority files (Phase 143)**:
- if_as_last_join_k.rs: removed ValueId, BTreeMap
- loop_true_break_once.rs: added #[cfg(test)] for test-only imports
- post_if_post_k.rs: removed ValueId, BTreeMap
- normalized_helpers.rs: added #[cfg(test)] for Span
**Additional cleanup**:
- contract_checks.rs: removed BasicBlockId
- joinir/mod.rs: removed Info struct re-exports (functions kept)
- patterns/mod.rs: removed Info struct re-exports (functions kept)
- ast_feature_extractor.rs: removed EscapeSkipPatternInfo
- plan_box.rs: added #[cfg(test)] for PlanKind
**Verification**:
- 0 unused import warnings (was 20+)
- All 69 normalized_shadow tests pass
- Clean build with --release
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Phase 143-loopvocab: Loop Vocabulary Extension
Status: ✅ P0 Complete Date: 2025-12-19
目的(Why)
Phase 131で loop(true) break を実装したが、Phase 143では「条件付きbreak」パターンを吸収する。
Phase 143-loopvocab では、loop(true) { if(cond_pure) break } を Normalized shadow lowering で段階的に拡張するための語彙追加を行う。
パターン進化
Phase 131:
loop(true) { break } // 無条件break
Phase 143 P0:
loop(true) { if(cond_pure) break } // 条件付きbreak
P0: Minimal Vocabulary Extension (COMPLETE ✅)
Summary
loop(true) { if(cond_pure) break } パターンを Normalized shadow で実装完了。
Scope (P0 - Conservative)
Supported:
- Loop condition:
trueliteral only - Loop body: Single
ifstatement only - If then branch:
breakonly (no continue, no nested if) - Condition expression: Pure only (variables, literals, arith, compare)
Out of Scope (Ok(None) fallback):
- Loop condition not
true:loop(x > 0) { ... } - Multiple statements in loop body
- If/else statements (no else branch)
- Impure conditions:
loop(true) { if(s.length() > 0) break } - Nested structures within if body
Design: 6-Function JoinModule
main(env) → loop_step(env) → loop_cond_check(env)
[condition lowering + Jump]
→ k_exit(env) on break [Ret]
→ loop_step(env) on continue [Call]
k_then(unused in P0)
k_else(unused in P0)
Jump Semantics:
Jump { cont: k_exit, args: [...], cond: Some(vid) }- If
vidis true: jump to k_exit (break) - If
vidis false: fall through to Call(loop_step)
Implementation Steps (Complete ✅)
Step 1-2: Pattern Detection + Routing
- Extract loop(true) + if + break pattern
- Validate loop condition = Bool(true) literal
- Validate if body = single Break statement
- Add module declaration and routing in builder.rs
Step 3: Condition Lowering Integration
- Validate condition with NormalizedExprLowererBox
- Use ExprLoweringScope::PureOnly
- Return Ok(None) for impure conditions (graceful fallback)
Step 4: Branch Instruction Emission
- Allocate 6 JoinFuncIds (stable IDs 0-5)
- Build env parameter passing (deterministic BTreeMap)
- Emit Jump instruction in loop_cond_check
- Create Call fallthrough for loop_step
Step 5: Exit Action Discrimination
- Complete k_exit() function
- Build exit values from env_layout.writes
- Extract final ValueIds from environment
Step 6: ExitMeta Construction
- Create ExitMeta::multiple() from exit values
- Use JoinFragmentMeta::carrier_only()
- Return Ok(Some((module, meta)))
Step 7: Routing Integration
- Already integrated in builder.rs (Step 1)
- Phase 131 (simpler) → Phase 143 (conditional) priority
Step 8: Fixtures + Smoke Tests
Fixture: apps/tests/phase143_loop_true_if_break_min.hako
Tests:
tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_vm.shtools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_llvm_exe.sh
Expected exit code: 7
Step 9: Documentation (THIS FILE)
Acceptance Criteria (All Met ✅)
- Pattern detection correctly identifies
loop(true) { if(cond) break } - Condition lowering validates pure scope
- Out-of-scope patterns always return
Ok(None) - JoinModule built with 6 functions
- Jump instruction with conditional emission
- k_exit returns exit values
- ExitMeta constructed correctly
- Fixture executes correctly (VM)
- LLVM EXE parity test ready
- No regressions in Phase 131-142
- cargo check passes (no errors)
- All commits created
Verification Results
Compilation: cargo check -p nyash-rust --lib ✅ (0 errors)
Commits:
f55f6cc65- Step 3: Condition lowering integration434c891a1- Step 4: Branch instruction emissiond1d59dc82- Steps 5-6: Exit handling + ExitMetae28d59101- Step 8: Fixtures + Smoke tests
P1: Continue Vocabulary (COMPLETE ✅)
Summary
loop(true) { if(cond_pure) continue } を語彙として受理し、Normalized shadow 経路で「コンパイル/実行が落ちない」ことを固定する。
Important note (P1 scope)
P1 の fixture は 意図的に non-terminating(break/else/state update を含まない)である。
- 条件式は
ExprLoweringScope::PureOnlyで lowering できることを検証する(スコープ境界の固定)。 - ただし P1 では continue を「条件分岐で skip する」語彙までに留め、bridge 側の Jump(early-return) と混線させないため、
実際の JoinIR emission は
loop_stepへの tail call を基本にする。
Fixture / smokes
- Fixture:
apps/tests/phase143_loop_true_if_continue_min.hako - VM smoke (timeout contract):
tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_continue_vm.sh- Contract:
HAKO_VM_MAX_STEPS=0+timeout ${SMOKES_P143_CONTINUE_TIMEOUT_SECS:-1}→ exit code124
- LLVM EXE smoke (timeout contract):
tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_continue_llvm_exe.sh- Contract:
RUN_TIMEOUT_SECS=${SMOKES_P143_CONTINUE_TIMEOUT_SECS:-1}→ exit code124
Design Principles
Out-of-Scope Handling
All out-of-scope patterns return Ok(None) for graceful fallback to legacy routing.
Fail-Fast Policy
- Out-of-scope: Always
Ok(None)(no change to existing behavior) - In-scope errors: Return
Err(msg)(internal errors, strict mode freeze)
Files
Core Implementation
- src/mir/control_tree/normalized_shadow/loop_true_if_break_continue.rs (~400 lines)
Fixtures + Tests
- apps/tests/phase143_loop_true_if_break_min.hako
- tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_vm.sh
- tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_llvm_exe.sh
Related Documentation
Commits
f55f6cc65- feat(phase143): Step 3 - Condition lowering integration434c891a1- feat(phase143): Step 4 - Branch instruction emissiond1d59dc82- feat(phase143): Steps 5-6 - Exit handling + ExitMetae28d59101- feat(phase143): Step 8 - Fixtures + Smoke tests