authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-08-21 12:48:54+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-08-21 16:24:57+01:00
log7bbbbf8ffa3fa9be085cef8e8237cd94ce342483
treeae66c4b5c90ec6593a96bda1c645b2248c59b448
parent8fc15f188c0deb1b0e2847297e535823eca1d2e8

compiler: fix losing ZIR instructions in main_struct_inst fields


2 files changed, 36 insertions(+), 7 deletions(-)

lib/std/zig/Zir.zig+19-1
......@@ -3548,7 +3548,7 @@ pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
35483548 const datas = zir.instructions.items(.data);
35493549 switch (tags[@intFromEnum(decl_inst)]) {
35503550 // Functions are allowed and yield no iterations.
3551 // There is one case matching this in the extended instruction set below.
3551 // This is because they are returned by `findDecls`.
35523552 .func, .func_inferred, .func_fancy => return .{
35533553 .extra_index = undefined,
35543554 .decls_remaining = 0,
......@@ -3558,6 +3558,13 @@ pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
35583558 .extended => {
35593559 const extended = datas[@intFromEnum(decl_inst)].extended;
35603560 switch (extended.opcode) {
3561 // Reifications are allowed and yield no iterations.
3562 // This is because they are returned by `findDecls`.
3563 .reify => return .{
3564 .extra_index = undefined,
3565 .decls_remaining = 0,
3566 .zir = zir,
3567 },
35613568 .struct_decl => {
35623569 const small: Inst.StructDecl.Small = @bitCast(extended.small);
35633570 var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.StructDecl).Struct.fields.len);
......@@ -3690,6 +3697,17 @@ pub fn findDecls(zir: Zir, gpa: Allocator, list: *std.ArrayListUnmanaged(Inst.In
36903697 if (bodies.addrspace_body) |b| try zir.findDeclsBody(gpa, list, &found_defers, b);
36913698}
36923699
3700/// Like `findDecls`, but only considers the `main_struct_inst` instruction. This may return more than
3701/// just that instruction because it will also traverse fields.
3702pub fn findDeclsRoot(zir: Zir, gpa: Allocator, list: *std.ArrayListUnmanaged(Inst.Index)) !void {
3703 list.clearRetainingCapacity();
3704
3705 var found_defers: std.AutoHashMapUnmanaged(u32, void) = .{};
3706 defer found_defers.deinit(gpa);
3707
3708 try zir.findDeclsInner(gpa, list, &found_defers, .main_struct_inst);
3709}
3710
36933711fn findDeclsInner(
36943712 zir: Zir,
36953713 gpa: Allocator,
src/Zcu.zig+17-6
......@@ -2554,18 +2554,29 @@ pub fn mapOldZirToNew(
25542554 var match_stack: std.ArrayListUnmanaged(MatchedZirDecl) = .{};
25552555 defer match_stack.deinit(gpa);
25562556
2557 // Main struct inst is always matched
2558 try match_stack.append(gpa, .{
2559 .old_inst = .main_struct_inst,
2560 .new_inst = .main_struct_inst,
2561 });
2562
25632557 // Used as temporary buffers for namespace declaration instructions
25642558 var old_decls: std.ArrayListUnmanaged(Zir.Inst.Index) = .{};
25652559 defer old_decls.deinit(gpa);
25662560 var new_decls: std.ArrayListUnmanaged(Zir.Inst.Index) = .{};
25672561 defer new_decls.deinit(gpa);
25682562
2563 // Map the main struct inst (and anything in its fields)
2564 {
2565 try old_zir.findDeclsRoot(gpa, &old_decls);
2566 try new_zir.findDeclsRoot(gpa, &new_decls);
2567
2568 assert(old_decls.items[0] == .main_struct_inst);
2569 assert(new_decls.items[0] == .main_struct_inst);
2570
2571 // We don't have any smart way of matching up these type declarations, so we always
2572 // correlate them based on source order.
2573 const n = @min(old_decls.items.len, new_decls.items.len);
2574 try match_stack.ensureUnusedCapacity(gpa, n);
2575 for (old_decls.items[0..n], new_decls.items[0..n]) |old_inst, new_inst| {
2576 match_stack.appendAssumeCapacity(.{ .old_inst = old_inst, .new_inst = new_inst });
2577 }
2578 }
2579
25692580 while (match_stack.popOrNull()) |match_item| {
25702581 // Match the namespace declaration itself
25712582 try inst_map.put(gpa, match_item.old_inst, match_item.new_inst);