Skip to content

fix(hy-emit): hoist exclusive range upper bound into outer temp (#730) - #1717

Open
ubelai wants to merge 1 commit into
limitlessprojects:mainfrom
ubelai:fix/730-hoist-exclusive-range-bound
Open

ubelai wants to merge 1 commit into
limitlessprojects:mainfrom
ubelai:fix/730-hoist-exclusive-range-bound

Conversation

@ubelai

@ubelai ubelai commented Oct 25, 2026

Copy link
Copy Markdown

Summary

Fixes #730

While inclusive range loops (for v in lo..=hi) already hoist both bounds (hyLo and hyHi) before declaring the loop variable v, exclusive range loops (for v in lo..hi) previously emitted:

for v := <lo>; v < <hi>; v++ {

This caused two bugs:

  1. Outer-variable shadowing (for n in 0..n): In Go's for header scoping rules, n := 0 in the init statement is in scope for the condition n < n, so for n in 0..n lowered to for n := 0; n < n; n++ (0 iterations instead of reading the outer n).
  2. Repeated upper-bound evaluation: Side-effecting or expensive hi expressions (for i in 0..expensive()) were re-evaluated on every iteration instead of once at loop entry.

Changes

  1. compiler/crates/hy-emit/src/stmt.rs:
    • Hoist the exclusive range upper bound hi_t into a fresh hyHi temporary (let hi_once = self.next_temp("hyHi"); self.push(&format!("{} := {}", hi_once, hi_t));) before emitting for {} := {}; {} < {}; {}++ {{.
  2. compiler/crates/hy-emit/src/rangebind.rs:
    • Because both inclusive and exclusive ForKind::Range loops now evaluate lo and hi in the enclosing scope before binding var, stmt_reads uniformly treats expr_reads(lo, target) || expr_reads(hi, target) as reading the outer target even when var == target.
  3. Tests (compiler/crates/hy-emit/src/tests.rs & compiler/crates/hy-emit/tests/rangebind_match_soundness.rs):
    • Added exclusive_range_hoists_upper_bound_once_in_outer_scope verifying for n in 0..n lowers to hyHi0 := n followed by for n := 0; n < hyHi0; n++.
    • Updated rangebind_match_soundness.rs and golden emission assertions for the hoisted hyHi binding.

Verification

  • cargo test -p hy-emit -p hy-check: 977 passed; 0 failed.

@ubelai
ubelai force-pushed the fix/730-hoist-exclusive-range-bound branch from 8dbb659 to 912cfe6 Compare November 9, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:conflict Shepherd: merge conflicts vs main bot:land-candidate Shepherd: fresh, gate-clean, verifiable (set from classify()) bot:stale-base Shepherd: behind main beyond threshold

Projects

None yet

1 participant