Skip to content

fix(loader): transitive helpers for selective use — greens the Bun-ESM corpus (follow-up to #772) - #774

Merged
hyperpolymath merged 2 commits into
mainfrom
arena/01a1022a-affinescript
Oct 3, 2026
Merged

hyperpolymath merged 2 commits into
mainfrom
arena/01a1022a-affinescript

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Follow-up to #772 (merged as 8941c87, plus CodeRabbit's doc-comment pass #773).

Why main is still red

With #772's masking fixes in, build now reaches step 15 Run codegen Bun-ESM tests and stops on one harness:

1 of 32 Bun-ESM harness(es) failed
  - dom_startup_error.harness.mjs
ReferenceError: h is not defined

Root cause is in the compiler, not the test: tests/codegen-deno/dom_startup_error.affine says
use Dom::{VNode, div, h1, p, text}, and stdlib/Dom.affine's div/h1/p are one-line wrappers
around Dom's own pub fn h(...). Module_loader.flatten_imports inlined exactly the named decls and
left h out of the flattened program, so the emitted module called an undefined h.
ImportGlob/ImportSimple already inline every public decl for this reason — ImportList was the
odd one out. Any consumer writing use M::{x} where x delegates internally hits this.

What this does

  • lib/module_loader.ml — close over the named decls' free variables to a fixpoint, pulling the
    module's own value decls (private helpers included) in dependency order. Aliases keep their
    behaviour: the closure runs on original names, renaming is applied afterwards.
  • lib/ast.ml, lib/codegen.ml — move find_free_vars into ast.ml (re-exported from codegen.ml
    for existing call sites) so the loader can share the walker instead of adding a fourth private
    copy. Codegen depends on Module_loader, so the loader could not reach the copy where it lived.

Verification

The OCaml build is the verification (no local toolchain here); the CI run on this PR is the check.
Once step 15 passes, steps 16–18 (native Bun-ESM, face transformers, extension.ts) execute for the
first time in this pipeline instead of being skipped behind it.

Before merge

The temporary [diag] probe (tools/ci/diag-probe.sh, .github/workflows/zz-probe-*.yml, the
ci.yml [diag] step) is still present — it came in with #772 and is what makes this failure visible
without Actions log access. It is deleted in a follow-up commit on this branch once the run is green,
so what merges carries no diagnostics scaffolding.

tests/codegen-deno/dom_startup_error.affine says `use Dom::{VNode, div, h1,
p, text}`. Module_loader.flatten_imports inlined exactly those decls — but
stdlib/Dom.affine's div/h1/p are one-line wrappers around Dom's own
`pub fn h(...)`. `h` was never named by the import list, so it was left out of
the flattened program and the emitted module called an undefined `h`:
`ReferenceError: h is not defined`. ImportGlob/ImportSimple already inline
every public decl for this reason; ImportList was the odd one out.

Close over the named decls' free variables until a fixpoint, pulling in the
module's own value decls (private helpers included — a public wrapper may
delegate to one) in dependency order. Aliased items keep their behaviour:
the closure runs on the original names, then renaming is applied.

To share the walker instead of adding a fourth private copy (codegen.ml had
one; borrow.ml has another), move find_free_vars into ast.ml and re-export it
from codegen.ml for the existing call sites. (Codegen depends on
Module_loader, so the loader could not reach the copy where it lived.)

Verified locally: the emitted-module call pattern is what the harness died
on; the fix makes `h` part of the flattened program. Full verification needs
the OCaml build in CI.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 36 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 15519794-1e1d-435a-946e-d6b58facb275
📥 Commits

Reviewing files that changed from the base of the PR and between 45c07de and 4d8d1f9.

📒 Files selected for processing (3)
  • lib/ast.ml
  • lib/codegen.ml
  • lib/module_loader.ml
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…`use`

Next link in the same chain as the previous commit. With `h` inlined, the
emitted module moved on to `ReferenceError: VText is not defined`:
stdlib/Dom.affine's `text(content)` returns `VText(content)`, i.e. a
constructor of Dom's own `pub enum VNode`, and flatten_imports carries no
type decls at all — the #138 note says imported TYPE decls were deliberately
dropped because re-emitting the prelude's Option/Result constructors produced
duplicate `const Some` declarations under node.

So the closure now also carries an enum when a constructor of it is
referenced, with the #138 hazard closed rather than ignored: Some/None/Ok/Err
are never carried, because every non-wasm backend preamble already provides
them. That narrows type-carrying to user enums a preamble cannot supply,
which is exactly what a consumer hits with `use Dom::{div}`.

Also let a locally-declared type name suppress a same-named import, the same
rule local functions and constants already follow.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
@hyperpolymath
hyperpolymath force-pushed the arena/01a1022a-affinescript branch from 052a5ab to 4d8d1f9 Compare October 3, 2026 15:19
@sonarqubecloud

sonarqubecloud Bot commented Oct 3, 2026

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath merged commit a9defd2 into main Oct 3, 2026
20 checks passed
@hyperpolymath
hyperpolymath deleted the arena/01a1022a-affinescript branch October 3, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant