Files
hakorune/docs/development/current/main/phases/phase-100

Phase 100: Pinned ReadOnly Captures設計メモ

目的

JoinIR lowering のスコープ解決(ConditionEnv → LoopBodyLocalEnv → CapturedEnv)の前提を崩さずに、 「ループ外で定義した local動的式でも可」をループ内で receiver として参照できるようにする。

例(問題の形):

local s = "a" + "b"   // 条件式とは無関係
loop(i < n) {
  local ch = s.substring(i, i + 1)  // receiver 解決が必要
}

方針SSOT

  • “Pinned local” は 新しい Pattern ではなく、ループに入ってくる readonly 入力として扱う。
  • SSOT は増やさず CapturedEnv に統合し、CapturedKind で区別する:
    • Explicit: 従来の capture
    • Pinned: ループ内参照のために必要な readonly local

FailFast 契約

  • Pinned は loop body 内で 再代入されないassignment target に現れたら拒否)。
  • loop entry 時点で host 側 ValueId が存在する(variable_map に無い場合は拒否)。
  • 初期化が loop より後にある等、支配関係が曖昧な場合は拒否(理由付き)。
  • init 式の副作用有無は問わない評価はホスト側で1回、Pinned は値を渡すだけ)。

Loop Canonicalizer との関係(混ぜない)

  • Phase 100 は「ループ外の値が loop 内で見えない」問題capture/wiringを解く。
  • Loop Canonicalizer は「ループ内の不変式を外に出す」AST 変換であり、別ユースケース。