ReviewOS

also looking at this

home-lang/home

fix(types): define the index variable of an enumerating for loop

#935
Open mkantautas wants to merge fix/types-for-index-variable into main
2 files +57 -0
8 days ago

Problem

home check rejects the index variable of an enumerating for loop:

fn main() {
  for i, x in [10, 20] {
    let next = i + 1
    print(next)
  }
}

home check reports error: Undefined variable at i, although home run prints 1 and 2. For arrays, strings and ints the interpreter binds the index (for_stmt.index) to the position, an int, before the item; the type checker's loop scope only defines the item variable.

Fix

For array, string and integer iterables, the type checker defines the index as an int, before the item, like the interpreter. Other iterables keep their current behaviour: a map binds its value there and the checker cannot type that yet (a map literal infers as void), and a range such as 0..3 also infers as void, so its index is still reported as undefined.

Tests

New checker defines the index variable of an enumerating for loop in packages/types/tests/control_flow_checker_test.zig checks the program above, that a map's first name is not typed as an int (value + 1 on a bool value still fails, also through ?Map<string, bool>), and that for x, x in ["hello"] keeps the item binding. The first case fails on main; the map cases fail if the index is typed as an int for other iterables, and the last fails if the index is defined after the item. It runs the checker on an arena because the checker does not free for-loop scopes yet (a plain for x in ... leaks under the testing allocator on main as well). zig build test -Denable_jsc=false -Dfilter=types on macOS passes. On Linux this test step does not compile on main or on this branch, because the parser's module resolver calls libc access and the test target does not link libc.

GitHub Actions does not run on this repo at the moment, so I ran the full suite on Linux x86_64 with the pinned Zig 0.17.0-dev.2163, on main (854d00f) and on this branch: zig build test --summary all records 9226 passes, 3 failures and 8 skips out of 9237 on both (the same 3 failing tests), 23 failed build steps on both, and the diagnostic snapshot harness output is identical. With the built home, home check on the program above reports the undefined variable on main and passes on this branch; this debug build then prints DebugAllocator reports for the leaked loop scope, as home check already does on main for a plain for x in loop.

2 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.