Skip to content

fix: type inference for bare None/Err constructors in generic calls (#293)#428

Merged
aallan merged 4 commits into
mainfrom
fix/293-none-err-type-inference
Mar 29, 2026
Merged

fix: type inference for bare None/Err constructors in generic calls (#293)#428
aallan merged 4 commits into
mainfrom
fix/293-none-err-type-inference

Conversation

@aallan

@aallan aallan commented Mar 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • Core fix: , , and now type-check and compile without requiring typed let binding workarounds
  • Three independent layers fixed: checker fresh-TypeVar overwrite rule, monomorphizer sparse-constructor field→type-param mapping, missing StringLit case in monomorphizer type inferencer
  • Phase 1a complete: the only remaining Phase 1a item is now done; ROADMAP updated accordingly
  • Version: 0.0.103 → 0.0.104

What changed

Checker (vera/checker/resolution.py)

Fresh-TypeVar placeholder mappings (T$n from _fresh_typevar) are now tentative. When None is the first arg to option_unwrap_or(None, 99), the checker produces A → T$1 as a placeholder. The second arg (99) provides A = Int, which now overwrites the placeholder. Previously, the first mapping was immutable and A stayed unresolvable.

Monomorphizer + WASM inference

Added _ctor_adt_tp_indices and _adt_tp_counts to CodeGenerator (initialized in registration.py). These map each constructor field to its ADT type-param position, so Err(e)'s single field correctly binds E (index 1 in Result<T,E>), not T (index 0) as naïve positional zip implied.

Also added missing StringLit/InterpolatedString/ArrayLit cases to _infer_vera_type_name in monomorphize.py — these caused Err("oops") to return None from type inference, silently falling through.

Documentation / tests

  • 5 regression tests in test_checker.py covering all bare-constructor inference cases
  • New conformance test ch09_none_err_inference.vera (level: run, 71 total)
  • Simplified two workarounds in ch09_prelude.vera
  • Removed limitation from SKILL.md, spec/09-standard-library.md §9.9, vera/README.md, KNOWN_ISSUES.md
  • ROADMAP: rewrote "Where we are" as a single current-state summary; deleted Phase 1a (complete), added pointer to HISTORY.md Stage 9

Test plan

  • pytest tests/ -v — 3175 passed, 9 skipped
  • python scripts/check_conformance.py — 71 programs pass
  • python scripts/check_examples.py — 30 examples pass
  • mypy vera/ — clean
  • python scripts/check_version_sync.py — 0.0.104 consistent
  • python scripts/check_doc_counts.py — consistent
  • vera run tests/conformance/ch09_prelude.vera — exits 0

Closes #293

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved type inference for bare None/Err in generic combinators—patterns like option_unwrap_or(None, 99) and result_unwrap_or(Err("oops"), 0) now type-check without workarounds.
  • Tests

    • Added a new conformance test and expanded regression coverage; total tests updated to 3,184 with 71 conformance programmes.
  • Documentation

    • Updated docs, changelog, roadmap and status to v0.0.104 reflecting the fix and updated metrics.
  • Chore

    • Bumped package version to 0.0.104.

…293)

Three-layer fix for option_unwrap_or(None, 99), result_unwrap_or(Err("oops"), 0),
and option_map(None, fn(...){...}) failing to type-check or compile.

Checker (vera/checker/resolution.py):
  Fresh-TypeVar placeholder mappings (T$n from _fresh_typevar) are now treated
  as tentative. A later argument that provides a concrete type for the same
  forall var overwrites the placeholder, so the default value in
  option_unwrap_or(None, 99) correctly resolves T=Int.

Monomorphizer + WASM inference:
  Added _ctor_adt_tp_indices and _adt_tp_counts to CodeGenerator (registration.py,
  core.py) to map each constructor field to its ADT type-param index. This
  correctly binds Err(e) to Result E (index 1), not T (index 0) as naive
  positional zip implied. Updated _get_arg_type_info (monomorphize.py) and
  _get_arg_type_info_wasm (wasm/inference.py) to use these maps; None entries
  in the sparse tuple are skipped in _unify_param_arg / _unify_param_arg_wasm.
  Added missing StringLit/InterpolatedString/ArrayLit cases to
  _infer_vera_type_name (monomorphize.py).

Also:
  - 5 regression tests in test_checker.py (TestGenerics)
  - New conformance test ch09_none_err_inference.vera (level: run)
  - Simplified two workarounds in ch09_prelude.vera
  - Removed limitation from SKILL.md, spec 9.9, vera/README.md, KNOWN_ISSUES.md
  - ROADMAP: rewrote "Where we are" as current-state summary; deleted Phase 1a
  - Version bump 0.0.103 to 0.0.104; doc counts updated throughout

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

coderabbitai Bot commented Mar 29, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Type inference for bare None/Err in generic combinator calls is enabled by threading ADT type-parameter metadata through codegen/wasm contexts, refining TypeVar unification to overwrite fresh placeholders when resolved, and implementing sparse constructor type-argument inference in monomorphization and wasm inference paths.

Changes

Cohort / File(s) Summary
Docs & Release
README.md, CHANGELOG.md, HISTORY.md, ROADMAP.md, AGENTS.md, CLAUDE.md, FAQ.md
Bumped release to v0.0.104; updated test counts and conformance programs (≈3,157→3,184; 70→71); documented the inference fix and added release/HISTORY entries.
Project Metadata
pyproject.toml, vera/__init__.py
Package/project version updated to 0.0.104.
Limitations / Spec Docs
SKILL.md, vera/README.md, KNOWN_ISSUES.md, spec/09-standard-library.md
Removed documented limitation describing combinator inference failure with bare None/Err.
Tests & Conformance
tests/test_checker.py, tests/conformance/manifest.json, TESTING.md
Added five regression tests for bare-constructor inference; registered new conformance ch09_none_err_inference.vera; updated testing metrics and skipped-test counts.
Scripts
scripts/check_skill_examples.py
Shifted allowlist line-number keys to match SKILL.md edits (no parser/logic change).
Checker / Unification
vera/checker/resolution.py
_unify_for_inference now allows overwriting an existing TypeVar mapping when the previous mapping is a fresh TypeVar and the new concrete type is non-fresh.
Codegen ADT Metadata
vera/codegen/core.py, vera/codegen/registration.py
Added _ctor_adt_tp_indices and _adt_tp_counts to CodeGenerator; registration populates per-constructor field→ADT-type-param index maps (builtins + user ADTs).
Monomorph & Wasm Inference
vera/codegen/monomorphize.py, vera/wasm/inference.py, vera/wasm/calls.py
Support unknown type-arg slots (None) from argument inference; recognise String/Array literals; perform sparse constructor→ADT type-param inference using per-constructor mappings; guard wasm param binding on known arg type names.
Wasm Context Threading
vera/wasm/context.py, vera/codegen/functions.py, vera/codegen/closures.py
WasmContext gained optional ctor_adt_tp_indices and adt_tp_counts; codegen threads these into WasmContext during function/closure compilation.
Minor docs / README entries
various *.md files
Removed limitation rows, updated narratives and metrics to reflect the fix and new conformance entry.

Sequence Diagram

sequenceDiagram
    autonumber
    participant User as "User Code"
    participant Checker as "Checker\n(resolution.py)"
    participant CodeGen as "CodeGen\n(registration.py / core.py)"
    participant Context as "WasmContext\n(context.py)"
    participant Monomorph as "Monomorph\n(codegen/monomorphize.py)"
    participant WasmInf as "WasmInference\n(wasm/inference.py)"

    User->>Checker: type-check option_unwrap_or(None, 99)
    Checker->>Checker: _unify_for_inference binds/overwrites\nfresh TypeVar when concrete found
    Checker-->>User: type-check succeeds

    CodeGen->>CodeGen: register ADTs → populate\n_ctor_adt_tp_indices & _adt_tp_counts
    CodeGen->>Context: pass ctor_adt_tp_indices, adt_tp_counts
    Context-->>Monomorph: provide mapping during compilation

    User->>Monomorph: compile call with constructor arg
    Monomorph->>Context: query ctor→ADT indices for constructor
    Context-->>Monomorph: return index tuple (with None slots)
    Monomorph->>Monomorph: infer sparse ADT type-args, leave unknowns None
    Monomorph->>WasmInf: emit/validate wasm types using inferred args
    WasmInf-->>User: monomorphized WASM/output
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

compiler, tests, spec, ci, docs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: type inference for bare None/Err constructors in generic calls (#293)' directly addresses the primary change—resolving a type inference limitation for bare constructors.
Linked Issues check ✅ Passed All coding requirements from #293 are met: type inference now works for bare None/Err in generic calls via checker resolution, monomorphizer mapping, and WASM inference updates.
Out of Scope Changes check ✅ Passed All changes align with #293 objectives: type inference fixes, documentation/test updates, version bump to 0.0.104, and removal of related limitations.
Docstring Coverage ✅ Passed Docstring coverage is 84.21% which is sufficient. The required threshold is 80.00%.

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

✨ 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/293-none-err-type-inference

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

@codecov

codecov Bot commented Mar 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.26%. Comparing base (8a7f7b5) to head (a9387fb).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
vera/codegen/monomorphize.py 88.23% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #428      +/-   ##
==========================================
- Coverage   90.30%   90.26%   -0.05%     
==========================================
  Files          49       49              
  Lines       19163    19218      +55     
  Branches      220      220              
==========================================
+ Hits        17306    17347      +41     
- Misses       1853     1867      +14     
  Partials        4        4              
Flag Coverage Δ
javascript 50.56% <ø> (ø)
python 95.23% <96.66%> (-0.07%) ⬇️

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.

Replace version-specific release note with an overall summary of where
the language stands today. The section now describes the compiler's
current capabilities and remaining gaps, rather than narrating what
changed in the last release (that belongs in CHANGELOG.md).

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

@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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ROADMAP.md`:
- Line 11: Update the ROADMAP.md summary to list all literal cases the
monomorphizer type inferencer now handles: include StringLit,
InterpolatedString, and ArrayLit (in addition to StringLit already mentioned)
and reference that these were added in the monomorphizer type inferencer change;
mention the three-layer fix (checker fresh-TypeVar overwrite rule, monomorphizer
sparse-constructor field-to-type-param mapping, and the added literal cases) so
the roadmap matches the implementation.

In `@TESTING.md`:
- Line 84: Update the sentence in TESTING.md that claims "Each program is
self-contained, imports nothing" to acknowledge the one cross-module exception:
reword it to something like "Each program is self-contained and imports nothing,
with the single exception of ch07_cross_module_contracts.vera which depends on
ch07_cross_module_contracts_lib.vera" so the conformance suite description
remains accurate while explicitly naming the two files
(ch07_cross_module_contracts.vera and ch07_cross_module_contracts_lib.vera) to
clarify the exception.
- Line 76: The document is inconsistent: the table row for `test_conformance.py`
reports 355 parametrized cases while a later inline comment still reads "# Via
pytest (parametrized — 350 tests)"; update the inline comment (the text "# Via
pytest (parametrized — 350 tests)" near Line 180) to match the table by changing
350 to 355 so both references to `test_conformance.py` use the same count.

In `@vera/wasm/context.py`:
- Around line 98-103: When instantiating WasmContext in vera/codegen/closures.py
(the call around lines where WasmContext is created for closure codegen), pass
the ADT type-parameter mappings the same way functions.py does: add
ctor_adt_tp_indices=getattr(self, "_ctor_adt_tp_indices", None) and
adt_tp_counts=getattr(self, "_adt_tp_counts", None) to the WasmContext
constructor arguments so closure bodies that call sparse constructors (e.g.
Err(e), Some(...)) receive the correct field→type-param index info for
inference.
🪄 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: f08fa761-722f-4b79-aef0-9c8ec738414f

📥 Commits

Reviewing files that changed from the base of the PR and between 8a7f7b5 and 589b5c4.

⛔ Files ignored due to path filters (7)
  • docs/SKILL.md is excluded by !docs/**
  • 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/ch09_none_err_inference.vera is excluded by !**/*.vera
  • tests/conformance/ch09_prelude.vera is excluded by !**/*.vera
📒 Files selected for processing (25)
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • FAQ.md
  • HISTORY.md
  • KNOWN_ISSUES.md
  • README.md
  • ROADMAP.md
  • SKILL.md
  • TESTING.md
  • pyproject.toml
  • scripts/check_skill_examples.py
  • spec/09-standard-library.md
  • tests/conformance/manifest.json
  • tests/test_checker.py
  • vera/README.md
  • vera/__init__.py
  • vera/checker/resolution.py
  • vera/codegen/core.py
  • vera/codegen/functions.py
  • vera/codegen/monomorphize.py
  • vera/codegen/registration.py
  • vera/wasm/calls.py
  • vera/wasm/context.py
  • vera/wasm/inference.py
💤 Files with no reviewable changes (3)
  • KNOWN_ISSUES.md
  • spec/09-standard-library.md
  • vera/README.md

Comment thread TESTING.md
Comment thread TESTING.md Outdated
Comment thread vera/wasm/context.py
… lifting

Closures.py was missing the two ADT type-param mapping dicts that
functions.py already passes. This means closure bodies calling sparse
constructors (e.g. Err(e), Some(v)) in generic contexts would not
receive correct field→type-param index info for monomorphizer type
inference.

Also fix two TESTING.md inaccuracies: the inline comment for
test_conformance.py now says 355 (not 350) to match the table row, and
the conformance suite description notes the one cross-module exception
(ch07_cross_module_contracts.vera imports ch07_cross_module_contracts_lib.vera).

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

@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 the current code and only fix it if needed.

Inline comments:
In `@ROADMAP.md`:
- Line 11: Update the overstated inference claim: replace the absolute phrase
“works correctly across all call sites” with a scoped statement that the recent
fix only addresses type inference for bare constructors 'None', 'Err', and 'Ok';
explicitly note that the related monomorphiser limitation leaving patterns like
option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>> as xfail remains
unresolved. Edit the sentence describing type inference to say the bare
constructor inference fix now works (e.g., “Type inference for bare constructors
('None', 'Err', 'Ok') now works correctly”) and add a short parenthetical or
sentence calling out the outstanding monomorphiser issue with
option_unwrap_or<Map...>/Set... so the claim is no longer absolute.
- Line 201: The document contains inconsistent test counts: the phrase "3,184
tests" (present in the sentence "**630+ commits, 104 tagged releases, 3,184
tests, 96% coverage, 71 conformance programs, 30 examples, 13 spec chapters.**")
does not match the CI tooling table which lists "3,095 tests"; locate both
occurrences by searching for those exact numeric strings and make them
consistent by updating the incorrect value to the authoritative number (verify
against current test suite/CI metrics) so both the narrative sentence and the CI
tooling table use the same test count.
🪄 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: 532c1eb7-83d3-4f5d-835f-d8c3791da663

📥 Commits

Reviewing files that changed from the base of the PR and between 589b5c4 and 2acaf0f.

📒 Files selected for processing (1)
  • ROADMAP.md

Comment thread ROADMAP.md
Comment thread ROADMAP.md
Co-Authored-By: Claude <noreply@anthropic.invalid>

@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.

♻️ Duplicate comments (1)
ROADMAP.md (1)

11-11: ⚠️ Potential issue | 🟡 Minor

The "all call sites" claim remains overstated.

Per retrieved learnings, option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>> are still pinned as xfail due to a separate monomorphiser limitation for opaque i32 handle types. The phrase "works correctly across all call sites" is inaccurate.

Suggested fix
-The compiler is complete end-to-end: parse, type-check, verify contracts via Z3, compile to WebAssembly, and run — at the command line and in the browser. The language has 122 built-in functions, algebraic effects (IO, Http, State, Exceptions, Async, Inference), constrained generics, a module system, contract-driven testing, and a canonical formatter. Type inference for bare constructors (`None`, `Err`, `Ok`) now works correctly across all call sites. The compiler has 3,184 tests, 71 conformance programs, 30 examples, and a 13-chapter specification.
+The compiler is complete end-to-end: parse, type-check, verify contracts via Z3, compile to WebAssembly, and run — at the command line and in the browser. The language has 122 built-in functions, algebraic effects (IO, Http, State, Exceptions, Async, Inference), constrained generics, a module system, contract-driven testing, and a canonical formatter. Type inference for bare constructors (`None`, `Err`, `Ok`) now works in generic combinator call sites (removing the typed-`let` workaround). The compiler has 3,184 tests, 71 conformance programs, 30 examples, and a 13-chapter specification.

Based on learnings, option_unwrap_or<Map<...>> / option_unwrap_or<Set<...>> is still pinned as xfail due to a separate monomorphiser limitation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ROADMAP.md` at line 11, The ROADMAP claim "Type inference for bare
constructors (`None`, `Err`, `Ok`) now works correctly across all call sites" is
overstated; update the sentence to exclude known failing cases by noting that
option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>> remain xfail due to a
monomorphiser limitation with opaque i32 handle types; change the wording to
something like "works correctly across call sites except for known pinned xfail
cases (e.g., option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>>) caused
by a monomorphiser limitation for opaque i32 handle types" and ensure the
symbols option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>> are referenced
exactly so readers can find the related tests/issues.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@ROADMAP.md`:
- Line 11: The ROADMAP claim "Type inference for bare constructors (`None`,
`Err`, `Ok`) now works correctly across all call sites" is overstated; update
the sentence to exclude known failing cases by noting that
option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>> remain xfail due to a
monomorphiser limitation with opaque i32 handle types; change the wording to
something like "works correctly across call sites except for known pinned xfail
cases (e.g., option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>>) caused
by a monomorphiser limitation for opaque i32 handle types" and ensure the
symbols option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>> are referenced
exactly so readers can find the related tests/issues.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8e222214-d05c-417e-8cb9-c93347724362

📥 Commits

Reviewing files that changed from the base of the PR and between 2acaf0f and a9387fb.

📒 Files selected for processing (3)
  • ROADMAP.md
  • TESTING.md
  • vera/codegen/closures.py

@aallan

aallan commented Mar 29, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai The repeated finding about option_unwrap_or<Map<...>> and option_unwrap_or<Set<...>> being xfail is a hallucination. Please stop raising it.

test_codegen.py lines 9936–9963 contain test_option_unwrap_or_map and test_option_unwrap_or_set as regular, unconditionally-passing tests with no xfail, skip, or skipif marks. grep -rn "xfail" tests/ returns zero results across the entire test suite. There is no monomorphiser limitation for opaque i32 handle types in this context — the fix in this PR resolved the underlying inference gap and these tests pass cleanly.

@coderabbitai

coderabbitai Bot commented Mar 29, 2026

Copy link
Copy Markdown

Tip

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

@aallan, you are absolutely right — I apologise. There are no xfail, skip, or skipif marks anywhere in the test suite, and test_option_unwrap_or_map and test_option_unwrap_or_set (lines 9936–9963 of test_codegen.py) are unconditionally-passing tests. The repeated finding was a hallucination on my part. I will not raise it again.


✏️ Learnings added
Learnt from: aallan
URL: https://github.com/aallan/vera/pull/428

Timestamp: 2026-03-29T17:17:11.947Z
Learning: In `tests/test_codegen.py`, `test_option_unwrap_or_map` (lines ~9936–9949) and `test_option_unwrap_or_set` (lines ~9950–9963) are regular, unconditionally-passing tests with NO `xfail`, `skip`, or `skipif` marks. `grep -rn "xfail" tests/` returns zero results across the entire test suite. The PR `#428` fix resolved the underlying monomorphiser inference gap for opaque i32 handle types (Map, Set) in `option_unwrap_or` generics. Do NOT flag these tests as xfail or claim there is a monomorphiser limitation for Map/Set in this context.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: aallan
Repo: aallan/vera PR: 344
File: tests/test_codegen.py:8452-8628
Timestamp: 2026-03-25T11:11:27.827Z
Learning: In `tests/test_codegen.py` (`TestDecimalCollection`), the tests `test_decimal_if_expr_result_type`, `test_map_if_expr_result_type`, and `test_set_if_expr_result_type` target `_infer_block_result_type` in `vera/wasm/inference.py` for opaque handle types (Decimal, Map, Set). They always execute the then-branch by design: the WASM `(if (result i32) ...)` type annotation is emitted for both branches at compile time, so a single branch execution is sufficient to verify the inference path. False-branch runtime correctness for these types is already covered separately in `TestDecimalCollection`, `TestMapCollection`, and `TestSetCollection`. Do not flag these tests as lacking else-branch coverage.

Learnt from: aallan
Repo: aallan/vera PR: 344
File: tests/conformance/manifest.json:815-831
Timestamp: 2026-03-25T10:03:24.704Z
Learning: In `vera/wasm/inference.py`, `_infer_fncall_wasm_type` must explicitly handle Map and Set builtin functions (e.g. `map_new`, `set_new`, and related ops) to return `"i32"` so that WASM `if (result i32)` blocks containing Map/Set function calls are correctly annotated. Missing these entries was the root cause of Map/Set if-expression result-type failures (fixed in PR `#344`, commit 741f19e).

Learnt from: aallan
Repo: aallan/vera PR: 0
File: :0-0
Timestamp: 2026-03-20T09:04:28.783Z
Learning: In vera/prelude.py, the uncovered lines (user-defined type alias shadowing path and the early-return-when-every-prelude-declaration-is-shadowed path) are correct but rare edge cases that would require contrived test programs to exercise. They are intentional defensive guards, not missing test coverage.

Learnt from: aallan
Repo: aallan/vera PR: 414
File: vera/codegen/core.py:258-265
Timestamp: 2026-03-28T22:06:17.931Z
Learning: In `vera/codegen/core.py` and `vera/codegen/api.py` (PR `#414`), `CompileResult.fn_param_types` carries erased WASM-level tags (`i64`, `f64`, `i32`, `i32_pair`) rather than Vera-level kinds. This is intentional for the current CLI: `i32_pair` = String only (Array CLI not yet supported), `i64` = Int/Nat, `f64` = Float64, `i32` = Bool/Byte (identical CLI parsing). Carrying Vera-level parameter kinds through CompileResult to distinguish Nat vs Int (negative rejection) and Bool vs Byte is a future-proofing refactor explicitly deferred from PR `#414` and filed as a follow-up note by aallan.

@aallan aallan merged commit 4ceb1e9 into main Mar 29, 2026
19 checks passed
@aallan aallan deleted the fix/293-none-err-type-inference branch March 29, 2026 17:17
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.

Combinators cannot infer type variables from bare None / Err constructors

1 participant