Surfaced by
Layer 1 of #626 — the new scripts/check_e602_clean.py pre-commit gate that fails when any compile emits [E602] (body unsupported) or [E604] (param unsupported) outside an explicit allowlist. When the gate first ran across examples/*.vera + tests/conformance/*.vera, eight functions failed it. This issue tracks them.
Two failure shapes
Shape A — spurious warnings, mono clones work end-to-end (7 functions)
These are generic-decl [E602] / [E604] warnings that fire against the template declaration, while the actual mono clones (produced per call site at vera/codegen/core.py::compile_program's mono-decls loop) compile and run correctly. Same root cause as the #604 option_unwrap_or / result_unwrap_or half — the compilability check is running on the wrong artefact.
| Function |
File |
Code |
Verified-via-mono |
identity |
examples/generics.vera, tests/conformance/ch02_generics.vera |
E604 |
✓ — test_generics returns 42 |
const |
examples/generics.vera |
E604 |
✓ — test_generics returns 42 |
is_some |
examples/generics.vera, tests/conformance/ch02_generics.vera |
E602 |
✓ — is_some(Some(42)) returns true |
are_equal |
tests/conformance/ch09_abilities.vera |
E604 |
✓ — Eq-constrained generic; ability dispatch in mono clone |
cmp_sign |
tests/conformance/ch09_abilities.vera |
E604 |
✓ — Ord-constrained generic |
All five are forall<T> (or forall<A, B>) with bare type-variable parameters. The mono name-mangler produces e.g. identity$Int, is_some$Int — those compile cleanly.
Shape B — real codegen gap, function genuinely missing (1 function)
| Function |
File |
Code |
Trap |
head |
examples/refinement_types.vera |
E602 |
Calling head([42, 13, 99]) produces WAT compilation failed: unknown func: $head |
head is a non-generic function taking a refinement-type-over-Array parameter:
type NonEmptyArray = { @Array<Int> | array_length(@Array<Int>.0) > 0 };
private fn head(@NonEmptyArray -> @Int)
requires(true) ensures(true) effects(pure)
{
@NonEmptyArray.0[0]
}
The body @NonEmptyArray.0[0] is an IndexExpr on a slot whose declared type is @NonEmptyArray (a type-alias for a refinement-of-Array). The translator returns None somewhere in this chain — either the IndexExpr translator doesn't unwrap the refinement-alias before checking the element-load shape, or the slot-type resolution stops at the alias name without descending into the refinement's @Array<Int> base.
examples/refinement_types.vera runs successfully today because test_refine doesn't actually call head — but a user who copy-pasted head and tried to use it would hit the missing-$head error.
Why this isn't #604
Acceptance
Pairs with
Surfaced by
Layer 1 of #626 — the new
scripts/check_e602_clean.pypre-commit gate that fails when any compile emits[E602](body unsupported) or[E604](param unsupported) outside an explicit allowlist. When the gate first ran acrossexamples/*.vera+tests/conformance/*.vera, eight functions failed it. This issue tracks them.Two failure shapes
Shape A — spurious warnings, mono clones work end-to-end (7 functions)
These are generic-decl
[E602]/[E604]warnings that fire against the template declaration, while the actual mono clones (produced per call site atvera/codegen/core.py::compile_program's mono-decls loop) compile and run correctly. Same root cause as the #604option_unwrap_or/result_unwrap_orhalf — the compilability check is running on the wrong artefact.identityexamples/generics.vera,tests/conformance/ch02_generics.veraE604test_genericsreturns 42constexamples/generics.veraE604test_genericsreturns 42is_someexamples/generics.vera,tests/conformance/ch02_generics.veraE602is_some(Some(42))returnstrueare_equaltests/conformance/ch09_abilities.veraE604cmp_signtests/conformance/ch09_abilities.veraE604All five are
forall<T>(orforall<A, B>) with bare type-variable parameters. The mono name-mangler produces e.g.identity$Int,is_some$Int— those compile cleanly.Shape B — real codegen gap, function genuinely missing (1 function)
headexamples/refinement_types.veraE602head([42, 13, 99])producesWAT compilation failed: unknown func: $headheadis a non-generic function taking a refinement-type-over-Array parameter:The body
@NonEmptyArray.0[0]is anIndexExpron a slot whose declared type is@NonEmptyArray(a type-alias for a refinement-of-Array). The translator returnsNonesomewhere in this chain — either the IndexExpr translator doesn't unwrap the refinement-alias before checking the element-load shape, or the slot-type resolution stops at the alias name without descending into the refinement's@Array<Int>base.examples/refinement_types.veraruns successfully today becausetest_refinedoesn't actually callhead— but a user who copy-pastedheadand tried to use it would hit the missing-$headerror.Why this isn't #604
_unwrap_orhalf (warning fires on template; mono works), but the affected functions are user-code, not the prelude. Fixing Five prelude combinators silently skipped from every WASM compile (option_map / option_and_then / result_map + two _unwrap_or variants) #604's diagnostic side ("suppress the warning when at least one mono clone of this generic exists") would close Shape A here as a side effect.Acceptance
identity/const/is_some/are_equal/cmp_signinscripts/check_e602_clean.pycan be removed.head([1,2,3])end-to-end. Remove theheadallowlist entry.Pairs with
scripts/check_e602_clean.pytoward empty.