sema/ir: kill remaining s64 fallbacks (sema Type + getRefType)
- types.Type: add dedicated `unresolved` variant (mirrors ir.TypeId.unresolved) with eql/displayName arms; bridgeType maps it to TypeId.unresolved. - sema.inferExprType + signature/field resolution: every Type.fromTypeExpr / fromName / symbol lookup miss and call/field/index fallthrough now yields Type.unresolved instead of a fabricated s(64). A variadic `..xs: []T` slice element is taken from T, not a guessed "s32". Genuine literal defaults (int=>s64, float=>f32, .len=>s64) kept. - Builder.getRefType: an unlocatable ref (no active function / out-of-range) returns .unresolved, not .s64 -- this is the accurate type source the pack mono / binop / null-cmp fixes rely on, so it must not fabricate. 236 examples + unit tests (incl sema) green.
This commit is contained in:
35
src/sema.zig
35
src/sema.zig
@@ -136,11 +136,16 @@ pub const Analyzer = struct {
|
||||
var param_types = std.ArrayList(Type).empty;
|
||||
var has_variadic = false;
|
||||
for (fd.params) |param| {
|
||||
const pt = Type.fromTypeExpr(param.type_expr) orelse Type.s(64);
|
||||
const pt = Type.fromTypeExpr(param.type_expr) orelse Type.unresolved;
|
||||
if (param.is_variadic) {
|
||||
has_variadic = true;
|
||||
// Variadic param becomes a slice type
|
||||
const elem_name = if (param.type_expr.data == .type_expr) param.type_expr.data.type_expr.name else "s32";
|
||||
const elem_name = switch (param.type_expr.data) {
|
||||
.type_expr => |te| te.name,
|
||||
// `..xs: []T` — the element is T, not a guessed s32.
|
||||
.slice_type_expr => |st| if (st.element_type.data == .type_expr) st.element_type.data.type_expr.name else "<unresolved>",
|
||||
else => "<unresolved>",
|
||||
};
|
||||
try param_types.append(self.allocator, .{ .slice_type = .{ .element_name = elem_name } });
|
||||
} else {
|
||||
try param_types.append(self.allocator, pt);
|
||||
@@ -169,7 +174,7 @@ pub const Analyzer = struct {
|
||||
const lam = cd.value.data.lambda;
|
||||
var param_types = std.ArrayList(Type).empty;
|
||||
for (lam.params) |param| {
|
||||
const pt = Type.fromTypeExpr(param.type_expr) orelse Type.s(64);
|
||||
const pt = Type.fromTypeExpr(param.type_expr) orelse Type.unresolved;
|
||||
try param_types.append(self.allocator, pt);
|
||||
}
|
||||
const ret = if (lam.return_type) |rt|
|
||||
@@ -222,7 +227,7 @@ pub const Analyzer = struct {
|
||||
}
|
||||
if (i < sd.field_names.len) {
|
||||
try all_names.append(self.allocator, sd.field_names[i]);
|
||||
const resolved = Type.fromTypeExpr(sd.field_types[i]) orelse Type.s(64);
|
||||
const resolved = Type.fromTypeExpr(sd.field_types[i]) orelse Type.unresolved;
|
||||
try all_types.append(self.allocator, resolved);
|
||||
}
|
||||
}
|
||||
@@ -233,7 +238,7 @@ pub const Analyzer = struct {
|
||||
} else {
|
||||
var field_types = std.ArrayList(Type).empty;
|
||||
for (sd.field_types) |ft| {
|
||||
const resolved = Type.fromTypeExpr(ft) orelse Type.s(64);
|
||||
const resolved = Type.fromTypeExpr(ft) orelse Type.unresolved;
|
||||
try field_types.append(self.allocator, resolved);
|
||||
}
|
||||
try self.struct_types.put(sd.name, .{
|
||||
@@ -369,11 +374,11 @@ pub const Analyzer = struct {
|
||||
j -= 1;
|
||||
const sym = self.symbols.items[indices.items[j]];
|
||||
if (sym.scope_depth <= self.scope_depth) {
|
||||
return sym.ty orelse Type.s(64);
|
||||
return sym.ty orelse Type.unresolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Type.s(64);
|
||||
return Type.unresolved;
|
||||
},
|
||||
.if_expr => |ie| {
|
||||
return self.inferExprType(ie.then_branch);
|
||||
@@ -391,7 +396,7 @@ pub const Analyzer = struct {
|
||||
return .void_type;
|
||||
},
|
||||
.call => |call_node| {
|
||||
const callee_name = self.resolveCalleeName(call_node) orelse return Type.s(64);
|
||||
const callee_name = self.resolveCalleeName(call_node) orelse return Type.unresolved;
|
||||
// Check fn_signatures registry
|
||||
if (self.fn_signatures.get(callee_name)) |sig| {
|
||||
return sig.return_type;
|
||||
@@ -405,7 +410,7 @@ pub const Analyzer = struct {
|
||||
if (call_node.args.len > 0) return self.inferExprType(call_node.args[0]);
|
||||
return .f32;
|
||||
}
|
||||
return Type.s(64);
|
||||
return Type.unresolved;
|
||||
},
|
||||
.unary_op => |unop| {
|
||||
return self.inferExprType(unop.operand);
|
||||
@@ -426,17 +431,17 @@ pub const Analyzer = struct {
|
||||
}
|
||||
}
|
||||
if (obj_ty.isArray()) {
|
||||
return Type.fromName(obj_ty.array_type.element_name) orelse Type.s(64);
|
||||
return Type.fromName(obj_ty.array_type.element_name) orelse Type.unresolved;
|
||||
}
|
||||
return Type.s(64);
|
||||
return Type.unresolved;
|
||||
},
|
||||
.index_expr => |ie| {
|
||||
const obj_ty = self.inferExprType(ie.object);
|
||||
if (obj_ty == .string_type) return Type.u(8);
|
||||
if (obj_ty.isArray()) {
|
||||
return Type.fromName(obj_ty.array_type.element_name) orelse Type.s(64);
|
||||
return Type.fromName(obj_ty.array_type.element_name) orelse Type.unresolved;
|
||||
}
|
||||
return Type.s(64);
|
||||
return Type.unresolved;
|
||||
},
|
||||
.slice_expr => |se| {
|
||||
const obj_ty = self.inferExprType(se.object);
|
||||
@@ -677,7 +682,7 @@ pub const Analyzer = struct {
|
||||
{
|
||||
var param_types = std.ArrayList(Type).empty;
|
||||
for (fd.params) |param| {
|
||||
const pt = Type.fromTypeExpr(param.type_expr) orelse Type.s(64);
|
||||
const pt = Type.fromTypeExpr(param.type_expr) orelse Type.unresolved;
|
||||
try param_types.append(self.allocator, pt);
|
||||
}
|
||||
try self.fn_signatures.put(fd.name, .{
|
||||
@@ -1026,7 +1031,7 @@ pub const Analyzer = struct {
|
||||
fn inferFnReturnType(self: *Analyzer, params: []const ast.Param, body: *const Node) ?Type {
|
||||
self.pushScope() catch return null;
|
||||
for (params) |param| {
|
||||
const pt = Type.fromTypeExpr(param.type_expr) orelse Type.s(64);
|
||||
const pt = Type.fromTypeExpr(param.type_expr) orelse Type.unresolved;
|
||||
self.addSymbol(param.name, .param, pt, param.name_span) catch {};
|
||||
}
|
||||
// Arrow fn_decl wraps body in block{[expr]} — unwrap to inner expression
|
||||
|
||||
Reference in New Issue
Block a user