Skip to content

Show/Hash abilities unimplemented in codegen for composite types (ADT/Tuple/Option/Result/Array): check-green, function dropped at compile #911

Description

@aallan

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 primitivesvera/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 runFunction '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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions