Skip to content

Fix #559: nested type aliases through Array<...> compile and run#666

Merged
aallan merged 1 commit into
mainfrom
fix-559-nested-aliases
May 13, 2026
Merged

Fix #559: nested type aliases through Array<...> compile and run#666
aallan merged 1 commit into
mainfrom
fix-559-nested-aliases

Conversation

@aallan

@aallan aallan commented May 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • Nested type aliases through Array<...> (e.g. type Row = Array<Int>; type Grid = Array<Row>;) now compile and run correctly when indexed through both layers.
  • Pre-fix vera/wasm/inference.py::_alias_array_element returned NamedType("Row") rather than the canonical NamedType("Array", (Int,)) for @Grid.0's element type. Downstream consumers either fell through (chained-indexing check inner_te.name == "Array" fails on "Row") or emitted load-as-i32 + i64.extend_i32_u against a heap pointer to an i32_pair — producing type mismatch: expected a type but nothing on stack at WASM validation, or the misleading unknown func: $caller symptom when the bug surfaced on a private helper.
  • Post-fix the helper canonicalises the extracted element through the existing _canonical_named_type walker (the Cross-cutting: centralise canonical Vera-type-name resolution to close the #602 bug class structurally #630 canonicalisation seam). Fallback preserves the pre-fix contract for non-NamedType element types.
  • Two new regression tests in tests/test_codegen.py::TestCompoundArrays (test_nested_alias_array_length_559, test_nested_alias_2d_index_559) pin both the single-level array_length shape and the chained-indexing shape from the issue body's Conway's-Life context.

Why this shape

The codebase already had the right primitive — _canonical_named_type was introduced in #630 to consolidate alias-walking logic. _alias_array_element slipped through that consolidation: it returned the element type but didn't re-canonicalise. The fix is one call to the existing walker plus a None fallback so non-NamedType elements (e.g. FnType) don't regress the direct Array<T> path. Minimal blast radius, no new abstraction.

Test plan

  • pytest tests/ -q → 3,811 passed, 14 skipped (pre-bump count; 3,813 post-bump)
  • mypy vera/ → clean
  • vera run on the issue's reproducer (array_length(@Grid.0[0])) → 1 (was: type-mismatch trap)
  • vera run on the Conway's-Life helper pattern (@Grid.0[@Int.1][@Int.0] inside a private fn) → returns expected value (was: skipped, misleading unknown func: $caller)
  • Doc sweep across SKILL/CLAUDE/AGENTS/README/spec/docs/examples/tests → no stale workarounds, no limitation claims pointing at Nested type aliases (Array<Array<Foo>>) cause silent codegen skip; WAT error misleadingly points at callers #559

Closes #559

Pre-fix `vera/wasm/inference.py::_alias_array_element` extracted
the array element type but did not canonicalise it.  For
`type Row = Array<Int>; type Grid = Array<Row>;`, indexing
`@Grid.0` walked `Grid -> Array<Row>` and returned
`NamedType("Row")` rather than the canonical
`NamedType("Array", (Int,))`.

Two downstream consequences:

1. Chained-indexing in `_infer_index_element_type_expr` checks
   `inner_te.name == "Array"` — on `"Row"` this falls through to
   `return None`, so `@Grid.0[i][j]` silently dropped the
   enclosing function via `[E602]`.

2. The IndexExpr WASM-emit path looked up the element WASM type
   by name; for the opaque alias `Row` it returned scalar shape
   and emitted a load-as-i32 + `i64.extend_i32_u` against what is
   actually a heap pointer to an i32_pair.  WASM validation
   rejected the module with `type mismatch: expected a type but
   nothing on stack`.

When the bug surfaced on a private helper (e.g. the
`cell_alive(@grid, @int, @int -> @int)` from the Conway's Life
program in the issue body), the failure mode was the misleading
`unknown func: $caller` symptom because the helper had been
dropped via [E602] earlier in the pipeline and the call site
referenced a non-existent symbol.

Post-fix the helper runs the extracted element through the
existing `_canonical_named_type` walker (the #630
canonicalisation seam, which iteratively peels `RefinementType`
layers and follows alias chains).  A `Row` element resolves to
`Array<Int>`, the chained-indexing branch matches `"Array"`, and
downstream size lookups see the real i32_pair shape.

Fallback: `_canonical_named_type` returns `None` when the walk
terminates at a non-NamedType (e.g. element is a `FnType` — not
a useful array shape today).  In that case we fall back to the
original unresolved NamedType so we don't regress the pre-#559
contract for the direct `Array<T>` path.

Two new regression tests in
`tests/test_codegen.py::TestCompoundArrays`:
- `test_nested_alias_array_length_559` — pins
  `array_length(@Grid.0[0])` returning 1 for `[[10]]`.
- `test_nested_alias_2d_index_559` — pins `@Grid.0[1][0]`
  returning 30 for `[[10, 20], [30, 40]]` (chained index branch).

Validation
- pytest tests/ -q -> 3,811 passed, 14 skipped (pre-version-bump
  number; post bump will be 3,813)
- mypy vera/ -> clean
- vera run on issue's repro -> 1 (was: type mismatch trap)
- vera run on Conway's-Life helper pattern -> 3 (was: skipped)

Closes #559

Co-Authored-By: Claude <noreply@anthropic.invalid>
@codecov

codecov Bot commented May 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.06%. Comparing base (db4f9bd) to head (40fb5c6).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #666   +/-   ##
=======================================
  Coverage   91.06%   91.06%           
=======================================
  Files          60       60           
  Lines       23239    23240    +1     
  Branches      259      259           
=======================================
+ Hits        21163    21164    +1     
  Misses       2069     2069           
  Partials        7        7           
Flag Coverage Δ
javascript 57.36% <ø> (ø)
python 94.85% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fc521f44-a313-48e3-97e9-5451962ef712

📥 Commits

Reviewing files that changed from the base of the PR and between db4f9bd and 40fb5c6.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • CHANGELOG.md
  • HISTORY.md
  • KNOWN_ISSUES.md
  • README.md
  • ROADMAP.md
  • TESTING.md
  • docs/index.html
  • docs/index.md
  • docs/llms-full.txt
  • docs/llms.txt
  • docs/sitemap.xml
  • pyproject.toml
  • tests/test_codegen.py
  • vera/__init__.py
  • vera/wasm/inference.py
💤 Files with no reviewable changes (1)
  • KNOWN_ISSUES.md

Walkthrough

Release v0.0.150 fixes issue #559 (nested type aliases in array indexing) by canonicalising element types in InferenceMixin._alias_array_element, adds regression tests for chained alias indexing, and updates version numbers and release documentation across the project.

Changes

Nested Type-Alias Canonicalisation and v0.0.150 Release

Layer / File(s) Summary
Nested alias canonicalisation in array element inference
vera/wasm/inference.py, tests/test_codegen.py
_alias_array_element now canonicalises element types when T is a named alias in Array<T>, enabling correct resolution of chains like Array<Array<Int>> during type inference. Two regression tests verify that array_length(@Grid.0[0]) and chained indexing @Grid.0[1][0] execute correctly for nested alias grids.
Release v0.0.150 documentation and metadata
CHANGELOG.md, HISTORY.md, KNOWN_ISSUES.md, README.md, ROADMAP.md, TESTING.md, pyproject.toml, vera/__init__.py, docs/index.html, docs/index.md, docs/llms.txt, docs/llms-full.txt, docs/sitemap.xml
Version bumped from 0.0.149 to 0.0.150; changelog adds release entry for fix to issue #559; known issues table removes nested alias bug; test metrics updated from 3,825 to 3,827 tests to account for new regression test cases; all version references and release links updated.

Possibly Related PRs

  • aallan/vera#662: Both PRs modify vera/wasm/inference.py's InferenceMixin._alias_array_element to improve how Array<T> element types are resolved through type-alias chains (main PR canonicalises nested alias elements; retrieved PR unwraps RefinementType layers before inferring the underlying array element).
  • aallan/vera#629: Both PRs modify vera/wasm/inference.py's array-index/type inference pipeline by changing how _infer_index_element_type_expr uses _alias_array_element, and the main PR's _alias_array_element canonicalisation of nested Array<alias-of-alias> elements directly complements the retrieved PR's refinement-unwrapping before extracting array element types.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main change: fixing nested type aliases through Array<...> to compile and run correctly, which is the core objective of the PR.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering the problem, solution, rationale, and test plan for fixing nested type aliases.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@aallan aallan merged commit 49d6dff into main May 13, 2026
23 checks passed
@aallan aallan deleted the fix-559-nested-aliases branch May 13, 2026 09:23
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.

Nested type aliases (Array<Array<Foo>>) cause silent codegen skip; WAT error misleadingly points at callers

1 participant