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:
agra
2026-06-16 19:06:57 +03:00
parent bd139dc09c
commit ac8c689518
7 changed files with 107 additions and 17 deletions

View File

@@ -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