Summary
The Show and Hash abilities are registered as fully polymorphic builtins (vera/environment.py: show: (TypeVar A) -> String, hash: (TypeVar A) -> Int), so the checker accepts show(x) / hash(x) for any type (spec §9.8 documents Show/Hash as universal). But WASM codegen implements them only for primitives — vera/wasm/calls_handlers.py _translate_show (lines 30–73) and _translate_hash (lines 75–119) dispatch via _SHOW_DISPATCH (Int/Nat/Bool/Byte/Float64 + special-cased String/Unit/Decimal) and raise CodegenSkip(arg, "show()/hash() not supported for type <T>") for every composite. The enclosing function is silently dropped from the WASM exports → vera check passes but vera run fails.
This is check-green → codegen-fail on ordinary code. It affects show/hash on: user ADTs (nullary-enum and field-carrying), Tuple, Option, Result, Array, and nested ADTs — 14 confirmed variants (systematic hunt).
Note: structural eq/== on ADTs already works (codegen recurses fields), so the machinery to walk composite layouts exists — show/hash were simply never extended to composites.
Canonical repros
private data Foo { MkFoo(Int) }
public fn main(@Unit -> @String) requires(true) ensures(true) effects(pure) { show(MkFoo(5)) }
private data Color { Red, Green, Blue }
public fn main(@Unit -> @Int) requires(true) ensures(true) effects(pure) { hash(Red) }
Both: vera check → OK; vera run → Function 'main' body contains unsupported ... : show()/hash() not supported for type 'Foo'/'Color' — function skipped. then No exported functions to call. (show(42)/hash(7) on primitives work — the control.)
Fix direction
Implement _translate_show and _translate_hash for composite types by recursing over the value's layout, mirroring how structural eq already walks ADT fields:
- show(ADT): render
ConstructorName (nullary) or ConstructorName(field0, field1, …) with each field rendered by its own show (recursively), per spec §9.8's documented format. Tuple → (a, b); Option → Some(x)/None; Result → Ok(x)/Err(e); Array → [e0, e1, …].
- hash(ADT): fold field hashes into a combined hash (constructor tag + field hashes), recursively.
Both must handle nested composites. Confirm show/hash on every primitive still works unchanged.
Scope
Pre-existing (present on main); surfaced by the systematic check-green→codegen-fail hunt. Fix for v0.1.0 (release/v0.1.0) per the "implement everything" decision. One coherent PR (show + hash share structure).
Summary
The
ShowandHashabilities are registered as fully polymorphic builtins (vera/environment.py:show: (TypeVar A) -> String,hash: (TypeVar A) -> Int), so the checker acceptsshow(x)/hash(x)for any type (spec §9.8 documents Show/Hash as universal). But WASM codegen implements them only for primitives —vera/wasm/calls_handlers.py_translate_show(lines 30–73) and_translate_hash(lines 75–119) dispatch via_SHOW_DISPATCH(Int/Nat/Bool/Byte/Float64 + special-cased String/Unit/Decimal) andraise CodegenSkip(arg, "show()/hash() not supported for type <T>")for every composite. The enclosing function is silently dropped from the WASM exports →vera checkpasses butvera runfails.This is check-green → codegen-fail on ordinary code. It affects
show/hashon: user ADTs (nullary-enum and field-carrying),Tuple,Option,Result,Array, and nested ADTs — 14 confirmed variants (systematic hunt).Note: structural
eq/==on ADTs already works (codegen recurses fields), so the machinery to walk composite layouts exists —show/hashwere simply never extended to composites.Canonical repros
Both:
vera check→ OK;vera run→Function 'main' body contains unsupported ... : show()/hash() not supported for type 'Foo'/'Color' — function skipped.thenNo exported functions to call.(show(42)/hash(7)on primitives work — the control.)Fix direction
Implement
_translate_showand_translate_hashfor composite types by recursing over the value's layout, mirroring how structuraleqalready walks ADT fields:ConstructorName(nullary) orConstructorName(field0, field1, …)with each field rendered by its ownshow(recursively), per spec §9.8's documented format. Tuple →(a, b); Option →Some(x)/None; Result →Ok(x)/Err(e); Array →[e0, e1, …].Both must handle nested composites. Confirm
show/hashon every primitive still works unchanged.Scope
Pre-existing (present on
main); surfaced by the systematic check-green→codegen-fail hunt. Fix for v0.1.0 (release/v0.1.0) per the "implement everything" decision. One coherent PR (show + hash share structure).