green(reify): field_type($T, i) -> Type over the type table
REIFY Phase 2.1. fieldTypeOf (lower/generic.zig, re-exported on Lowering) returns the i-th member type of T: struct field / tagged-union + union variant payload (.void for a tagless variant) / tuple element / array + vector element. Out-of-range and memberless types poison to .unresolved with a loud diagnostic (never a silent default). Wired into resolveTypeCallWithBindings (replacing the Phase-2 bail); since it folds to a TypeId at lower time it composes inside type_eq / type_name / any type-arg slot. examples/0616 green: struct fields (name via field_name + type via field_type), type_eq fold, tagged-union payloads incl. quit -> void. Suite green (672 examples, 447 unit). type_info($T) -> TypeInfo (reflect into a value, inverse of reify) is NOT done — still bails loudly; it's the larger Phase 2.2 step (widen the TypeInfo data model + comptime value construction). Plan/checkpoint updated.
This commit is contained in:
@@ -4,7 +4,21 @@ Companion to [PLAN-REIFY.md](PLAN-REIFY.md). Update after every step (one step a
|
||||
time, per the cadence rule).
|
||||
|
||||
## Last completed step
|
||||
**Phase 1 (type-fn → reify identity) — COMPLETE.** A type-fn body that returns
|
||||
**Phase 2.1 (green) — `field_type` done.** `field_type($T, i) -> Type` is
|
||||
implemented over the type table (`fieldTypeOf` in `lower/generic.zig`, re-exported
|
||||
on `Lowering`): struct field / tagged-union + `union` variant payload (`.void` for
|
||||
a tagless variant) / tuple element / array + vector element; OOB and memberless
|
||||
types poison to `.unresolved` with a loud diagnostic (never a silent default).
|
||||
It folds at lower time, so it composes inside `type_eq` / `type_name` / any type-arg
|
||||
slot. `examples/0616` green (struct fields name+type, `type_eq` fold, tagged-union
|
||||
payloads incl. `quit → void`). Full suite green (672 examples, 447 unit). Cadence:
|
||||
2.0 xfail (empty marker, RED) → 2.1 green (this commit).
|
||||
|
||||
**`type_info` is NOT done** — it still bails loudly in
|
||||
`call.zig:tryLowerReflectionCall`. It builds a full `TypeInfo` *value* (inverse of
|
||||
reify) and is the larger Phase 2.2 step (see Next step).
|
||||
|
||||
### (prior) Phase 1 (type-fn → reify identity) — COMPLETE. A type-fn body that returns
|
||||
`reify(...)` now mints the enum under the instantiation's name:
|
||||
`instantiateTypeFunction` (`lower/generic.zig`) detects a reify-returning body
|
||||
(`findReturnReifyCall`) and routes it to `reifyType(<mangled-or-alias name>,
|
||||
@@ -65,16 +79,23 @@ on-demand import keeps the prelude clean; reify users `#import
|
||||
"modules/std/meta.sx"`. (User-directed.)
|
||||
|
||||
## Next step
|
||||
**Phase 2 (`type_info` + `field_type`).** Reflect a struct/tuple → read variant /
|
||||
field names + **types** (`field_type($T, i) -> Type`, `type_info($T) -> TypeInfo`).
|
||||
xfail → green by implementing both over the type table (reuse the
|
||||
`field_count`/`field_name` reflection path; both currently bail loudly —
|
||||
`type_info` in `call.zig:tryLowerReflectionCall`, `field_type` in
|
||||
`generic.zig:resolveTypeCallWithBindings`). NOTE: `reifyType` still reads a LITERAL
|
||||
`TypeInfo` off the AST (works for the inline-literal and type-fn-over-literal cases
|
||||
Phases 0–1 use); a `type_info`-derived (computed, non-literal) `TypeInfo` fed back
|
||||
into `reify` would need the reader generalized (or interp evaluation) — call that out
|
||||
when Phase 2 enables round-tripping.
|
||||
**Phase 2.2 (`type_info($T) -> TypeInfo`).** Reflect a type into a `TypeInfo`
|
||||
*value* — the inverse of reify. Two sub-pieces, both non-trivial: (a) widen the
|
||||
`meta.sx` `TypeInfo` data model beyond `` `enum `` (struct / tuple variants); (b)
|
||||
build the value at comptime — a `[]EnumVariant`-style slice of structs holding
|
||||
strings (`name`) + `Type` tags (`payload`), populated from the type table. This is
|
||||
comptime value-CONSTRUCTION (allocating slice/struct/string/type-tag values in the
|
||||
interpreter), materially larger than 2.1's fold-to-a-TypeId. Currently bails loudly
|
||||
in `call.zig:tryLowerReflectionCall`. Best done as its own session for context room.
|
||||
|
||||
NOTE (round-tripping): `reifyType` still reads a LITERAL `TypeInfo` off the AST
|
||||
(fine for the inline-literal + type-fn-over-literal cases of Phases 0–1). Once 2.2
|
||||
produces a COMPUTED `TypeInfo`, feeding it back into `reify` needs the reader
|
||||
generalized (or interp evaluation of the `TypeInfo` value) — handle that when 2.2
|
||||
enables round-tripping.
|
||||
|
||||
Alternatively jump to **Phase 3** (`make_enum` + `RecvResult`/`TryResult` sx lib over
|
||||
`reify`) — that only needs reify (have it) + type-fns (have them), not `type_info`.
|
||||
|
||||
SELF-REFERENCE = Phase 4, API DECIDED (user-directed): explicit **`declare()` →
|
||||
`define(h, info)`** (the declaration-vs-definition split; NOT a `reify_rec((self)=>…)`
|
||||
@@ -92,6 +113,11 @@ in PLAN-REIFY Phase 4.
|
||||
None yet.
|
||||
|
||||
## Log
|
||||
- **2.1 (green) — `field_type` done.** `fieldTypeOf` over the type table
|
||||
(struct/tagged-union/union/tuple/array/vector; OOB+memberless = loud poison);
|
||||
folds at lower time, composes in `type_eq`/`type_name`; `0616` green. `type_info`
|
||||
still pending (Phase 2.2 — builds a TypeInfo value).
|
||||
- **2.0 (xfail).** `0616` + empty `.exit` marker → RED (field_type bailed).
|
||||
- **1.1 (green) — Phase 1 done.** Type-fn body `return reify(...)` routes through
|
||||
`reifyType` under the instantiation name (`findReturnReifyCall` +
|
||||
mangled-name registration); `Box(i64)` at two sites = one type (Contract 1);
|
||||
|
||||
@@ -70,11 +70,12 @@ Examples: `06xx` (comptime, deterministic), `11xx` (diagnostics for loud failure
|
||||
| 1.0 | xfail | `examples/06xx-comptime-reify-typefn-identity.sx` — `R :: ($T)->Type { reify(...) }`; assert `R(i64)` from two sites is ONE type (assignable/matchable across sites). Red if reify-result not registered by mangled name. | `examples/06xx-*` |
|
||||
| 1.1 | green | register a reify-returning type-fn's result under the instantiation mangled name (mirror the inline-struct path `generic.zig:1663-1689`). Identity holds (Contract 1). | `src/ir/lower/generic.zig` |
|
||||
|
||||
### Phase 2 — `type_info` (reflect) + `field_type`
|
||||
### Phase 2 — `field_type` (done) + `type_info` (reflect → value, pending)
|
||||
| Step | Commit | What | Files |
|
||||
|---|---|---|---|
|
||||
| 2.0 | xfail | reflect a struct/tuple → read variant/field names + **types** (`field_type($T,i)`). Red. | `examples/06xx-*` |
|
||||
| 2.1 | green | implement `type_info`/`field_type` over the type table (reuse the `field_count`/`field_name` reflection path). | `src/ir/interp.zig` |
|
||||
| 2.0 | xfail | reflect a struct/tuple/tagged-union → read field/variant names + **types** (`field_type($T,i)`). Red. | `examples/0616-*` |
|
||||
| 2.1 | green | **DONE.** `field_type($T, i) -> Type` over the type table (`fieldTypeOf` in `generic.zig`): struct field / tagged-union+union variant payload / tuple element / array+vector element; OOB + memberless → loud poison. Folds at lower time, composes in `type_eq`/`type_name`. | `src/ir/lower/generic.zig` |
|
||||
| 2.2 | xfail→green | **PENDING.** `type_info($T) -> TypeInfo` — reflect a type into a `TypeInfo` *value* (the inverse of reify). Needs the `TypeInfo` data model widened (struct/tuple variants beyond `` `enum ``) AND comptime construction of a `[]EnumVariant`-style value (slice of structs holding strings + `Type` tags) read from the type table. Still bails loudly in `call.zig:tryLowerReflectionCall`. Larger than 2.1 — its own step. | `library/modules/std/meta.sx`, `src/ir/interp.zig` / `call.zig` |
|
||||
|
||||
### Phase 3 — `make_enum` + `RecvResult`/`TryResult` (sx lib)
|
||||
| Step | Commit | What | Files |
|
||||
@@ -130,6 +131,8 @@ Examples: `06xx` (comptime, deterministic), `11xx` (diagnostics for loud failure
|
||||
shared `buildEnumInfo` path; `examples/0614` green; Contract 2 confirmed)
|
||||
- [x] Phase 1 — type-fn identity (`Box :: ($T)->Type { reify(...) }` memoizes by
|
||||
mangled name; `Box(i64)` at two sites is one type; `examples/0615` green)
|
||||
- [~] Phase 2 — `field_type` DONE (`examples/0616` green); `type_info` (reflect → a
|
||||
`TypeInfo` value) PENDING as step 2.2
|
||||
- [ ] Phase 2 — `type_info` + `field_type`
|
||||
- [ ] Phase 3 — `make_enum` + `RecvResult`/`TryResult`
|
||||
- [ ] Phase 4 — reference self-reference
|
||||
|
||||
Reference in New Issue
Block a user