From 3731a200c362085971922917ef79774cb8f50331 Mon Sep 17 00:00:00 2001 From: agra Date: Sat, 30 May 2026 00:54:07 +0300 Subject: [PATCH] ir: convert remaining s64 var-init fallbacks + fix stale s64 sentinel checks Var-init placeholders that could leak when a lookup failed now init to .unresolved: struct field-not-found (lowerFieldAccess/store), match payload variant-not-found, deref-of-non-pointer pointee, array-literal element type. Also fixes checks that used .s64 as the "resolution failed" sentinel and broke when the producing functions started returning .unresolved instead: - array-literal: `resolved != .s64` -> `!= .unresolved`. - parameterized type-alias registration and pack-fn return-type resolution: `!= .s64` -> `!= .unresolved` (also fixes a latent bug where a genuine `s64` alias / `-> s64` return was treated as a failure). - the variadic Any-boxing refinement (infer, then upgrade via getRefType) now triggers on .unresolved, not .s64, matching the honest inferExprType. Every silent s64 fallback in the codebase is now gone; only genuine s64<->name mappings and the defined int-literal/tag-width defaults remain. 236 + unit green. --- src/ir/lower.zig | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ir/lower.zig b/src/ir/lower.zig index f900b8a..ee22296 100644 --- a/src/ir/lower.zig +++ b/src/ir/lower.zig @@ -665,7 +665,7 @@ pub const Lowering = struct { // under the alias name so `Vec4` in expression // position can `const_type()`. const result_ty = type_bridge.resolveAstType(cd.value, &self.module.types); - if (result_ty != .void and result_ty != .s64) { + if (result_ty != .void and result_ty != .unresolved) { self.type_alias_map.put(cd.name, result_ty) catch {}; } } @@ -1904,7 +1904,7 @@ pub const Lowering = struct { const struct_fields = self.getStructFields(obj_ty); var field_idx: u32 = 0; - var field_ty: TypeId = .s64; + var field_ty: TypeId = .unresolved; for (struct_fields, 0..) |f, i| { if (f.name == field_name_id) { field_idx = @intCast(i); @@ -3636,7 +3636,7 @@ pub const Lowering = struct { } else { // Resolve actual variant index and payload type from the subject's type var variant_idx: u32 = @intCast(i); - var payload_ty: TypeId = .s64; + var payload_ty: TypeId = .unresolved; if (arm.pattern) |arm_pat| { const pat_name = switch (arm_pat.data) { .enum_literal => |el| el.name, @@ -4664,14 +4664,14 @@ pub const Lowering = struct { defer elems.deinit(self.alloc); // Determine element type: explicit type_expr > target_type > inference - var elem_ty: TypeId = .s64; + var elem_ty: TypeId = .unresolved; var from_target = false; var is_vector = false; // First, check explicit type annotation on the literal (e.g. Vector(3,f32).[1,2,3]) if (al.type_expr) |te| { const resolved = self.resolveArrayLiteralType(te); - if (resolved != .s64) { + if (resolved != .unresolved) { if (!resolved.isBuiltin()) { const info = self.module.types.get(resolved); switch (info) { @@ -4965,7 +4965,7 @@ pub const Lowering = struct { const ptr = self.lowerExpr(de.operand); // Resolve pointee type from the pointer type const ptr_ty = self.inferExprType(de.operand); - var pointee_ty: TypeId = .s64; + var pointee_ty: TypeId = .unresolved; if (!ptr_ty.isBuiltin()) { const info = self.module.types.get(ptr_ty); if (info == .pointer) { @@ -7740,7 +7740,7 @@ pub const Lowering = struct { const field_name_id = self.module.types.internString(fa.field); const struct_fields = self.getStructFields(obj_ty); var field_idx: u32 = 0; - var field_ty: TypeId = .s64; + var field_ty: TypeId = .unresolved; for (struct_fields, 0..) |f, fi| { if (f.name == field_name_id) { field_idx = @intCast(fi); @@ -8191,7 +8191,7 @@ pub const Lowering = struct { var val = self.lowerExpr(arg); var source_ty = self.inferExprType(arg); // If AST-based inference falls back to .s64 but the lowered ref is a string/struct, use that - if (source_ty == .s64) { + if (source_ty == .unresolved) { const ref_ty = self.builder.getRefType(val); if (ref_ty == .string or ref_ty == .f32 or ref_ty == .f64 or ref_ty == .bool) { source_ty = ref_ty; @@ -8336,9 +8336,9 @@ pub const Lowering = struct { if (is_any) { var source_ty = self.inferExprType(c.args[fixed_count + i]); // If AST-based inference falls back to .s64 but the lowered ref has a richer type, use that - if (source_ty == .s64) { + if (source_ty == .unresolved) { const ref_ty = self.builder.getRefType(val); - if (ref_ty != .s64 and ref_ty != .void) source_ty = ref_ty; + if (ref_ty != .unresolved and ref_ty != .void) source_ty = ref_ty; } // Auto-unwrap optionals: box inner value if present, else box string "null" if (!source_ty.isBuiltin()) { @@ -8606,7 +8606,7 @@ pub const Lowering = struct { const ret_ty: TypeId = blk: { if (fd.return_type) |rt| { if (rt.data == .type_expr) { - if (type_bridge.resolveAstType(rt, &self.module.types) != .s64) { + if (type_bridge.resolveAstType(rt, &self.module.types) != .unresolved) { break :blk type_bridge.resolveAstType(rt, &self.module.types); } }