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:
@@ -130,23 +130,15 @@ pub const Ops = struct {
|
||||
}
|
||||
|
||||
pub fn emitConstType(self: Ops, tid: TypeId) void {
|
||||
// Type values are Any-shaped pairs:
|
||||
// { tag = .any.index() (the meta-marker),
|
||||
// value = tid.index() }
|
||||
// Lets storage in Any slots, struct fields,
|
||||
// `Type`-typed vars, and slice elements all round-
|
||||
// trip through the standard Any infrastructure.
|
||||
// `case type:` in `any_to_string` matches on
|
||||
// tag == `.any.index()`. Runtime `type_name(t)`
|
||||
// extracts the value field and indexes into the
|
||||
// type-name lookup table.
|
||||
const any_ty = self.e.getAnyStructType();
|
||||
const tag = c.LLVMConstInt(self.e.cached_i64, TypeId.any.index(), 0);
|
||||
// A Type value is an 8-byte handle: a bare i64 carrying `tid.index()`
|
||||
// (the `.type_value` builtin TypeId), distinct from the 16-byte boxed
|
||||
// `.any`. Flowing a Type into an `Any` slot boxes it via the standard
|
||||
// box-any coercion (`{ tag = .any.index(), value = tid }`); `case type:`
|
||||
// in `any_to_string` then matches tag == `.any.index()`, and runtime
|
||||
// `type_name(t)` reads the TypeId through `reflectArgTypeId` (`.bare`
|
||||
// when the arg is `.type_value`, `.boxed` when it is an Any).
|
||||
const val = c.LLVMConstInt(self.e.cached_i64, tid.index(), 0);
|
||||
var result = c.LLVMGetUndef(any_ty);
|
||||
result = c.LLVMBuildInsertValue(self.e.builder, result, tag, 0, "ct.tag");
|
||||
result = c.LLVMBuildInsertValue(self.e.builder, result, val, 1, "ct.val");
|
||||
self.e.mapRef(result);
|
||||
self.e.mapRef(val);
|
||||
}
|
||||
|
||||
// ── Arithmetic ─────────────────────────────────────────
|
||||
@@ -1341,11 +1333,11 @@ pub const Ops = struct {
|
||||
/// Resolve the `TypeId` (as a runtime `i64`) that a dynamic
|
||||
/// `type_name` / `type_is_unsigned` must operate on. A reflection
|
||||
/// builtin reads an `Any`'s runtime TYPE-TAG, never its raw payload:
|
||||
/// - `.bare`: a `Type` value already lowered to a bare i64 `TypeId`
|
||||
/// index (an unboxed direct call site) → the value itself.
|
||||
/// - `.bare`: a `Type` value (a `.type_value` arg) — a bare i64 `TypeId`
|
||||
/// index (e.g. `type_of(x)` directly) → the value itself.
|
||||
/// - `.boxed`: an `Any` aggregate `{ tag, value }`. When the tag is
|
||||
/// `.any`, the box carries a *Type value* (the `{ .any, tid }` shape
|
||||
/// `const_type` / `type_of` produce) → the TypeId is the payload.
|
||||
/// `.type_value`, the box carries a *Type value* (a `Type` boxed into an
|
||||
/// `Any`, `{ .type_value, tid }`) → the TypeId is the payload.
|
||||
/// Otherwise the box carries a *runtime value* whose type IS the tag
|
||||
/// → use the tag as the TypeId. This is what makes `type_name(av)`
|
||||
/// for `av : Any = 6` report `i64` (the held value's type), while
|
||||
@@ -1360,8 +1352,8 @@ pub const Ops = struct {
|
||||
.boxed => blk: {
|
||||
const tag = c.LLVMBuildExtractValue(self.e.builder, arg_val, 0, "refl.tag");
|
||||
const payload = c.LLVMBuildExtractValue(self.e.builder, arg_val, 1, "refl.val");
|
||||
const any_tag = c.LLVMConstInt(self.e.cached_i64, @intCast(TypeId.any.index()), 0);
|
||||
const holds_type = c.LLVMBuildICmp(self.e.builder, c.LLVMIntEQ, tag, any_tag, "refl.istype");
|
||||
const type_tag = c.LLVMConstInt(self.e.cached_i64, @intCast(TypeId.type_value.index()), 0);
|
||||
const holds_type = c.LLVMBuildICmp(self.e.builder, c.LLVMIntEQ, tag, type_tag, "refl.istype");
|
||||
break :blk c.LLVMBuildSelect(self.e.builder, holds_type, payload, tag, "refl.tid");
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user