green(reify): type-fn bodies comptime-evaluated; reify fully removed from the compiler

Second slice of the re-architecture — the compiler now has ZERO type-
construction code beyond declare/define.

- instantiateTypeFunction: a type-fn body returning a computed Type (a call
  to a non-generic, bodied, Type-returning fn) is comptime-evaluated with the
  type bindings active, then renamed to the mangled instantiation name for
  identity (renameNominalType). Replaces the old reify-call pattern-matching.
- DELETED: reifyType (lower/nominal.zig), findReturnReifyCall (lower/generic.zig),
  and the stale inline-position reify gate in resolveTypeCallWithBindings.
- evalComptimeType (was evalComptimeTypeNamed): pure eval, no rename; the
  type-fn caller renames explicitly. renameReifiedType → renameNominalType.
- The TYPE NAME now travels in the data: EnumInfo gains `name`, and define()
  names the slot from it (the compiler derives no name from a binding LHS).
  examples/0614/0615 carry `name = "..."`; RecvResult/TryResult set it too.
- field_type stays a reflection #builtin (reads a type); only construction
  moved out. All reify mentions stripped from compiler source.

examples 0614/0615/0617 run on the floor. Full suite green (673).
This commit is contained in:
agra
2026-06-16 21:03:16 +03:00
parent 442a70b8c9
commit 8ae655687a
11 changed files with 112 additions and 194 deletions

View File

@@ -44,8 +44,8 @@ const isPackFn = Lowering.isPackFn;
/// Anything starting with `Java_` is a JNI native method that Android's
/// runtime resolves by name mangling — same rule.
/// True when `fd` declares a `-> Type` return — the signal that a non-generic
/// call to it (`E :: f(...)`) should be comptime-evaluated to mint a type (the
/// REIFY floor). Matches a bare `Type` type-expr return only.
/// call to it (`E :: f(...)`) should be comptime-evaluated to mint a type.
/// Matches a bare `Type` type-expr return only.
fn fnReturnsTypeValue(fd: *const ast.FnDecl) bool {
const rt = fd.return_type orelse return false;
return rt.data == .type_expr and std.mem.eql(u8, rt.data.type_expr.name, "Type");
@@ -660,16 +660,18 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void {
else => "",
};
// `E :: f(...)` where `f` is a NON-generic fn returning
// `Type` (e.g. the sx `reify` / `make_enum`): comptime-
// evaluate the call — `declare`/`define` reached inside it
// mint the type — and bind `E` as an alias to the result.
// The compiler has ZERO `reify` knowledge: any Type-returning
// value-fn flows here. Generic type-fns (`$T`) are minted by
// `Type` (a comptime type constructor): comptime-evaluate the
// call — `declare`/`define` reached inside it mint the type —
// and bind `E` as an alias to the result. No hardcoded
// constructor names: any Type-returning value-fn flows here.
// Generic type-fns (`$T`) are minted by
// `instantiateTypeFunction` below. Poison on failure so
// `E.x` gets a clean follow-on, never a silent default.
if (self.program_index.fn_ast_map.get(callee_name)) |fd| {
if (fd.type_params.len == 0 and fnReturnsTypeValue(fd)) {
const tid = self.evalComptimeTypeNamed(cd.value, cd.name) orelse TypeId.unresolved;
// The minted type's NAME comes from its `TypeInfo`
// (via `define`), not the binding LHS — no rename.
const tid = self.evalComptimeType(cd.value) orelse TypeId.unresolved;
self.putTypeAlias(self.current_source_file, cd.name, tid);
continue;
}