ReviewOS

home-lang/home

TypeScript checker panics compiling zig-js representative benchmark

#834
Closed glennmichael123 opened this 8 days ago ·
8 days ago

Consumer: zig-utils/zig-js#1021 (blocking zig-utils/zig-js#1019)

Reproducer

From the clean zig-js main checkout at 388a01f67cf04e087dc448f75787bc820b896d49:

HOME_RUN_LOCK=/Users/glennmichaeltorregosa/.cache/home-run.lock \
HOME_RUN_LOCK_WAIT=1800 \
HOME_RUN_MAX_MB=512 \
HOME_RUN_LABEL=zig-js-1019-home-repro \
/Users/glennmichaeltorregosa/Documents/Projects/home/scripts/run-bounded.pl 300 \
/Users/glennmichaeltorregosa/Code/Home/lang/zig-out/bin/home-tool \
run tools/representative-benchmark.ts --self-test

Actual

The checker aborts before the module self-test runs:

panic: start index 7 is larger than end index 6
packages/ts_checker/src/check.zig:114801 in checkExpression
packages/ts_checker/src/check.zig:130535 in checkMethodThisCompatibility
packages/ts_checker/src/check.zig:155332 in checkTemplateLiteralExpression

Exit code is 134. The bounded supervisor reports a 138 MB peak tree footprint and 37% host low-water, so this is not resource pressure.

The authoritative zig-js command zig build benchmark-comparison-test --summary all fails at the same compile stage. Running its imports separately isolates the first failure to tools/representative-benchmark.ts; the preceding benchmark-comparison, benchmark-publication, and representative-matrix validators pass.

Provenance

  • zig-js source file SHA-256: c5ab6c701a02132ad26e0991f3135254b1bedce6fa801c093d77f524dc428a0e
  • that file last changed in zig-js 224cd4846b3af783993dd6fb30118f92f6517074 on 2026-09-29
  • home-tool SHA-256: b9e326a4585abf491db59d19a3ec16a10c7bd15346f6fe27f22f3df24e56f023
  • home-tool mtime: 2026-10-01 20:22:55 +0800

The Home checkout currently has unrelated uncommitted checker instrumentation, so I did not rebuild or alter it. No consumer-side syntax workaround has been added.

Expected

The module compiles and runs its self-test, or reports a normal TypeScript diagnostic rather than aborting the process.

8 days ago

Fresh read-only diagnosis from the zig-js consumer lane:

  • The pinned home-tool still reproduces the abort on tools/representative-benchmark.ts --self-test: exit 134, start index 7 is larger than end index 6, 138 MB bounded peak.
  • The stale index is this_diag_start in checkExpression. It records self.diagnostics.items.len, calls checkMethodThisCompatibility, then slices self.diagnostics.items[this_diag_start..].
  • checkMethodThisCompatibility recursively checks the member receiver via checkExpression(m.object). That nested check can legitimately remove an earlier diagnostic, so the diagnostics list is not append-only and its length can fall below this_diag_start.
  • The semantic operation needed by the caller is already available: after the nested check, query diagnosticExists(node, TsCodes.this_context_not_assignable) instead of inferring TS2684 from an appended suffix. A bounds clamp would hide the stale-index bug and can miss a newly retained TS2684; the direct lookup is the logical fix.

I did not edit the Home checkout because the active Home task is currently compiling and using the same checker file. The consumer-side workaround remains absent.

8 days ago

Current-main follow-up (read-only, no Home edits): the freshly built zig-out/bin/home-tsc from Home d67ece512be2394cf64ff8d61b7592391e53586f (SHA-256 ee4938a9dc83fed1c787d9df4960aee324739a2fda97549cb6bd09786f9a0fef, built 2026-10-02 19:23 +0800) still exits 139 when checking zig-js tools/representative-benchmark.ts. A reduced module containing the selectFamilies / template-literal .join() shape exits 0, so the fault requires the larger module diagnostic history or import graph; it is not merely that expression in isolation. The original home-tool reproduction and stale-index analysis remain the strongest stack evidence. I removed the temporary reducer and left both repositories clean.

8 days ago

Fixed on main by daca8fc (fix(ts): avoid stale diagnostic slices (#834)).

The member-call path no longer slices diagnostics from a saved length after recursive receiver checking. It queries the call node directly for TS2684, so legitimate diagnostic removal cannot make the index stale; no bounds clamp or diagnostic suppression workaround was added.

Authoritative before/after:

  • prior home-tsc --ignoreConfig --noEmit tools/representative-benchmark.ts: exit 139
  • rebuilt home-tsc: completes with ordinary TypeScript diagnostics, peak 276 MB
  • rebuilt original reproducer home-tool run tools/representative-benchmark.ts --self-test: exit 0, OK representative benchmark self-test, peak 55 MB

Regression gates, all serial under HOME_RUN_MAX_MB=3840:

  • focused checker regression: pass, one TS2684 and zero dependent TS2322, peak 1,758 MB
  • complete ts_checker: pass, peak 2,300 MB
  • normal conformance: 16/16 smoke, 86/86 category, 586/586 baseline-aware, peak 2,057 MB
  • Zig formatting and diff checks: pass
  • edited runtime guide: Pickier pass

Closing as reproduced, repaired, and verified end to end.

Sign in to comment on this issue.