Pattern2 (Loop with Break) - JoinIR
Scope / Criteria
loop(...) { ... break ... }(break present, no continue/return)- break condition is normalized to "break when is true"
- loop variable comes from header condition or loop(true) counter extraction
- loop(true):
i = i + 1+substring(i, i + 1)ori = j + Kwithj = indexOf(..., i)+substring(i, ...)
- loop(true):
LoopBodyLocal promotion
- SSOT entry:
pattern2::api::try_promote - Supported: A-3 Trim / A-4 DigitPos (promote LoopBodyLocal to carrier)
- ConditionOnly carriers are recalculated per iteration (no host binding)
Trim (seg) minimal shape
- Example shape (A-3):
local seg = s.substring(i, i + 1) - Break guard:
if seg == " " || seg == "\\t" { break } - seg is read-only (no reassignment in the loop body)
Derived slot minimal shape (seg)
- Example shape (Derived):
local seg = ""thenif cond { seg = expr1 } else { seg = expr2 } - Break guard:
if seg == "" { break }(seg used in break condition) - seg is recomputed per-iteration (Select), no promotion
- Contract SSOT:
pattern2/contracts/derived_slot.rs
Carrier binding rules (Pattern2)
CarrierInit::FromHost-> host binding requiredCarrierInit::BoolConst(_)/CarrierInit::LoopLocalZero-> host binding is skipped- ConditionOnly carriers must not use
FromHost
Out of scope
- multiple breaks / continue / return in the loop body
- reassigned LoopBodyLocal outside the derived-slot shape
- break conditions with unsupported AST shapes
- non-substring init for Trim promotion (e.g.,
seg = other_call())
Fail-Fast policy
PromoteDecision::Freeze-> Err (missing implementation or contract violation)- JoinIR lowering/merge contract violations -> Err
Ok(None) meaning
- not Pattern2 (extractor returns None)
- promotion NotApplicable (continue Pattern2 without promotion)