mirror of
https://github.com/ziglang/zig.git
synced 2025-02-01 14:55:08 +00:00
compiler: fix losing ZIR instructions in main_struct_inst fields
This commit is contained in:
parent
8fc15f188c
commit
7bbbbf8ffa
@ -3548,7 +3548,7 @@ pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
|
||||
const datas = zir.instructions.items(.data);
|
||||
switch (tags[@intFromEnum(decl_inst)]) {
|
||||
// Functions are allowed and yield no iterations.
|
||||
// There is one case matching this in the extended instruction set below.
|
||||
// This is because they are returned by `findDecls`.
|
||||
.func, .func_inferred, .func_fancy => return .{
|
||||
.extra_index = undefined,
|
||||
.decls_remaining = 0,
|
||||
@ -3558,6 +3558,13 @@ pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
|
||||
.extended => {
|
||||
const extended = datas[@intFromEnum(decl_inst)].extended;
|
||||
switch (extended.opcode) {
|
||||
// Reifications are allowed and yield no iterations.
|
||||
// This is because they are returned by `findDecls`.
|
||||
.reify => return .{
|
||||
.extra_index = undefined,
|
||||
.decls_remaining = 0,
|
||||
.zir = zir,
|
||||
},
|
||||
.struct_decl => {
|
||||
const small: Inst.StructDecl.Small = @bitCast(extended.small);
|
||||
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
|
||||
if (bodies.addrspace_body) |b| try zir.findDeclsBody(gpa, list, &found_defers, b);
|
||||
}
|
||||
|
||||
/// Like `findDecls`, but only considers the `main_struct_inst` instruction. This may return more than
|
||||
/// just that instruction because it will also traverse fields.
|
||||
pub fn findDeclsRoot(zir: Zir, gpa: Allocator, list: *std.ArrayListUnmanaged(Inst.Index)) !void {
|
||||
list.clearRetainingCapacity();
|
||||
|
||||
var found_defers: std.AutoHashMapUnmanaged(u32, void) = .{};
|
||||
defer found_defers.deinit(gpa);
|
||||
|
||||
try zir.findDeclsInner(gpa, list, &found_defers, .main_struct_inst);
|
||||
}
|
||||
|
||||
fn findDeclsInner(
|
||||
zir: Zir,
|
||||
gpa: Allocator,
|
||||
|
23
src/Zcu.zig
23
src/Zcu.zig
@ -2554,18 +2554,29 @@ pub fn mapOldZirToNew(
|
||||
var match_stack: std.ArrayListUnmanaged(MatchedZirDecl) = .{};
|
||||
defer match_stack.deinit(gpa);
|
||||
|
||||
// Main struct inst is always matched
|
||||
try match_stack.append(gpa, .{
|
||||
.old_inst = .main_struct_inst,
|
||||
.new_inst = .main_struct_inst,
|
||||
});
|
||||
|
||||
// Used as temporary buffers for namespace declaration instructions
|
||||
var old_decls: std.ArrayListUnmanaged(Zir.Inst.Index) = .{};
|
||||
defer old_decls.deinit(gpa);
|
||||
var new_decls: std.ArrayListUnmanaged(Zir.Inst.Index) = .{};
|
||||
defer new_decls.deinit(gpa);
|
||||
|
||||
// Map the main struct inst (and anything in its fields)
|
||||
{
|
||||
try old_zir.findDeclsRoot(gpa, &old_decls);
|
||||
try new_zir.findDeclsRoot(gpa, &new_decls);
|
||||
|
||||
assert(old_decls.items[0] == .main_struct_inst);
|
||||
assert(new_decls.items[0] == .main_struct_inst);
|
||||
|
||||
// We don't have any smart way of matching up these type declarations, so we always
|
||||
// correlate them based on source order.
|
||||
const n = @min(old_decls.items.len, new_decls.items.len);
|
||||
try match_stack.ensureUnusedCapacity(gpa, n);
|
||||
for (old_decls.items[0..n], new_decls.items[0..n]) |old_inst, new_inst| {
|
||||
match_stack.appendAssumeCapacity(.{ .old_inst = old_inst, .new_inst = new_inst });
|
||||
}
|
||||
}
|
||||
|
||||
while (match_stack.popOrNull()) |match_item| {
|
||||
// Match the namespace declaration itself
|
||||
try inst_map.put(gpa, match_item.old_inst, match_item.new_inst);
|
||||
|
Loading…
Reference in New Issue
Block a user