sema_test: show human-readable AIR tag names in mismatch diagnostics
Export air_tag_name from verbose_air.zig to convert AIR tag u8 values to their string names (e.g. "arg", "ret", "block"). Use it in sema_test.zig error messages so mismatches show readable names instead of raw numbers. Also add refKindStr to distinguish ip/inst refs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -298,3 +298,10 @@ fn zigCompileAirImpl(
|
||||
}
|
||||
return .{ .items = allocated.ptr, .len = len, .callback_count = collector.callback_count };
|
||||
}
|
||||
|
||||
/// Return the tag name for an AIR instruction tag (u8).
|
||||
/// Exported for use by stage0 sema tests.
|
||||
export fn air_tag_name(tag_val: u8) [*:0]const u8 {
|
||||
const e: Air.Inst.Tag = @enumFromInt(tag_val);
|
||||
return @tagName(e);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,8 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
char* name; // function FQN (owned, null-terminated)
|
||||
InternPoolIndex func_ip; // IP index of function value (for name resolution)
|
||||
InternPoolIndex
|
||||
func_ip; // IP index of function value (for name resolution)
|
||||
Air air; // per-function Air (owns its arrays)
|
||||
} SemaFuncAir;
|
||||
|
||||
|
||||
@@ -309,6 +309,17 @@ fn cToOpt(comptime T: type, ptr: [*c]T) ?[*]const T {
|
||||
return if (ptr == null) null else @ptrCast(ptr);
|
||||
}
|
||||
|
||||
fn airTagNameSlice(tag_val: u8) []const u8 {
|
||||
return std.mem.span(air_tag_name(tag_val));
|
||||
}
|
||||
extern fn air_tag_name(tag: u8) [*:0]const u8;
|
||||
|
||||
fn refKindStr(ref: u32) []const u8 {
|
||||
if (ref == 0xFFFFFFFF) return "none";
|
||||
if ((ref >> 31) != 0) return "inst";
|
||||
return "ip";
|
||||
}
|
||||
|
||||
/// Canonicalize an AIR Ref for comparison. Inst refs (bit 31 set)
|
||||
/// and the special NONE sentinel are returned as-is. IP refs (bit 31
|
||||
/// clear) are assigned a sequential canonical ID via the map, in
|
||||
@@ -535,12 +546,12 @@ fn airCompareOne(name: []const u8, zig_air: *const c.Air, c_air: *const c.Air) !
|
||||
std.debug.print("'{s}': inst_len mismatch: zig={d} c={d}\n", .{ name, zig_air.inst_len, c_air.inst_len });
|
||||
if (cToOpt(u8, zig_air.inst_tags)) |zt| {
|
||||
std.debug.print(" zig tags:", .{});
|
||||
for (0..zig_air.inst_len) |j| std.debug.print(" {d}", .{zt[j]});
|
||||
for (0..zig_air.inst_len) |j| std.debug.print(" {s}", .{airTagNameSlice(zt[j])});
|
||||
std.debug.print("\n", .{});
|
||||
}
|
||||
if (cToOpt(u8, c_air.inst_tags)) |ct| {
|
||||
std.debug.print(" c tags:", .{});
|
||||
for (0..c_air.inst_len) |j| std.debug.print(" {d}", .{ct[j]});
|
||||
for (0..c_air.inst_len) |j| std.debug.print(" {s}", .{airTagNameSlice(ct[j])});
|
||||
std.debug.print("\n", .{});
|
||||
}
|
||||
return error.AirMismatch;
|
||||
@@ -568,7 +579,7 @@ fn airCompareOne(name: []const u8, zig_air: *const c.Air, c_air: *const c.Air) !
|
||||
if (!std.mem.eql(u8, zig_tags[0..inst_len], c_tags[0..inst_len])) {
|
||||
std.debug.print("'{s}': tags mismatch (inst_len={d}):", .{ name, inst_len });
|
||||
for (0..inst_len) |j| {
|
||||
std.debug.print(" zig[{d}]={d} c[{d}]={d}", .{ j, zig_tags[j], j, c_tags[j] });
|
||||
std.debug.print(" zig[{d}]={d}({s}) c[{d}]={d}({s})", .{ j, zig_tags[j], airTagNameSlice(zig_tags[j]), j, c_tags[j], airTagNameSlice(c_tags[j]) });
|
||||
}
|
||||
std.debug.print("\n", .{});
|
||||
return error.AirMismatch;
|
||||
@@ -615,13 +626,13 @@ fn airCompareOne(name: []const u8, zig_air: *const c.Air, c_air: *const c.Air) !
|
||||
const zig_canon = canonicalizeRef(zig_word, &zig_ref_map, &next_zig_id);
|
||||
const c_canon = canonicalizeRef(c_word, &c_ref_map, &next_c_id);
|
||||
if (zig_canon != c_canon) {
|
||||
std.debug.print("'{s}': datas ref mismatch at inst[{d}] slot {d}: zig=0x{x} c=0x{x} (canon: zig={d} c={d}) (tag={d})\n", .{ name, j, slot, zig_word, c_word, zig_canon, c_canon, tag_val });
|
||||
std.debug.print("'{s}': datas ref mismatch at inst[{d}] slot {d}: zig=0x{x}[{s}] c=0x{x}[{s}] (canon: zig={d} c={d}) (tag={s})\n", .{ name, j, slot, zig_word, refKindStr(zig_word), c_word, refKindStr(c_word), zig_canon, c_canon, airTagNameSlice(tag_val) });
|
||||
return error.AirMismatch;
|
||||
}
|
||||
} else {
|
||||
// Non-ref field — compare directly.
|
||||
if (zig_word != c_word) {
|
||||
std.debug.print("'{s}': datas mismatch at inst[{d}] slot {d}: zig=0x{x} c=0x{x} (tag={d})\n", .{ name, j, slot, zig_word, c_word, tag_val });
|
||||
std.debug.print("'{s}': datas mismatch at inst[{d}] slot {d}: zig=0x{x} c=0x{x} (tag={s})\n", .{ name, j, slot, zig_word, c_word, airTagNameSlice(tag_val) });
|
||||
return error.AirMismatch;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user