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.
This commit is contained in:
agra
2026-05-30 00:54:07 +03:00
parent f21b99c811
commit 3731a200c3

View File

@@ -665,7 +665,7 @@ pub const Lowering = struct {
// under the alias name so `Vec4` in expression
// position can `const_type(<vector tid>)`.
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);
}
}