Fix #655 Shape B: refinement-of-Array element inference + release v0.0.146#662
Conversation
…er + release v0.0.146 Closes #655 (Shape A was closed in v0.0.145; Shape B is this fix). ## Root cause `vera/wasm/inference.py::_alias_array_element` followed alias chains by checking `isinstance(target, ast.NamedType)` only. When the alias target was a `RefinementType` (e.g. `type NonEmptyArray = { @array<Int> | array_length(@array<Int>.0) > 0 }`), the helper returned `None`. Downstream `_infer_index_element_type` then returned `None` for `@NonEmptyArray.0[0]`, the enclosing `head` function got dropped via `[E602]` ("body contains unsupported expressions — skipped"), and any call site to `head` referenced a non-existent `$head` → `unknown func: $head` at WASM validation. ## Fix In `_alias_array_element`, peel any `RefinementType` layers from the alias target before checking whether the base is a `NamedType` pointing at `Array<T>`: ```python if type_name in self._type_aliases: target = self._type_aliases[type_name] while isinstance(target, ast.RefinementType): target = target.base_type if isinstance(target, ast.NamedType): return self._alias_array_element(target.name, target.type_args) ``` Mirrors the existing `RefinementType` unwrap pattern in `_canonical_named_type` (lines 619-622). Refinement-of-Array aliases now resolve their element type the same as a bare `Array<T>`. ## Allowlist + KNOWN_ISSUES cleanup `scripts/check_e602_clean.py` allowlist shrinks 6 → 5 entries (the `head` entry is removed). `KNOWN_ISSUES.md` `#655` row removed entirely. ## Example update `examples/refinement_types.vera::test_refine` previously called only `safe_divide` and `to_percentage`. Now also calls `head([42, 1, 2])` so the `head` codepath is exercised end-to-end by `scripts/check_examples.py` + `vera run`. Returns 145 instead of 103 (`10/3 + 100` + `42`). ## Regression tests New `TestHeadOverRefinement655ShapeB` class in `tests/test_codegen.py` with two tests: 1. `test_head_over_refinement_compiles_and_runs` — asserts `(func $head ...)` appears in WAT (function not dropped via [E602]) AND that `execute()` returns 1 (`head([1, 2, 3])`). 2. `test_head_emits_no_e602_for_refinement_alias` — asserts no `[E602]` warning for `head` in the diagnostic stream. Both fail against the pre-fix code path; both pass post-fix. ## Release prep (v0.0.146) Bundled per the ABSOLUTE RULE (no separate cleanup PRs): - `vera/__init__.py` + `pyproject.toml` + `uv.lock`: 0.0.145 → 0.0.146 - `CHANGELOG.md`: dated `[0.0.146] - 2026-05-12` heading + link refs - `HISTORY.md` Stage 12 row: v0.0.146 line clarifying Shape A/B split on v0.0.145 + adding v0.0.146 row - `docs/index.html`: version tag - `README.md` / `TESTING.md` / `ROADMAP.md`: count refreshes (3,813 tests, 146 releases) - `KNOWN_ISSUES.md`: removed #655 row (now fully closed); limitation count 34 (was 35) ## Verification - mypy clean (59 source files) - pytest: 3,799 passed, 14 skipped (was 3,797 + 2 new regression tests) - All 86 conformance programs pass - All 34 examples pass `vera check` + `vera verify` - e602 gate: 116 files clean, 5 allowlist matched, 0 stale - version-sync, doc-counts, limitations-sync: consistent Refs #655 #659 Co-Authored-By: Claude <noreply@anthropic.invalid>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughFixes Shape B of ChangesFix refinement-of-Array element type inference and cleanup
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #662 +/- ##
==========================================
+ Coverage 91.03% 91.05% +0.01%
==========================================
Files 60 60
Lines 23197 23199 +2
Branches 259 259
==========================================
+ Hits 21117 21123 +6
+ Misses 2073 2069 -4
Partials 7 7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@HISTORY.md`:
- Around line 292-293: The HISTORY.md roll-up counter is out of sync: update the
summary that currently reads "144 tagged releases" to "146 tagged releases" to
reflect the two new entries (v0.0.145 and v0.0.146); also search for and update
the matching tagged-release counter in ROADMAP.md so both counters remain
synchronized after adding the two releases.
In `@scripts/check_e602_clean.py`:
- Around line 95-98: Replace the placeholder PR reference and update the
explanatory block so it correctly states that the `head` entry (`#655` Shape B)
was removed in v0.0.146: find the note mentioning `_alias_array_element` in
`vera/wasm/inference.py` and replace "PR #<TBD>" with the actual PR number that
removed `head`, then revise the surrounding text to stop referring to `head` as
an active allowlist case (explain it was removed and why—due to
`_alias_array_element` unwrapping `RefinementType` layers) so the narrative and
status are consistent.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 24268b45-0dd3-47c5-89a4-291cb4357bf4
⛔ Files ignored due to path filters (6)
docs/index.htmlis excluded by!docs/**docs/index.mdis excluded by!docs/**docs/llms-full.txtis excluded by!docs/**docs/llms.txtis excluded by!docs/**examples/refinement_types.verais excluded by!**/*.verauv.lockis excluded by!**/*.lock,!uv.lock
📒 Files selected for processing (11)
CHANGELOG.mdHISTORY.mdKNOWN_ISSUES.mdREADME.mdROADMAP.mdTESTING.mdpyproject.tomlscripts/check_e602_clean.pytests/test_codegen.pyvera/__init__.pyvera/wasm/inference.py
💤 Files with no reviewable changes (1)
- KNOWN_ISSUES.md
CR-1 (`HISTORY.md:334`) — release counter The "Total: 810+ commits, 144 tagged releases, 58 active development days." roll-up was 2 tags out of date. Updated to 146 to reflect v0.0.145 + v0.0.146. CodeRabbit also asked to check ROADMAP.md for a matching counter — verified, ROADMAP does not carry a tagged-release count (only test/example/chapter counts). Skipped that half. `README.md:184` already had the correct "146 releases" from the earlier release-prep update. CR-2 (`scripts/check_e602_clean.py:98`) — allowlist note Replaced `PR #<TBD>` with `PR #662` and rewrote the surrounding prose to reflect that `head` is no longer an active allowlist case. The new note explains why it was removable (the `_alias_array_element` `RefinementType` unwrap means refinement-of-Array aliases resolve their element type the same as bare `Array<T>`) and explicitly states `#655` is fully closed. Narrative + status now consistent. Validation: e602 gate clean (5/5 matched, 0 stale); mypy clean. Refs #655 #662 Co-Authored-By: Claude <noreply@anthropic.invalid>
Summary
head([1, 2, 3])over aNonEmptyArray = { @Array<Int> | predicate }refinement-alias now compiles and runs (returns 1) instead of trapping withunknown func: $headat WASM validation._alias_array_elementinvera/wasm/inference.pyfollowed alias-target chains viaisinstance(target, ast.NamedType)only;RefinementTypewrapping was never unwrapped. Fix peels theRefinementTypelayers (mirroring the existing pattern in_canonical_named_type).Closes #655.
Root cause (one paragraph)
vera/wasm/inference.py::_alias_array_elementresolved alias chains by checkingisinstance(target, ast.NamedType)only. Fortype NonEmptyArray = { @Array<Int> | array_length(@Array<Int>.0) > 0 }, the alias target is aRefinementType(base_type=NamedType("Array", ...), predicate=...)— theisinstance(..., NamedType)check failed and the helper returnedNone. Downstream_infer_index_element_typereturnedNonefor@NonEmptyArray.0[0], theheadfunction got dropped via[E602], and any call site referenced a non-existent$headat WASM validation.Fix
Three lines added (the
whileloop). Mirrors the existingRefinementTypeunwrap pattern in_canonical_named_type(lines 619-622).Regression tests
TestHeadOverRefinement655ShapeBclass with two tests:test_head_over_refinement_compiles_and_runs—(func $head ...)appears in WAT (function not dropped);execute()returns 1.test_head_emits_no_e602_for_refinement_alias— no[E602]warning forheadin the diagnostic stream.Both fail against the pre-fix code path; both pass post-fix.
Allowlist + KNOWN_ISSUES + example cleanup
scripts/check_e602_clean.pyallowlist shrinks 6 → 5 entries (theheadentry removed)KNOWN_ISSUES.md:#655row removed entirely (limitation count 35 → 34)examples/refinement_types.vera::test_refinenow callshead([42, 1, 2])directly so the codepath is exercised end-to-end byscripts/check_examples.py+vera runRelease prep (v0.0.146)
vera/__init__.py+pyproject.toml+uv.lock: 0.0.145 → 0.0.146CHANGELOG.md: dated[0.0.146] - 2026-05-12heading + link refsHISTORY.mdStage 12 row: v0.0.146 line + clarified v0.0.145 row (Shape A only)docs/index.html: version tagREADME.md/TESTING.md/ROADMAP.md: count refreshesTest plan
vera check+vera verify🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests
Chores