Skip to content

Commit 197e02b

Browse files
hyperpolymathclaude
andcommitted
fix(layout): add WHT_Any; resultLayout payload now (ref any) — no stubs remain
Adds WHT_Any (WasmGC top reference type) to WasmHeapType. DecEq: 11 new cases (same-constructor Yes Refl + 10 cross-constructor impossible). resultLayout: payload field changed from placeholder WHT_Struct [] to WVT_Ref WHT_Any. — comment updated; resultPayloadIsAny : resultLayout = ... is Refl. anyNot* distinctness proofs (anyNotArray, anyNotStruct, anyNotFunc, anyNotVar, anyNotRec) — all impossible. No stubs, placeholders, or believe_me remain in src/abi/layout/. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 39c1491 commit 197e02b

1 file changed

Lines changed: 40 additions & 3 deletions

File tree

src/abi/layout/Types.idr

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,18 @@ data WasmPrimitive
5656
-- Example: List elem =
5757
-- WHT_Rec (WHT_Struct [("head", WVT_Ref elem), ("tail", WVT_RefNull (WHT_Var 0))])
5858
-- which is the WasmGC type μX. (struct (field (ref elem)) (field (ref null X)))
59+
--
60+
-- WHT_Any is the WasmGC top reference type (`any` in the spec). All struct,
61+
-- array, and i31 references are subtypes of `any`. It is used as the payload
62+
-- type in `resultLayout` (a `Result T E` stores its payload as `(ref any)` and
63+
-- casts to the concrete T or E at the use site).
5964
data WasmHeapType
6065
= WHT_Array WasmValType -- (array <valtype>)
6166
| WHT_Struct (List (String, WasmValType)) -- (struct (field ...))
6267
| WHT_Func (List WasmValType) (List WasmValType) -- (func (param ...) (result ...))
6368
| WHT_Var Nat -- bound type variable (de Bruijn index)
6469
| WHT_Rec WasmHeapType -- μ-binder: (rec <heaptype>)
70+
| WHT_Any -- top reference type: (any)
6571

6672
-- | A WasmGC value type — either a primitive or a typed reference.
6773
data WasmValType
@@ -92,9 +98,10 @@ optionLayout t = WVT_RefNull t
9298
||| Field 1: payload as (ref any) — cast to concrete T or E at use site.
9399
resultLayout : WasmValType
94100
resultLayout =
95-
WVT_Ref (WHT_Struct [("tag", WVT_Prim WasmI32), ("payload", WVT_Ref (WHT_Struct []))])
96-
-- Note: placeholder payload uses an empty struct; a `WasmExtern` constructor
97-
-- will replace it when WasmGC's `any`/`extern` reference types are modelled.
101+
WVT_Ref (WHT_Struct [("tag", WVT_Prim WasmI32), ("payload", WVT_Ref WHT_Any)])
102+
-- Payload is (ref any): the concrete T or E is recovered by a checked downcast
103+
-- at the use site. WHT_Any is the WasmGC top reference type — all structs and
104+
-- arrays are subtypes, so this is the canonical encoding for a sum-type payload.
98105

99106
-- ─────────────────────────────────────────────────────────────────────────────
100107
-- DecEq instances
@@ -198,6 +205,18 @@ mutual
198205
decEq (WHT_Array _) (WHT_Rec _) = No (\case Refl impossible)
199206
decEq (WHT_Struct _) (WHT_Rec _) = No (\case Refl impossible)
200207
decEq (WHT_Func _ _) (WHT_Rec _) = No (\case Refl impossible)
208+
-- WHT_Any — nullary constructor; equal only to itself
209+
decEq WHT_Any WHT_Any = Yes Refl
210+
decEq WHT_Any (WHT_Array _) = No (\case Refl impossible)
211+
decEq WHT_Any (WHT_Struct _) = No (\case Refl impossible)
212+
decEq WHT_Any (WHT_Func _ _) = No (\case Refl impossible)
213+
decEq WHT_Any (WHT_Var _) = No (\case Refl impossible)
214+
decEq WHT_Any (WHT_Rec _) = No (\case Refl impossible)
215+
decEq (WHT_Array _) WHT_Any = No (\case Refl impossible)
216+
decEq (WHT_Struct _) WHT_Any = No (\case Refl impossible)
217+
decEq (WHT_Func _ _) WHT_Any = No (\case Refl impossible)
218+
decEq (WHT_Var _) WHT_Any = No (\case Refl impossible)
219+
decEq (WHT_Rec _) WHT_Any = No (\case Refl impossible)
201220

202221
DecEq WasmValType where
203222
decEq (WVT_Prim p1) (WVT_Prim p2) with (decEq p1 p2)
@@ -289,3 +308,21 @@ varInjective _ _ Refl = Refl
289308
||| WHT_Rec is injective: equal bodies give equal recursive types.
290309
recInjective : (h1 h2 : WasmHeapType) -> WHT_Rec h1 = WHT_Rec h2 -> h1 = h2
291310
recInjective _ _ Refl = Refl
311+
312+
||| WHT_Any is not an array, struct, func, var, or recursive type.
313+
||| Prevents any code from treating the top type as a concrete layout.
314+
anyNotArray : (v : WasmValType) -> WHT_Any = WHT_Array v -> Void
315+
anyNotArray _ Refl impossible
316+
anyNotStruct : (fs : List (String, WasmValType)) -> WHT_Any = WHT_Struct fs -> Void
317+
anyNotStruct _ Refl impossible
318+
anyNotFunc : (ps rs : List WasmValType) -> WHT_Any = WHT_Func ps rs -> Void
319+
anyNotFunc _ _ Refl impossible
320+
anyNotVar : (n : Nat) -> WHT_Any = WHT_Var n -> Void
321+
anyNotVar _ Refl impossible
322+
anyNotRec : (h : WasmHeapType) -> WHT_Any = WHT_Rec h -> Void
323+
anyNotRec _ Refl impossible
324+
325+
||| `resultLayout` payload uses (ref any): correct WasmGC encoding.
326+
resultPayloadIsAny
327+
: resultLayout = WVT_Ref (WHT_Struct [("tag", WVT_Prim WasmI32), ("payload", WVT_Ref WHT_Any)])
328+
resultPayloadIsAny = Refl

0 commit comments

Comments
 (0)