Skip to content

fix(wasm): resolve nested fn-type aliases transitively for apply_fn lowering (#867)#880

Closed
aallan wants to merge 1 commit into
mainfrom
fix/867-transitive-alias-fn
Closed

fix(wasm): resolve nested fn-type aliases transitively for apply_fn lowering (#867)#880
aallan wants to merge 1 commit into
mainfrom
fix/867-transitive-alias-fn

Conversation

@aallan

@aallan aallan commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary

A nested type-alias chain to a fn type (type Inner = fn(...); type Mapper = Inner;) used as an apply_fn closure argument resolved only ONE alias hop in every closure-arg return-type consultor — the chain landed on a NamedType, the consultor bailed to its default, and a check-green program failed at run: call_indirect emitted against the wrong signature (type mismatch: expected i32, found i64 trap) on the sync path, and the fused-await classifier silently skipped async_await on the async path (silent wrong value — the #843-family failure at depth ≥ 2).

The fix — one shared transitive resolver

resolve_fn_type_alias(te, type_aliases, type_alias_params) in vera/wasm/async_fusion.py: walks the alias chain depth-N to the terminal FnType, unwrapping RefinementType layers and substituting each generic alias's type params at every hop, with a seen cycle guard returning None on malformed cyclic aliases (the checker already rejects those; the resolver must not infinite-loop regardless). All three consultors route through it — _infer_apply_fn_return_type, _infer_fncall_vera_type's apply_fn arm, and _apply_fn_closure_ret_type — completing the shared-resolver consolidation scoped on the issue (PR #868 follow-through), so depth-N behaviour cannot drift between sites.

Evidence

  • Per-site RED on main: two- and three-hop String-returning alias → call_indirect i32/i64 trap; two- and three-hop Future<Result<String,String>> alias → fused-await classifier emits no async_await import (silent identity await). Single-hop control runs correctly — the bug is specifically transitivity.
  • Orchestrator flip probe (independent): the new conformance program ch05_nested_fn_type_alias on main = check exit 0, run exit 1 with type mismatch: expected i32, found i64; on the branch = run exit 0, correct output.
  • Mutation kills (pycache-purged): chain-follow neutered to one level → all 5 depth-2+ tests RED, the 5 single-hop/AnonFn controls stay green; seen guard removed → the 3 cycle-guard tests time out RED under a SIGALRM watchdog.
  • The pre-existing _still_fails_loud Nested type alias to a fn type breaks apply_fn lowering: single-level alias resolution emits invalid WASM #867 pin test is flipped to _awaited_correctly.

Gates

Full non-stress suite 5915 passed / 43 skipped; conformance 109/109 (new run-level ch05_nested_fn_type_alias); examples 37/37; mypy clean; ruff (incl. --select S) clean; all doc gates + doc counts + site assets regenerated.

Docs

CHANGELOG [Unreleased]; exactly the #867 KNOWN_ISSUES Bugs row removed; spec §9.5.4 + TESTING.md updated. No version bump (rides the v0.1.0 burndown).

Closes #867

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed apply_fn/indirect-call handling for nested (transitive) function-type aliases, including generic substitution and cycle-safe resolution, preventing invalid indirect-call closure signatures (e.g., mismatched value widths).
  • Tests
    • Added regression coverage for multi-hop and refinement-wrapped fn type aliases, including behaviour through cyclic alias graphs.
  • Documentation
    • Updated the §9.5.4 “Async” specification and refreshed conformance/testing materials to reflect 109 programs (including the new relevant conformance entry).

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 92ca495c-d572-4003-94f3-463ed69b22d7

📥 Commits

Reviewing files that changed from the base of the PR and between 60d398d and 4327251.

⛔ Files ignored due to path filters (5)
  • docs/index.html is excluded by !docs/**
  • docs/index.md is excluded by !docs/**
  • docs/llms-full.txt is excluded by !docs/**
  • docs/llms.txt is excluded by !docs/**
  • tests/conformance/ch05_nested_fn_type_alias.vera is excluded by !**/*.vera
📒 Files selected for processing (16)
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • FAQ.md
  • KNOWN_ISSUES.md
  • ROADMAP.md
  • TESTING.md
  • spec/09-standard-library.md
  • tests/conformance/manifest.json
  • tests/test_codegen_closures.py
  • tests/test_codegen_modules.py
  • tests/test_codegen_monomorphize.py
  • vera/monomorphize.py
  • vera/wasm/async_fusion.py
  • vera/wasm/calls.py
  • vera/wasm/inference.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • aallan/vera-bench (manual)
💤 Files with no reviewable changes (1)
  • KNOWN_ISSUES.md

📝 Walkthrough

Walkthrough

Adds shared transitive resolution for function-type aliases, wires it into wasm inference and call handling, expands regression coverage, and updates the async-lowering spec, release notes, and conformance/test count documentation.

Changes

Alias resolution fix and coverage

Layer / File(s) Summary
Shared alias resolver
vera/monomorphize.py
Adds resolve_fn_type_alias for transitive FnType alias resolution with refinement unwrapping, generic substitution, and cycle detection, and uses it in callable-shape inference.
Wasm inference and call-site wiring
vera/wasm/async_fusion.py, vera/wasm/calls.py, vera/wasm/inference.py
Routes SlotRef closure handling, apply_fn return-type inference, and wasm call-site alias handling through the shared resolver.
Regression tests and manifest
tests/conformance/manifest.json, tests/test_codegen_closures.py, tests/test_codegen_modules.py, tests/test_codegen_monomorphize.py
Adds the new conformance case, closure/codegen regressions for multi-hop aliases and refinement-wrapped fn types, generic HOF alias tests, and cycle-guard coverage.
Spec and release notes
spec/09-standard-library.md, CHANGELOG.md, KNOWN_ISSUES.md
Updates the async lowering spec, records the fix in the changelog, and removes the resolved known-issues entry.

Conformance and test count documentation

Layer / File(s) Summary
Count updates
AGENTS.md, CLAUDE.md, FAQ.md, ROADMAP.md, TESTING.md
Updates conformance-program totals and related test metrics throughout project documentation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

  • aallan/vera#629: Both PRs modify vera/wasm/inference.py’s apply_fn/closure-return type inference to correctly unwrap RefinementType and resolve terminal callable/FnType return shapes.
  • aallan/vera#631: Both PRs change the WASM apply_fn/call_indirect type inference paths in vera/wasm/inference.py to improve canonical/type-alias handling.
  • aallan/vera#659: Both PRs touch the mono/codegen inference path for callable SlotRef arguments whose static type is a FnType alias.

Suggested labels: compiler, tests, spec, docs

🚥 Pre-merge checks | ✅ 8
✅ Passed checks (8 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: transitive resolution of nested fn-type aliases for apply_fn lowering.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Changelog Covers Public-Surface Changes ✅ Passed Only public-surface file changed is spec/09-standard-library.md, and CHANGELOG.md explicitly describes the transitive alias/await-lowering fix.
Spec And Implementation Move Together ✅ Passed Spec 09.5.4 now documents transitive fn-alias resolution for apply_fn/await, and the changed vera/* paths all route through the shared resolver to match.
Diagnostics Carry An Error Code ✅ Passed No new diagnostic emissions or changed diagnostic definitions were introduced; the patch only alters alias-resolution/type-inference paths and docs/tests.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/867-transitive-alias-fn

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

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.56604% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.01%. Comparing base (01225e8) to head (4327251).

Files with missing lines Patch % Lines
vera/monomorphize.py 89.28% 3 Missing ⚠️
vera/wasm/calls.py 85.71% 1 Missing ⚠️
vera/wasm/inference.py 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #880      +/-   ##
==========================================
- Coverage   93.01%   93.01%   -0.01%     
==========================================
  Files          95       95              
  Lines       29232    29208      -24     
  Branches      360      360              
==========================================
- Hits        27190    27167      -23     
+ Misses       2036     2035       -1     
  Partials        6        6              
Flag Coverage Δ
javascript 75.01% <ø> (ø)
python 95.01% <90.56%> (-0.01%) ⬇️

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

☔ View full report in Codecov by Harness.
📢 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 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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 `@vera/wasm/async_fusion.py`:
- Around line 169-236: resolve_fn_type_alias currently drops refinement-wrapped
fn aliases because it only returns a value when the alias is a plain ast.FnType
before any further unwrapping. Update the walker so that after peeling
ast.RefinementType layers from the alias body, it treats a wrapped fn as
terminal and returns that ast.FnType instead of falling through to None. Keep
the existing alias-chain handling in resolve_fn_type_alias and the related
substitution logic intact, but make sure refinement_type cases resolve the same
way as bare fn_type aliases.
🪄 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 Plus

Run ID: b104c382-5790-4264-b2e2-2414c64fe763

📥 Commits

Reviewing files that changed from the base of the PR and between c0af1b9 and ab15b0b.

⛔ Files ignored due to path filters (5)
  • docs/index.html is excluded by !docs/**
  • docs/index.md is excluded by !docs/**
  • docs/llms-full.txt is excluded by !docs/**
  • docs/llms.txt is excluded by !docs/**
  • tests/conformance/ch05_nested_fn_type_alias.vera is excluded by !**/*.vera
📒 Files selected for processing (13)
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • FAQ.md
  • KNOWN_ISSUES.md
  • ROADMAP.md
  • TESTING.md
  • spec/09-standard-library.md
  • tests/conformance/manifest.json
  • tests/test_codegen_closures.py
  • tests/test_codegen_modules.py
  • vera/wasm/async_fusion.py
  • vera/wasm/inference.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • aallan/vera-bench (manual)
💤 Files with no reviewable changes (1)
  • KNOWN_ISSUES.md

Comment thread vera/wasm/async_fusion.py Outdated
aallan pushed a commit that referenced this pull request Jul 3, 2026
…eling; generic-HOF consultors routed through the shared resolver

Two findings from the PR #880 review, both the #867 nested-alias class:

Finding 1 (CodeRabbit, Major): `resolve_fn_type_alias` peeled
`RefinementType` layers but did not treat a bared inline `FnType` as
terminal — an alias whose body is a refinement directly wrapping a fn
type (`type Foo = { @fn(String -> String) | p };`) fell through the
`NamedType` check to None, and the caller fell to the i64 default:
check-green, `vera run` trap (`type mismatch: expected i32, found
i64`). An Int-returning closure ran by coincidence (the i64 default
matches Int) — the String probe is the discriminator. The walk now
checks `isinstance(te, ast.FnType)` at the top of each iteration, so a
peeled FnType is terminal at any depth.

Finding 2 (blast-radius skeptic, pre-existing, same class): the generic
higher-order-fn path still did single-hop alias lookups in four places
— `Monomorphizer._resolve_arg_fn_shape` / `_infer_fn_alias_type_args`
(vera/monomorphize.py, instantiation discovery) and their WASM
call-rewrite twins in vera/wasm/calls.py. A two-hop-alias-typed closure
slot passed to a generic HOF (`my_map(@MyFn.0, 7)` with `type MyFn =
InnerFn;`) failed shape resolution, so a closure-bound type param fell
to the phantom-var default: wrong mono suffix (`my_map$Int_Bool`,
result i32), check-green, run-trap (`expected i64, found i32`) — while
the single-hop control ran. The HOF's own fn param declared through an
alias chain (`type MapFn2<X, Y> = MapFn<X, Y>;`) hit the same gap on
the param-lookup side. All four sites now route through
`resolve_fn_type_alias`; the param side resolves the chain instantiated
at the alias's own param names so positional matching survives
renaming hops.

The resolver moved from vera/wasm/async_fusion.py to the codegen-free
vera/monomorphize.py (the #732 relocation precedent): the monomorphizer
itself is now a consumer, and async_fusion imports vera.monomorphize,
so hosting it in async_fusion would have made that import a cycle. The
sweep of remaining `_type_aliases.get` + isinstance-FnType single-hop
patterns also routed the fn-typed-slot classifier in
`_infer_expr_wasm_type` (vera/wasm/inference.py); the other transitive
walkers (`_reaches_fn_type`, `_canonical_named_type`,
`_resolve_base_type_name`, registration.py resolvers) were verified
already depth-N.

Mutation-validated per site: restoring the pre-fix non-terminal
peeled-FnType structure flips exactly the two refinement tests;
un-routing any one of the four HOF sites flips exactly its
discriminating test (arg-side x2 -> the two-hop run + mangle tests;
param-side x2 -> the param-chain test); controls stay green throughout.

Co-Authored-By: Claude <[email protected]>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
TESTING.md (1)

151-155: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the run-level conformance count here.

Line 151 still says 89 run-level programmes, but Line 180 now says 91. This sentence is stale and leaves the file internally inconsistent.

🤖 Prompt for 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.

In `@TESTING.md` around lines 151 - 155, Update the stale run-level conformance
count in the TESTING.md summary so it matches the current total used elsewhere
in the document. Adjust the `test_wasi_target.py` description text that mentions
the dual-target conformance differential from 89 to the same value as the later
conformance count, keeping the wording consistent and internally aligned.
🤖 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.

Outside diff comments:
In `@TESTING.md`:
- Around line 151-155: Update the stale run-level conformance count in the
TESTING.md summary so it matches the current total used elsewhere in the
document. Adjust the `test_wasi_target.py` description text that mentions the
dual-target conformance differential from 89 to the same value as the later
conformance count, keeping the wording consistent and internally aligned.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3d0ca779-17e7-4fbd-bca6-3fec39d5f662

📥 Commits

Reviewing files that changed from the base of the PR and between ab15b0b and 4ee579e.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • ROADMAP.md
  • TESTING.md
  • tests/test_codegen_closures.py
  • tests/test_codegen_modules.py
  • tests/test_codegen_monomorphize.py
  • vera/monomorphize.py
  • vera/wasm/async_fusion.py
  • vera/wasm/calls.py
  • vera/wasm/inference.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • aallan/vera-bench (manual)

@aallan aallan force-pushed the fix/867-transitive-alias-fn branch from 4ee579e to 7831e46 Compare July 3, 2026 07:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@FAQ.md`:
- Line 177: The FAQ still contains the old conformance-suite program count, so
update every remaining occurrence of the 108 literal to 109 throughout the file,
including the prose in the Conformance Suite section and any other free-form
references; use the existing conformance-suite wording around the Vera
documentation and test-suite descriptions to locate and replace all stale counts
consistently.

In `@TESTING.md`:
- Around line 9-11: The conformance suite count is stale in the prose, so the
document is internally inconsistent. Update every occurrence of the old 108
literal in TESTING.md, including the free-form paragraph under the Conformance
Suite section, so it matches the current 109 count shown in the overview table.
Use the Conformance Suite heading and the surrounding prose to locate and
replace any remaining old-count references.
🪄 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 Plus

Run ID: 519f9288-b69b-48c2-a993-b1fe5c978418

📥 Commits

Reviewing files that changed from the base of the PR and between 4ee579e and 7831e46.

⛔ Files ignored due to path filters (5)
  • docs/index.html is excluded by !docs/**
  • docs/index.md is excluded by !docs/**
  • docs/llms-full.txt is excluded by !docs/**
  • docs/llms.txt is excluded by !docs/**
  • tests/conformance/ch05_nested_fn_type_alias.vera is excluded by !**/*.vera
📒 Files selected for processing (16)
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • FAQ.md
  • KNOWN_ISSUES.md
  • ROADMAP.md
  • TESTING.md
  • spec/09-standard-library.md
  • tests/conformance/manifest.json
  • tests/test_codegen_closures.py
  • tests/test_codegen_modules.py
  • tests/test_codegen_monomorphize.py
  • vera/monomorphize.py
  • vera/wasm/async_fusion.py
  • vera/wasm/calls.py
  • vera/wasm/inference.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • aallan/vera-bench (manual)

Comment thread FAQ.md
Comment thread TESTING.md Outdated
@aallan

aallan commented Jul 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@aallan aallan force-pushed the fix/867-transitive-alias-fn branch from 7831e46 to 60d398d Compare July 3, 2026 08:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
vera/wasm/inference.py (1)

1743-1771: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Refinement-wrapped FnType aliases still need the shared resolver

vera/wasm/context.py and vera/wasm/data.py both feed annotated slot types into _slot_name_to_wasm_type, so a binding like let @foo = ... with type Foo = { @fn(String -> String) effects(pure) | true }; still reaches the name in self._type_aliases branch, misses the bare ast.FnType check, and falls through to None. That rejects a valid closure-typed slot. Route this branch through resolve_fn_type_alias(...) so refinement-wrapped and chained aliases map to i32 too.

🤖 Prompt for 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.

In `@vera/wasm/inference.py` around lines 1743 - 1771, The slot type mapper in
_slot_name_to_wasm_type is treating only bare ast.FnType aliases as closures, so
refinement-wrapped or chained function aliases can fall through to None. Update
the self._type_aliases branch to use resolve_fn_type_alias(...) before deciding
the WASM type, and keep returning i32 for any alias that resolves to a function
type. This lets annotated slots coming from context.py and data.py map correctly
for cases like Foo-style alias refinements.
🤖 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.

Outside diff comments:
In `@vera/wasm/inference.py`:
- Around line 1743-1771: The slot type mapper in _slot_name_to_wasm_type is
treating only bare ast.FnType aliases as closures, so refinement-wrapped or
chained function aliases can fall through to None. Update the self._type_aliases
branch to use resolve_fn_type_alias(...) before deciding the WASM type, and keep
returning i32 for any alias that resolves to a function type. This lets
annotated slots coming from context.py and data.py map correctly for cases like
Foo-style alias refinements.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3b0113b0-d931-4ab7-b411-1a40b9ba133a

📥 Commits

Reviewing files that changed from the base of the PR and between 7831e46 and 60d398d.

⛔ Files ignored due to path filters (5)
  • docs/index.html is excluded by !docs/**
  • docs/index.md is excluded by !docs/**
  • docs/llms-full.txt is excluded by !docs/**
  • docs/llms.txt is excluded by !docs/**
  • tests/conformance/ch05_nested_fn_type_alias.vera is excluded by !**/*.vera
📒 Files selected for processing (16)
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • FAQ.md
  • KNOWN_ISSUES.md
  • ROADMAP.md
  • TESTING.md
  • spec/09-standard-library.md
  • tests/conformance/manifest.json
  • tests/test_codegen_closures.py
  • tests/test_codegen_modules.py
  • tests/test_codegen_monomorphize.py
  • vera/monomorphize.py
  • vera/wasm/async_fusion.py
  • vera/wasm/calls.py
  • vera/wasm/inference.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • aallan/vera-bench (manual)
💤 Files with no reviewable changes (1)
  • KNOWN_ISSUES.md

…ering, generic-HOF consultors, refinement peeling (#867)

One shared cycle-guarded resolver (resolve_fn_type_alias, relocated to
vera/monomorphize.py to avoid an import cycle): apply_fn closure-return
consultors, the generic higher-order-function monomorphization sites
(calls.py + monomorphize.py twins), and FnType-terminal after refinement
unwrapping. Flips the pre-existing still-fails-loud #867 pin to
awaited-correctly.

PR #880 review, 4th single-hop site: _slot_name_to_wasm_type
(vera/wasm/inference.py) classified only a BARE FnType alias as an i32
closure pointer, so a let/param slot annotated with a refinement-wrapped
fn alias (type Foo = { @fn(...) | p };) or one chained through a
refinement resolved to None — the binding was rejected with CodegenSkip
("has no WASM representation") and its whole function dropped, on a
check/verify-green program. A plain NamedType chain was already handled
by the _resolve_base_type_name prefix, so only the refinement-involving
shapes remained. Routed through the same shared resolver; mutation-kill:
un-routing it flips exactly its two refinement-slot tests, all others
green.

Co-Authored-By: Claude <[email protected]>
@aallan aallan force-pushed the fix/867-transitive-alias-fn branch from 60d398d to 4327251 Compare July 3, 2026 08:46
@aallan

aallan commented Jul 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai On the outside-diff vera/wasm/inference.py finding (_slot_name_to_wasm_type refinement-wrapped/chained fn-alias slots — Major): confirmed LIVE and fixed in 4327251. The branch there classified only a bare ast.FnType alias as an i32 closure; a refinement-wrapped alias (type Foo = { @fn(String -> String) effects(pure) | true }) or a chain through a refinement, used as a let @Foo = … slot, fell to None and dropped the function via CodegenSkip (check-green → "No exported functions to call"). Now routed through resolve_fn_type_alias like the other three sites. A plain NamedType chain (type Foo = Bar; type Bar = fn(...)) was already handled by the existing _resolve_base_type_name prefix walk, so only the refinement-involving shapes remained — pinned by two new tests, mutation-validated (revert this site → exactly those 2 flip RED, the 5 apply_fn-site tests stay green).

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
git log --oneline -5 4327251 2>/dev/null || echo "commit not found locally"
git show 4327251 --stat 2>/dev/null | head -30
echo "---"
rg -n "_slot_name_to_wasm_type|resolve_fn_type_alias" vera/wasm/inference.py -A5 -B5 | head -100

Length of output: 7552


Confirmed — commit 4327251 is present on the branch and _slot_name_to_wasm_type (Line 172, vera/wasm/inference.py) now routes through resolve_fn_type_alias exactly as described, replacing the prior bare-FnType check.

@aallan Thanks for the detailed follow-up — I verified 4327251 on the branch. Line 172 in vera/wasm/inference.py now calls resolve_fn_type_alias(ast.NamedType(name=expr.type_name, type_args=expr.type_args), self._type_aliases, self._type_alias_params) instead of a direct FnType alias check, so refinement-wrapped and refinement-chained fn-alias slots correctly classify as "i32" closure pointers rather than falling through to None/CodegenSkip. This closes the last of the four consultor sites (alongside _infer_apply_fn_return_type, _infer_fncall_vera_type's apply_fn arm, and _apply_fn_closure_ret_type) on the shared resolver, and the mutation-kill behavior you described (reverting this hop flips exactly the two refinement-slot tests) matches good regression hygiene. Marking this resolved.

aallan pushed a commit that referenced this pull request Jul 3, 2026
@aallan

aallan commented Jul 3, 2026

Copy link
Copy Markdown
Owner Author

Superseded by the release/v0.1.0 integration branch — this fix is merged there as e70c8c0 (full six-fix suite green: 6162 passed). Per-bug review record preserved here; issue closure (#867) rides the single release/v0.1.0 → main PR. Closing this PR.

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 alias to a fn type breaks apply_fn lowering: single-level alias resolution emits invalid WASM

1 participant