astgen: blockExpr rvalue, local_ptr rvalue, array_mult

- blockExpr: call rvalue on void result for unlabeled blocks, matching
  upstream AstGen.zig:2431. This was causing a missing STORE_NODE when
  empty blocks like {} were used as struct field values with pointer RL.
- identifierExpr: call rvalueNoCoercePreRef after LOAD in local_ptr case,
  matching upstream AstGen.zig:8453-8454.
- Implement AST_NODE_ARRAY_MULT (** operator) with ArrayMul payload,
  matching upstream AstGen.zig:774-785.
- Enable parser_test.zig and astgen_test.zig corpus tests.
- Enable combined corpus test (all 5 files pass).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 10:19:36 +00:00
parent 28ee5d40b7
commit b10557306d
2 changed files with 46 additions and 7 deletions

View File

@@ -256,6 +256,32 @@ fn expectEqualZir(gpa: Allocator, ref: Zir, got: c.Zir) !void {
@as(i32, @intCast(got_counts[t])) - @as(i32, @intCast(ref_counts[t])),
});
}
// Find first tag divergence.
const min_len = @min(ref_len, got.inst_len);
for (0..min_len) |i| {
const ref_tag: u8 = @intFromEnum(ref_tags[i]);
const got_tag: u8 = @intCast(got.inst_tags[i]);
if (ref_tag != got_tag) {
std.debug.print("first divergence at [{d}]: ref_tag={d} got_tag={d}\n", .{ i, ref_tag, got_tag });
// Show ref instruction data for this position.
const rd = ref_datas[i];
std.debug.print(" ref pl_node: src_node={d} payload={d}\n", .{
rd.pl_node.src_node, rd.pl_node.payload_index,
});
// Scan for nearest declaration.
var j: usize = i;
while (j > 0) {
j -= 1;
if (ref_tags[j] == .declaration) {
std.debug.print(" nearest decl at [{d}]: src_node={d}\n", .{
j, ref_datas[j].declaration.src_node,
});
break;
}
}
break;
}
}
return error.TestExpectedEqual;
}
@@ -817,9 +843,6 @@ test "astgen: corpus tokenizer_test.zig" {
}
test "astgen: corpus parser_test.zig" {
// TODO: 10+ extra data mismatches (ref=48 got=32, bit 4 = propagate_error_trace)
// in call instruction flags — ctx propagation differs from upstream.
if (true) return error.SkipZigTest;
const gpa = std.testing.allocator;
try corpusCheck(gpa, @embedFile("parser_test.zig"));
}
@@ -857,7 +880,7 @@ test "astgen: struct init typed" {
}
test "astgen: corpus" {
if (true) return error.SkipZigTest; // TODO: parser_test.zig fails
// All individual corpus tests now pass.
const gpa = std.testing.allocator;
var any_fail = false;