Skip to content

Fix interpreter and glue generator for polymorphic types#9248

Open
lukewilliamboswell wants to merge 5 commits intomainfrom
more-glue-fixes
Open

Fix interpreter and glue generator for polymorphic types#9248
lukewilliamboswell wants to merge 5 commits intomainfrom
more-glue-fixes

Conversation

@lukewilliamboswell
Copy link
Copy Markdown
Collaborator

@lukewilliamboswell lukewilliamboswell commented Mar 10, 2026

Summary

  • Interpreter: Fix module resolution collisions between platform and app imports; use correct type var for hosted method return types
  • Interpreter: Fix ZST variant layout for concrete types in polymorphic tag unions (e.g., List.get : List(a) -> Result a b where a was rigid at layout time)
  • Interpreter: Fix rigid type substitution to also check rigid_name_subst (from platform for clause), extend variant layout correction to box_of_zst, and handle ZST/box_of_zst payloads in evalBoxIntrinsic
  • Interpreter: Fix silent OOM in record extension chain flattening
  • Glue generator: Separate per-target layout computation from type table — types are now stored without size/alignment, and layouts are computed per target via computeLayoutsForTarget
  • Glue generator: Parse platform targets section to build target list, deduplicate by pointer width
  • Glue generator: Pass per-target layouts to Roc glue specs (ZigGlue.roc, RustGlue.roc) for correct cross-platform struct field ordering and comptime assertions
  • Glue generator: New platform types TargetLayout and TypeLayout; simplified RecordField, RecordRepr, TagUnionRepr, TagVariant (removed inline size/alignment fields)

Test plan

  • zig build minici passes (all 3107 tests, CLI tests, lints, snapshots)

🤖 Generated with Claude Code

lukewilliamboswell and others added 5 commits March 11, 2026 13:49
…ue generator improvements

Interpreter fixes:
- evalLookupExternal: prefer module-local resolveImports over shared
  import_envs map, which could have collisions when platform and app
  both use the same import index for different modules (e.g. Keys vs Host)
- dot_access_collect_args: use the dot-access expression's type var
  (dac.expr_idx) for hosted method call return types instead of the
  lambda expression type, which produced a closure layout and crashed
  the ? operator's match

Glue generator fixes:
- Make getSizeAlignForRepr target-aware: box/str/list sizes now use
  target pointer width instead of hardcoded 64-bit values
- Compute alt (32-bit vs 64-bit) record layouts and emit comptime
  conditional extern structs when field ordering diverges between targets
- Deduplicate anonymous record types by structural signature so
  identical records (e.g. { x: F32, y: F32 }) share a single definition
- Fix memory leaks where record reconstruction dropped alt_fields

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a tag union is compiled in a polymorphic context (e.g., List.get :
List(a) -> Result a b), the variant payload layout may be computed as ZST
because the type variable was rigid/flex at layout-computation time. At
runtime, when we have a concrete structure or alias type, we now compute
the correct layout instead of using the stale ZST layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These trace blocks were leftover debugging aids added during development.
One was specific to a single identifier ("pack"). Remove all 4 blocks
since they add noise without lasting diagnostic value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Return oomUnknown("record") on allocation failure when collecting fields
from record extension chains, instead of silently dropping fields with
catch {}. Silent failures could produce incorrect struct layouts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…reter rigid substitution

Refactor glue generator to store types without layout info (size/alignment/field_order)
and compute layouts separately per target via computeLayoutsForTarget. Parse platform
targets section to build target list, deduplicate by pointer width, and pass per-target
layouts to Roc glue specs for correct cross-platform struct field ordering and assertions.

Fix interpreter rigid type substitution to also check rigid_name_subst (from platform
`for` clause), extend variant layout correction from ZST to box_of_zst, and handle
ZST/box_of_zst payloads in evalBoxIntrinsic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lukewilliamboswell lukewilliamboswell marked this pull request as ready for review March 11, 2026 02:50
@github-actions
Copy link
Copy Markdown

Thank you for your contribution! Sometimes PRs end up staying open for a long time without activity, which can make the list of open PRs get long and time-consuming to review. To keep things manageable for reviewers, this bot automatically closes PRs that haven’t had activity in 60 days. This PR hasn’t had activity in 30 days, so it will be automatically closed if there is no more activity in the next 30 days. Keep in mind that PRs marked Closed are not deleted, so no matter what, the PR will still be right here in the repo. You can always access it and reopen it anytime you like!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant