diff options
| -rw-r--r-- | src/Compilation.zig | 5 | ||||
| -rw-r--r-- | src/InternPool.zig | 70 | ||||
| -rw-r--r-- | src/Module.zig | 120 | ||||
| -rw-r--r-- | src/Sema.zig | 38 |
4 files changed, 110 insertions, 123 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 58f56517c3..f5d63c3676 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2795,6 +2795,7 @@ const Header = extern struct { extra_len: u32, limbs_len: u32, string_bytes_len: u32, + tracked_insts_len: u32, }, }; @@ -2802,7 +2803,7 @@ const Header = extern struct { /// saved, such as the target and most CLI flags. A cache hit will only occur /// when subsequent compiler invocations use the same set of flags. pub fn saveState(comp: *Compilation) !void { - var bufs_list: [6]std.os.iovec_const = undefined; + var bufs_list: [7]std.os.iovec_const = undefined; var bufs_len: usize = 0; const lf = comp.bin_file orelse return; @@ -2815,6 +2816,7 @@ pub fn saveState(comp: *Compilation) !void { .extra_len = @intCast(ip.extra.items.len), .limbs_len = @intCast(ip.limbs.items.len), .string_bytes_len = @intCast(ip.string_bytes.items.len), + .tracked_insts_len = @intCast(ip.tracked_insts.count()), }, }; addBuf(&bufs_list, &bufs_len, mem.asBytes(&header)); @@ -2823,6 +2825,7 @@ pub fn saveState(comp: *Compilation) !void { addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data))); addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag))); addBuf(&bufs_list, &bufs_len, ip.string_bytes.items); + addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys())); // TODO: compilation errors // TODO: files diff --git a/src/InternPool.zig b/src/InternPool.zig index 1c5703b055..88bd24ec93 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -54,6 +54,34 @@ string_table: std.HashMapUnmanaged( std.hash_map.default_max_load_percentage, ) = .{}, +/// An index into `tracked_insts` gives a reference to a single ZIR instruction which +/// persists across incremental updates. +tracked_insts: std.AutoArrayHashMapUnmanaged(TrackedInst, void) = .{}, + +pub const TrackedInst = extern struct { + path_digest: Cache.BinDigest, + inst: Zir.Inst.Index, + comptime { + // The fields should be tightly packed. See also serialiation logic in `Compilation.saveState`. + assert(@sizeOf(@This()) == Cache.bin_digest_len + @sizeOf(Zir.Inst.Index)); + } + pub const Index = enum(u32) { + _, + pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Zir.Inst.Index { + return ip.tracked_insts.keys()[@intFromEnum(i)].inst; + } + }; +}; + +pub fn trackZir(ip: *InternPool, gpa: Allocator, file: *Module.File, inst: Zir.Inst.Index) Allocator.Error!TrackedInst.Index { + const key: TrackedInst = .{ + .path_digest = file.path_digest, + .inst = inst, + }; + const gop = try ip.tracked_insts.getOrPut(gpa, key); + return @enumFromInt(gop.index); +} + const FieldMap = std.ArrayHashMapUnmanaged(void, void, std.array_hash_map.AutoContext(void), false); const builtin = @import("builtin"); @@ -62,11 +90,13 @@ const Allocator = std.mem.Allocator; const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; const BigIntMutable = std.math.big.int.Mutable; +const Cache = std.Build.Cache; const Limb = std.math.big.Limb; const Hash = std.hash.Wyhash; const InternPool = @This(); const Module = @import("Module.zig"); +const Zcu = Module; const Zir = @import("Zir.zig"); const KeyAdapter = struct { @@ -409,7 +439,7 @@ pub const Key = union(enum) { /// `none` when the struct has no declarations. namespace: OptionalNamespaceIndex, /// Index of the struct_decl ZIR instruction. - zir_index: Zir.Inst.Index, + zir_index: TrackedInst.Index, layout: std.builtin.Type.ContainerLayout, field_names: NullTerminatedString.Slice, field_types: Index.Slice, @@ -653,7 +683,7 @@ pub const Key = union(enum) { } /// Asserts the struct is not packed. - pub fn setZirIndex(s: @This(), ip: *InternPool, new_zir_index: Zir.Inst.Index) void { + pub fn setZirIndex(s: @This(), ip: *InternPool, new_zir_index: TrackedInst.Index) void { assert(s.layout != .Packed); const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?; ip.extra.items[s.extra_index + field_index] = @intFromEnum(new_zir_index); @@ -769,7 +799,7 @@ pub const Key = union(enum) { flags: Tag.TypeUnion.Flags, /// The enum that provides the list of field names and values. enum_tag_ty: Index, - zir_index: Zir.Inst.Index, + zir_index: TrackedInst.Index, /// The returned pointer expires with any addition to the `InternPool`. pub fn flagsPtr(self: @This(), ip: *const InternPool) *Tag.TypeUnion.Flags { @@ -1056,7 +1086,7 @@ pub const Key = union(enum) { /// the body. We store this rather than the body directly so that when ZIR /// is regenerated on update(), we can map this to the new corresponding /// ZIR instruction. - zir_body_inst: Zir.Inst.Index, + zir_body_inst: TrackedInst.Index, /// Relative to owner Decl. lbrace_line: u32, /// Relative to owner Decl. @@ -1082,7 +1112,7 @@ pub const Key = union(enum) { } /// Returns a pointer that becomes invalid after any additions to the `InternPool`. - pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *Zir.Inst.Index { + pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *TrackedInst.Index { return @ptrCast(&ip.extra.items[func.zir_body_inst_extra_index]); } @@ -1860,7 +1890,7 @@ pub const UnionType = struct { /// If this slice has length 0 it means all elements are `none`. field_aligns: Alignment.Slice, /// Index of the union_decl ZIR instruction. - zir_index: Zir.Inst.Index, + zir_index: TrackedInst.Index, /// Index into extra array of the `flags` field. flags_index: u32, /// Copied from `enum_tag_ty`. @@ -1954,10 +1984,10 @@ pub const UnionType = struct { } /// This does not mutate the field of UnionType. - pub fn setZirIndex(self: @This(), ip: *InternPool, new_zir_index: Zir.Inst.Index) void { + pub fn setZirIndex(self: @This(), ip: *InternPool, new_zir_index: TrackedInst.Index) void { const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?; const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?; - const ptr: *Zir.Inst.Index = + const ptr: *TrackedInst.Index = @ptrCast(&ip.extra.items[self.flags_index - flags_field_index + zir_index_field_index]); ptr.* = new_zir_index; } @@ -2976,7 +3006,7 @@ pub const Tag = enum(u8) { analysis: FuncAnalysis, owner_decl: DeclIndex, ty: Index, - zir_body_inst: Zir.Inst.Index, + zir_body_inst: TrackedInst.Index, lbrace_line: u32, rbrace_line: u32, lbrace_column: u32, @@ -3050,7 +3080,7 @@ pub const Tag = enum(u8) { namespace: NamespaceIndex, /// The enum that provides the list of field names and values. tag_ty: Index, - zir_index: Zir.Inst.Index, + zir_index: TrackedInst.Index, pub const Flags = packed struct(u32) { runtime_tag: UnionType.RuntimeTag, @@ -3072,7 +3102,7 @@ pub const Tag = enum(u8) { /// 2. init: Index for each fields_len // if tag is type_struct_packed_inits pub const TypeStructPacked = struct { decl: DeclIndex, - zir_index: Zir.Inst.Index, + zir_index: TrackedInst.Index, fields_len: u32, namespace: OptionalNamespaceIndex, backing_int_ty: Index, @@ -3119,7 +3149,7 @@ pub const Tag = enum(u8) { /// 7. field_offset: u32 // for each field in declared order, undef until layout_resolved pub const TypeStruct = struct { decl: DeclIndex, - zir_index: Zir.Inst.Index, + zir_index: TrackedInst.Index, fields_len: u32, flags: Flags, size: u32, @@ -3708,6 +3738,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { ip.string_table.deinit(gpa); + ip.tracked_insts.deinit(gpa); + ip.* = undefined; } @@ -5358,7 +5390,7 @@ pub const UnionTypeInit = struct { flags: Tag.TypeUnion.Flags, decl: DeclIndex, namespace: NamespaceIndex, - zir_index: Zir.Inst.Index, + zir_index: TrackedInst.Index, fields_len: u32, enum_tag_ty: Index, /// May have length 0 which leaves the values unset until later. @@ -5430,7 +5462,7 @@ pub const StructTypeInit = struct { decl: DeclIndex, namespace: OptionalNamespaceIndex, layout: std.builtin.Type.ContainerLayout, - zir_index: Zir.Inst.Index, + zir_index: TrackedInst.Index, fields_len: u32, known_non_opv: bool, requires_comptime: RequiresComptime, @@ -5704,7 +5736,7 @@ pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: Key.ExternFunc) Alloc pub const GetFuncDeclKey = struct { owner_decl: DeclIndex, ty: Index, - zir_body_inst: Zir.Inst.Index, + zir_body_inst: TrackedInst.Index, lbrace_line: u32, rbrace_line: u32, lbrace_column: u32, @@ -5773,7 +5805,7 @@ pub const GetFuncDeclIesKey = struct { is_var_args: bool, is_generic: bool, is_noinline: bool, - zir_body_inst: Zir.Inst.Index, + zir_body_inst: TrackedInst.Index, lbrace_line: u32, rbrace_line: u32, lbrace_column: u32, @@ -6535,7 +6567,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 { NullTerminatedString, OptionalNullTerminatedString, Tag.TypePointer.VectorIndex, - Zir.Inst.Index, + TrackedInst.Index, => @intFromEnum(@field(extra, field.name)), u32, @@ -6611,7 +6643,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct NullTerminatedString, OptionalNullTerminatedString, Tag.TypePointer.VectorIndex, - Zir.Inst.Index, + TrackedInst.Index, => @enumFromInt(int32), u32, @@ -8317,7 +8349,7 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool { return funcAnalysis(ip, i).inferred_error_set; } -pub fn funcZirBodyInst(ip: *const InternPool, i: Index) Zir.Inst.Index { +pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index { assert(i != .none); const item = ip.items.get(@intFromEnum(i)); const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?; diff --git a/src/Module.zig b/src/Module.zig index 02df2dac67..499eb02f1e 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -834,6 +834,9 @@ pub const File = struct { multi_pkg: bool = false, /// List of references to this file, used for multi-package errors. references: std.ArrayListUnmanaged(Reference) = .{}, + /// The hash of the path to this file, used to store `InternPool.TrackedInst`. + /// undefined until `zir_loaded == true`. + path_digest: Cache.BinDigest = undefined, /// Used by change detection algorithm, after astgen, contains the /// set of decls that existed in the previous ZIR but not in the new one. @@ -2594,7 +2597,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { const stat = try source_file.stat(); const want_local_cache = file.mod == mod.main_mod; - const digest = hash: { + const bin_digest = hash: { var path_hash: Cache.HashHelper = .{}; path_hash.addBytes(build_options.version); path_hash.add(builtin.zig_backend); @@ -2603,7 +2606,19 @@ pub fn astGenFile(mod: *Module, file: *File) !void { path_hash.addBytes(file.mod.root.sub_path); } path_hash.addBytes(file.sub_file_path); - break :hash path_hash.final(); + var bin: Cache.BinDigest = undefined; + path_hash.hasher.final(&bin); + break :hash bin; + }; + file.path_digest = bin_digest; + const hex_digest = hex: { + var hex: Cache.HexDigest = undefined; + _ = std.fmt.bufPrint( + &hex, + "{s}", + .{std.fmt.fmtSliceHexLower(&bin_digest)}, + ) catch unreachable; + break :hex hex; }; const cache_directory = if (want_local_cache) mod.local_zir_cache else mod.global_zir_cache; const zir_dir = cache_directory.handle; @@ -2613,7 +2628,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { .never_loaded, .retryable_failure => lock: { // First, load the cached ZIR code, if any. log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{ - file.sub_file_path, want_local_cache, &digest, + file.sub_file_path, want_local_cache, &hex_digest, }); break :lock .shared; @@ -2640,7 +2655,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { // version. Likewise if we're working on AstGen and another process asks for // the cached file, they'll get it. const cache_file = while (true) { - break zir_dir.createFile(&digest, .{ + break zir_dir.createFile(&hex_digest, .{ .read = true, .truncate = false, .lock = lock, @@ -2826,7 +2841,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { }; cache_file.writevAll(&iovecs) catch |err| { log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{ - file.mod.root, file.sub_file_path, cache_directory, &digest, @errorName(err), + file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err), }); }; @@ -2935,89 +2950,22 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) return zir; } -/// Patch ups: -/// * Struct.zir_index -/// * Decl.zir_index -/// * Fn.zir_body_inst -/// * Decl.zir_decl_index -fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void { - const gpa = mod.gpa; - const new_zir = file.zir; - - // The root decl will be null if the previous ZIR had AST errors. - const root_decl = file.root_decl.unwrap() orelse return; +fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir) !void { + const gpa = zcu.gpa; - // Maps from old ZIR to new ZIR, declaration, struct_decl, enum_decl, etc. Any instruction which - // creates a namespace, and any `declaration` instruction, gets mapped from old to new here. var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{}; defer inst_map.deinit(gpa); - try mapOldZirToNew(gpa, old_zir, new_zir, &inst_map); - - // Walk the Decl graph, updating ZIR indexes, strings, and populating - // the deleted and outdated lists. - - var decl_stack: ArrayListUnmanaged(Decl.Index) = .{}; - defer decl_stack.deinit(gpa); - - try decl_stack.append(gpa, root_decl); - - file.deleted_decls.clearRetainingCapacity(); - file.outdated_decls.clearRetainingCapacity(); - - // The root decl is always outdated; otherwise we would not have had - // to re-generate ZIR for the File. - try file.outdated_decls.append(gpa, root_decl); - - const ip = &mod.intern_pool; - - while (decl_stack.popOrNull()) |decl_index| { - const decl = mod.declPtr(decl_index); - // Anonymous decls and the root decl have this set to 0. We still need - // to walk them but we do not need to modify this value. - // Anonymous decls should not be marked outdated. They will be re-generated - // if their owner decl is marked outdated. - if (decl.zir_decl_index.unwrap()) |old_zir_decl_index| { - const new_zir_decl_index = inst_map.get(old_zir_decl_index) orelse { - try file.deleted_decls.append(gpa, decl_index); - continue; - }; - const old_hash = decl.contentsHashZir(old_zir); - decl.zir_decl_index = new_zir_decl_index.toOptional(); - const new_hash = decl.contentsHashZir(new_zir); - if (!std.zig.srcHashEql(old_hash, new_hash)) { - try file.outdated_decls.append(gpa, decl_index); - } - } + try mapOldZirToNew(gpa, old_zir, file.zir, &inst_map); - if (!decl.owns_tv) continue; - - if (decl.getOwnedStruct(mod)) |struct_type| { - struct_type.setZirIndex(ip, inst_map.get(struct_type.zir_index) orelse { - try file.deleted_decls.append(gpa, decl_index); - continue; - }); - } - - if (decl.getOwnedUnion(mod)) |union_type| { - union_type.setZirIndex(ip, inst_map.get(union_type.zir_index) orelse { - try file.deleted_decls.append(gpa, decl_index); - continue; - }); - } - - if (decl.getOwnedFunction(mod)) |func| { - func.zirBodyInst(ip).* = inst_map.get(func.zir_body_inst) orelse { - try file.deleted_decls.append(gpa, decl_index); - continue; - }; - } - - if (decl.getOwnedInnerNamespace(mod)) |namespace| { - for (namespace.decls.keys()) |sub_decl| { - try decl_stack.append(gpa, sub_decl); - } - } + // TODO: this should be done after all AstGen workers complete, to avoid + // iterating over this full set for every updated file. + for (zcu.intern_pool.tracked_insts.keys()) |*ti| { + if (!std.mem.eql(u8, &ti.path_digest, &file.path_digest)) continue; + ti.inst = inst_map.get(ti.inst) orelse { + // TODO: invalidate this `TrackedInst` via the dependency mechanism + continue; + }; } } @@ -3494,7 +3442,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { const struct_ty = sema.getStructType( new_decl_index, new_namespace_index, - .main_struct_inst, + try mod.intern_pool.trackZir(gpa, file, .main_struct_inst), ) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, }; @@ -4472,7 +4420,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato }; defer inner_block.instructions.deinit(gpa); - const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).*); + const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip)); // Here we are performing "runtime semantic analysis" for a function body, which means // we must map the parameter ZIR instructions to `arg` AIR instructions. @@ -6125,7 +6073,7 @@ pub fn getParamName(mod: *Module, func_index: InternPool.Index, index: u32) [:0] const tags = file.zir.instructions.items(.tag); const data = file.zir.instructions.items(.data); - const param_body = file.zir.getParamBody(func.zir_body_inst); + const param_body = file.zir.getParamBody(func.zir_body_inst.resolve(&mod.intern_pool)); const param = param_body[index]; return switch (tags[@intFromEnum(param)]) { diff --git a/src/Sema.zig b/src/Sema.zig index fc6cf0c017..7e0e317ffb 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2708,11 +2708,12 @@ pub fn getStructType( sema: *Sema, decl: InternPool.DeclIndex, namespace: InternPool.NamespaceIndex, - zir_index: Zir.Inst.Index, + tracked_inst: InternPool.TrackedInst.Index, ) !InternPool.Index { const mod = sema.mod; const gpa = sema.gpa; const ip = &mod.intern_pool; + const zir_index = tracked_inst.resolve(ip); const extended = sema.code.instructions.items(.data)[@intFromEnum(zir_index)].extended; assert(extended.opcode == .struct_decl); const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); @@ -2747,7 +2748,7 @@ pub fn getStructType( const ty = try ip.getStructType(gpa, .{ .decl = decl, .namespace = namespace.toOptional(), - .zir_index = zir_index, + .zir_index = tracked_inst, .layout = small.layout, .known_non_opv = small.known_non_opv, .is_tuple = small.is_tuple, @@ -2797,7 +2798,8 @@ fn zirStructDecl( errdefer mod.destroyNamespace(new_namespace_index); const struct_ty = ty: { - const ty = try sema.getStructType(new_decl_index, new_namespace_index, inst); + const tracked_inst = try ip.trackZir(mod.gpa, block.getFileScope(mod), inst); + const ty = try sema.getStructType(new_decl_index, new_namespace_index, tracked_inst); if (sema.builtin_type_target_index != .none) { ip.resolveBuiltinType(sema.builtin_type_target_index, ty); break :ty sema.builtin_type_target_index; @@ -2856,7 +2858,7 @@ fn createAnonymousDeclTypeNamed( return new_decl_index; }, .func => { - const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index)); + const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip)); const zir_tags = sema.code.instructions.items(.tag); var buf = std.ArrayList(u8).init(gpa); @@ -3252,7 +3254,7 @@ fn zirUnionDecl( }, .decl = new_decl_index, .namespace = new_namespace_index, - .zir_index = inst, + .zir_index = try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst), .fields_len = fields_len, .enum_tag_ty = .none, .field_types = &.{}, @@ -7446,7 +7448,7 @@ fn analyzeCall( // the AIR instructions of the callsite. The callee could be a generic function // which means its parameter type expressions must be resolved in order and used // to successively coerce the arguments. - const fn_info = ics.callee().code.getFnInfo(module_fn.zir_body_inst); + const fn_info = ics.callee().code.getFnInfo(module_fn.zir_body_inst.resolve(ip)); try ics.callee().inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body); var arg_i: u32 = 0; @@ -7494,7 +7496,7 @@ fn analyzeCall( // each of the parameters, resolving the return type and providing it to the child // `Sema` so that it can be used for the `ret_ptr` instruction. const ret_ty_inst = if (fn_info.ret_ty_body.len != 0) - try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst) + try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst.resolve(ip)) else try sema.resolveInst(fn_info.ret_ty_ref); const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; @@ -7885,7 +7887,7 @@ fn instantiateGenericCall( const namespace_index = fn_owner_decl.src_namespace; const namespace = mod.namespacePtr(namespace_index); const fn_zir = namespace.file_scope.zir; - const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst); + const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip)); const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count()); @memset(comptime_args, .none); @@ -9467,7 +9469,7 @@ fn funcCommon( .is_generic = final_is_generic, .is_noinline = is_noinline, - .zir_body_inst = func_inst, + .zir_body_inst = try ip.trackZir(gpa, block.getFileScope(mod), func_inst), .lbrace_line = src_locs.lbrace_line, .rbrace_line = src_locs.rbrace_line, .lbrace_column = @as(u16, @truncate(src_locs.columns)), @@ -9545,7 +9547,7 @@ fn funcCommon( .ty = func_ty, .cc = cc, .is_noinline = is_noinline, - .zir_body_inst = func_inst, + .zir_body_inst = try ip.trackZir(gpa, block.getFileScope(mod), func_inst), .lbrace_line = src_locs.lbrace_line, .rbrace_line = src_locs.rbrace_line, .lbrace_column = @as(u16, @truncate(src_locs.columns)), @@ -21553,7 +21555,7 @@ fn zirReify( .namespace = new_namespace_index, .enum_tag_ty = enum_tag_ty, .fields_len = fields_len, - .zir_index = inst, + .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst), // TODO: should reified types be handled differently? .flags = .{ .layout = layout, .status = .have_field_types, @@ -21721,7 +21723,7 @@ fn reifyStruct( const ty = try ip.getStructType(gpa, .{ .decl = new_decl_index, .namespace = .none, - .zir_index = inst, + .zir_index = try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst), // TODO: should reified types be handled differently? .layout = layout, .known_non_opv = false, .fields_len = fields_len, @@ -35593,7 +35595,8 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp break :blk accumulator; }; - const extended = zir.instructions.items(.data)[@intFromEnum(struct_type.zir_index)].extended; + const zir_index = struct_type.zir_index.resolve(ip); + const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended; assert(extended.opcode == .struct_decl); const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); @@ -35613,7 +35616,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref); } else { const body = zir.bodySlice(extra_index, backing_int_body_len); - const ty_ref = try sema.resolveBody(&block, body, struct_type.zir_index); + const ty_ref = try sema.resolveBody(&block, body, zir_index); break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref); } }; @@ -36357,7 +36360,7 @@ fn semaStructFields( const decl = mod.declPtr(decl_index); const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; const zir = mod.namespacePtr(namespace_index).file_scope.zir; - const zir_index = struct_type.zir_index; + const zir_index = struct_type.zir_index.resolve(ip); const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); @@ -36628,7 +36631,7 @@ fn semaStructFieldInits( const decl = mod.declPtr(decl_index); const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; const zir = mod.namespacePtr(namespace_index).file_scope.zir; - const zir_index = struct_type.zir_index; + const zir_index = struct_type.zir_index.resolve(ip); const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa); @@ -36777,7 +36780,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un const ip = &mod.intern_pool; const decl_index = union_type.decl; const zir = mod.namespacePtr(union_type.namespace).file_scope.zir; - const extended = zir.instructions.items(.data)[@intFromEnum(union_type.zir_index)].extended; + const zir_index = union_type.zir_index.resolve(ip); + const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended; assert(extended.opcode == .union_decl); const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small); var extra_index: usize = extended.operand; |
