ir: type-resolution fallbacks return .unresolved, not .s64 (batch A)

resolveFieldType (field-not-found, tuple OOB/parse-fail), getElementType
(element-of-a-non-collection), resolveArrayLiteralType, and the named-type
lookup in the type-call resolver all guessed .s64 when resolution failed --
the issue-0042 silent-default class. Return .unresolved so a genuine
resolution failure surfaces (and trips the sizeOf/toLLVMType panic) instead
of fabricating an 8-byte int. Genuine results (.len => .s64) unchanged.
This commit is contained in:
agra
2026-05-29 22:53:53 +03:00
parent 99baabd93f
commit 8681b72b47

View File

@@ -4094,17 +4094,17 @@ pub const Lowering = struct {
} }
// Try numeric index // Try numeric index
const idx = std.fmt.parseInt(usize, field, 10) catch { const idx = std.fmt.parseInt(usize, field, 10) catch {
return .s64; return .unresolved;
}; };
if (idx < tuple.fields.len) return tuple.fields[idx]; if (idx < tuple.fields.len) return tuple.fields[idx];
return .s64; return .unresolved;
} }
} }
const struct_fields = self.getStructFields(ty); const struct_fields = self.getStructFields(ty);
for (struct_fields) |f| { for (struct_fields) |f| {
if (f.name == field_name_id) return f.ty; if (f.name == field_name_id) return f.ty;
} }
return .s64; return .unresolved;
} }
fn lowerFieldAccess(self: *Lowering, fa: *const ast.FieldAccess, span: ast.Span) Ref { fn lowerFieldAccess(self: *Lowering, fa: *const ast.FieldAccess, span: ast.Span) Ref {
@@ -4720,7 +4720,7 @@ pub const Lowering = struct {
const callee_name = switch (cl.callee.data) { const callee_name = switch (cl.callee.data) {
.identifier => |id| id.name, .identifier => |id| id.name,
.field_access => |fa| fa.field, .field_access => |fa| fa.field,
else => return .s64, else => return .unresolved,
}; };
if (std.mem.eql(u8, callee_name, "Vector")) { if (std.mem.eql(u8, callee_name, "Vector")) {
if (cl.args.len == 2) { if (cl.args.len == 2) {
@@ -4736,20 +4736,20 @@ pub const Lowering = struct {
if (self.struct_template_map.getPtr(callee_name)) |tmpl| { if (self.struct_template_map.getPtr(callee_name)) |tmpl| {
return self.instantiateGenericStruct(tmpl, cl.args); return self.instantiateGenericStruct(tmpl, cl.args);
} }
return .s64; return .unresolved;
}, },
.parameterized_type_expr => |pt| return self.resolveParameterizedWithBindings(&pt), .parameterized_type_expr => |pt| return self.resolveParameterizedWithBindings(&pt),
.identifier => |id| { .identifier => |id| {
const name_id = self.module.types.internString(id.name); const name_id = self.module.types.internString(id.name);
return self.module.types.findByName(name_id) orelse .s64; return self.module.types.findByName(name_id) orelse .unresolved;
}, },
.type_expr => return type_bridge.resolveAstType(te, &self.module.types), .type_expr => return type_bridge.resolveAstType(te, &self.module.types),
.field_access => |fa| { .field_access => |fa| {
// Module.Type — try to resolve the field as a type name // Module.Type — try to resolve the field as a type name
const name_id = self.module.types.internString(fa.field); const name_id = self.module.types.internString(fa.field);
return self.module.types.findByName(name_id) orelse .s64; return self.module.types.findByName(name_id) orelse .unresolved;
}, },
else => return .s64, else => return .unresolved,
} }
} }
@@ -11118,7 +11118,7 @@ pub const Lowering = struct {
} }
// Try as a named type // Try as a named type
const name_id = self.module.types.internString(callee_name); const name_id = self.module.types.internString(callee_name);
return self.module.types.findByName(name_id) orelse .s64; return self.module.types.findByName(name_id) orelse .unresolved;
} }
/// Resolve a parameterized type expr, substituting bindings for type/value params. /// Resolve a parameterized type expr, substituting bindings for type/value params.
@@ -13979,17 +13979,19 @@ pub const Lowering = struct {
return null; return null;
} }
/// Get the element type for a slice/array/string type. Returns .s64 for unknown types. /// Get the element type for a slice/array/string type. A non-collection
/// type has no element type — return `.unresolved` (asking for it is a bug)
/// rather than a plausible `.s64`.
fn getElementType(self: *Lowering, ty: TypeId) TypeId { fn getElementType(self: *Lowering, ty: TypeId) TypeId {
if (ty == .string) return .u8; if (ty == .string) return .u8;
if (ty.isBuiltin()) return .s64; if (ty.isBuiltin()) return .unresolved;
const info = self.module.types.get(ty); const info = self.module.types.get(ty);
return switch (info) { return switch (info) {
.slice => |s| s.element, .slice => |s| s.element,
.array => |a| a.element, .array => |a| a.element,
.vector => |v| v.element, .vector => |v| v.element,
.many_pointer => |p| p.element, .many_pointer => |p| p.element,
else => .s64, else => .unresolved,
}; };
} }