comptime VM: flip Type to .type_value; migrate the .any refs that mean a Type value

type_resolver "Type" -> .type_value; const_type result + emitConstType now a
bare 8-byte i64 handle (not a 16-byte Any box). Migrated every .any ref meaning
"a Type value", leaving real boxed-Any refs:

- "Any holds a Type" meta-marker tag .any -> .type_value at all 4 consumers
  (reflectArgTypeId, reflectTypeId, the comptime type_tag-as-struct path,
  resolveTypeCategoryTags "type").
- reflection-builtin return types (type_of/declare/define) -> .type_value;
  runtime type_of(any) reads the tag as a .type_value (no re-box).
- expr_typer: a bare type-name expr is .type_value (backtick is_raw exempt).
- reflectionArgIsType accepts .type_value OR .any (a reflection arg can be a
  bare Type or a boxed Any).
- comptime switch_br accepts a .type_tag discriminant (type-category match).
- a bare function name in a Type slot -> const_type(its function type), not a
  func-ref (fixes a JIT crash); old string-box kept only for genuine Any params.
- field-not-found diagnostic + formatTypeName render .type_value as "Type".

Fixed 3 unit tests asserting the old .any behavior. 697/0 both gates (gate ON
bails cleanly to legacy since the VM doesn't model Type values yet) + 494 unit
tests. 24 snapshots regenerated (22 .ir const_type shape; 2 .stderr Any->Type).
This commit is contained in:
agra
2026-06-18 13:54:56 +03:00
parent 6844fb90e7
commit 94f60c51c0
37 changed files with 48941 additions and 48226 deletions

View File

@@ -1881,8 +1881,12 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
d.addFmt(.err, node.span, "'{s}' is not visible; #import the module that declares it", .{eff_fn_name});
break :blk self.emitError(eff_fn_name, node.span);
}
// Type-as-value: if target is Any (Type variable), produce a type name string
if (self.target_type == .any) {
// Type-as-value: a bare function name in a `Type` (`.type_value`)
// slot is its FUNCTION TYPE — `const_type(() -> R)` — so it prints
// / reflects as the real function type, not a func-ref. For a
// genuine `Any` param the old behavior is kept (a formatted
// type-name string boxed as Any).
if (self.target_type == .any or self.target_type == .type_value) {
const fd_any: ?*const ast.FnDecl = self.program_index.fn_ast_map.get(eff_fn_name) orelse fd_blk: {
switch (self.selectPlainCallableAuthor(id.name, self.current_source_file.?)) {
.func => |sf| break :fd_blk sf.decl,
@@ -1890,6 +1894,13 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
}
};
if (fd_any) |fd| {
if (self.target_type == .type_value) {
var param_ids = std.ArrayList(TypeId).empty;
defer param_ids.deinit(self.alloc);
for (fd.params) |p| param_ids.append(self.alloc, self.resolveParamType(&p)) catch {};
const fn_tid = self.module.types.functionType(param_ids.items, self.resolveReturnType(fd));
break :blk self.builder.constType(fn_tid);
}
const fn_type_str = self.formatFnTypeString(fd);
const sid = self.module.types.internString(fn_type_str);
const str = self.builder.constString(sid);