Skip to content

Commit 7bbbbf8

Browse files
committed
compiler: fix losing ZIR instructions in main_struct_inst fields
1 parent 8fc15f1 commit 7bbbbf8

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

lib/std/zig/Zir.zig

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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.
3702+
pub 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+
36933711
fn findDeclsInner(
36943712
zir: Zir,
36953713
gpa: Allocator,

src/Zcu.zig

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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);

0 commit comments

Comments
 (0)