Tracking the codegen issues surfaced while fixing #138 and making CI standalone (PRs #602, #603, #604, #606). None block CI today; recording so they aren't lost.
1. JS / C (and other flat) backends duplicate Option/Result constructors
Same class as the Deno bug fixed in #606, but for the other preamble-bearing backends. A program that declares type Option/type Result (e.g. stdlib/prelude.affine) emits Some/None/Ok/Err twice — once in the runtime preamble, once from the TopType lowering.
Repro:
affinescript compile -o /tmp/prelude.js stdlib/prelude.affine
grep -c 'Some' /tmp/prelude.js # 2 (preamble + declaration)
# same for the C backend (.c)
Not caught by CI: only the Deno output is executed under node (tools/run_codegen_deno_tests.sh); the JS/C outputs are generated but not run. Fix mirrors #606: skip preamble-provided constructors in each backend's enum lowering (or dedup centrally).
2. WASM: tuple patterns unsupported — blocks stdlib/option.affine / result.affine
affinescript compile -o /tmp/o.wasm stdlib/option.affine
# => Code generation error: (Codegen.UnsupportedFeature
# "Only variable and wildcard patterns supported in tuple patterns")
Pre-existing; independent of #138 (which only fixed the imported-constructor UnboundVariable). These stdlib files now get past the #138 error and reach this gap.
3. Mixed-representation match of a zero-arg variant returns the wrong value
A zero-arg variant (None) is a raw i32 tag while a constructor-with-args (Some(x)) is a heap pointer; matching the former against a constructor arm misreads it. Reproduces with a purely local enum (so unrelated to cross-module linking):
type Opt = Som(Int) | Non
fn unwrap_or(o: Opt, d: Int) -> Int { match o { Som(v) => v, Non => d } }
// unwrap_or(Non, 99) returns 0, not 99 (verified via node on the wasm output)
Related / already documented
Tracking the codegen issues surfaced while fixing #138 and making CI standalone (PRs #602, #603, #604, #606). None block CI today; recording so they aren't lost.
1. JS / C (and other flat) backends duplicate Option/Result constructors
Same class as the Deno bug fixed in #606, but for the other preamble-bearing backends. A program that declares
type Option/type Result(e.g.stdlib/prelude.affine) emitsSome/None/Ok/Errtwice — once in the runtime preamble, once from theTopTypelowering.Repro:
Not caught by CI: only the Deno output is executed under node (
tools/run_codegen_deno_tests.sh); the JS/C outputs are generated but not run. Fix mirrors #606: skip preamble-provided constructors in each backend's enum lowering (or dedup centrally).2. WASM: tuple patterns unsupported — blocks
stdlib/option.affine/result.affinePre-existing; independent of #138 (which only fixed the imported-constructor
UnboundVariable). These stdlib files now get past the #138 error and reach this gap.3. Mixed-representation
matchof a zero-arg variant returns the wrong valueA zero-arg variant (
None) is a raw i32 tag while a constructor-with-args (Some(x)) is a heap pointer; matching the former against a constructor arm misreads it. Reproduces with a purely local enum (so unrelated to cross-module linking):Related / already documented
docs/history/MODULE-SYSTEM-PROGRESS.md. Re-enablingflatten_importstype-carrying (reverted in ci: fix standalone-CI fallout — SHA-pin actions, de-trip secret scanner #604) needs item 1 fixed first (per-backend constructor dedup).