GeezerVison is showing github.com — fix(codegen): register struct_layouts for record-type aliases by hyperpolymath · Pull Request #388 · hyperpolymath/affinescript
Conversation
Summary
Record-type aliases (type X = { ... }) silently miscompiled when used as function parameters or return types: every field access on such a value resolved to offset 0.
Root cause
type X = { a: T, b: U } parses to TopType { td_body = TyAlias (TyRecord (rfs, _)) } (parser.mly:431). The TopType branch in gen_decl (codegen.ml:2439) handled the analogous TyStruct case by registering a 4-byte-stride layout in ctx.struct_layouts, but the TyAlias branch caught everything with TyAlias _ -> Ok ctx. With no layout registered, every .field_N access fell back to offset 0 — a silent runtime miscompile, not a validation error or compile failure.
The fix adds a TyAlias (TyRecord (rfs, _)) branch immediately before the catch-all, mirroring the TyStruct case but unpacking the alias.
Regression coverage
Two new tests in the E2E WASM group:
record-alias registers struct_layouts — parses type State = { health: Int, score: Int };, calls gen_decl directly, asserts (\"State\", [(\"health\", 0); (\"score\", 4)]) appears in ctx.struct_layouts. Verified to fail on main without the fix (stash-revert reproduces expected Some [...] but got None); passes with it.
non-record alias leaves struct_layouts alone — guards against accidental over-broadening: type Plain = Int must still hit the catch-all and add no layout entry.
Verification
```
$ dune build && dune runtest
…
Test Successful in 0.082s. 329 tests run.
```
Was 327, now 329 with the two new tests. Full suite green.
Discovered during
Field trial taking airborne-submarine-squadron (a 29-field state record stepped at 60 fps over WASM) from "compiles" to "runs to conclusion". The product currently ships via the linear backend with flat-record boundaries; this fix removes the flatness constraint at the per-record-alias level. WasmGC-backend record/tuple layout has a separate, independent defect — out of scope here.
Test plan
-
dune build clean
-
dune runtest → 329/329 green
- New regression test verified to fail on main without the fix
- Catch-all
TyAlias _ still reached for non-record aliases
- CI green
🤖 Generated with Claude Code
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
`type X = { a: T, b: U }` parses as `TopType { td_body = TyAlias
(TyRecord (rfs, _)) }`. The TopType branch in `gen_decl` handled
TyStruct (registering a 4-byte-stride field layout in
`ctx.struct_layouts`) but the TyAlias branch caught everything with
`TyAlias _ -> Ok ctx`, so record aliases never registered.
The downstream symptom is silent: every parameter or return of such
an alias resolves `.field_N` to offset 0 because the layout lookup
returns None. The miscompile only surfaces at runtime via wrong
field values, not a Wasm validation error or a compile failure.
Fix mirrors the existing TyStruct branch but unpacks the alias.
Regression coverage:
- `record-alias registers struct_layouts` — parses
`type State = { health: Int, score: Int };`, calls `gen_decl`
directly, asserts `("State", [("health", 0); ("score", 4)])`
appears in `ctx.struct_layouts`. This test fails on main without
the fix (verified by stash-revert) with
`expected Some [...] but got None`.
- `non-record alias leaves struct_layouts alone` — guards against
accidental over-broadening: `type Plain = Int` must still hit the
catch-all and add no layout entry.
327 → 329 tests; full suite green.
Refs affinescript ASBSQ trial 2026-05-19
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
🔍 Hypatia Security Scan
Findings: 43 issues detected
| Severity |
Count |
| 🔴 Critical |
15 |
| 🟠 High |
16 |
| 🟡 Medium |
12 |
⚠️ Action Required: Critical security issues found!
View findings
[
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Action actions/checkout@v6 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action denoland/setup-deno@v2 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/packages/affinescript-cli/mod.d.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/packages/affine-js/types.d.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/lib/runner.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/lib/discover.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/lib/compile.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/example/smoke_driver.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
}
]
Powered by Hypatia Neurosymbolic CI/CD Intelligence
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|