authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-04 03:33:23-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-07 22:59:52-04:00
log92ddb959a7c8877c98363b27c71cd5ae4b9603f4
treecba44064a9411426c0ff5639541d3a47533dd01e
parent8293ff94cf2798a2678b91019979472d34273bdb

InternPool: implement and use thread-safe list for items


6 files changed, 859 insertions(+), 737 deletions(-)

src/Compilation.zig+4-4
......@@ -2745,7 +2745,7 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {
27452745
27462746const Header = extern struct {
27472747 intern_pool: extern struct {
2748 items_len: u32,
2748 //items_len: u32,
27492749 extra_len: u32,
27502750 limbs_len: u32,
27512751 //string_bytes_len: u32,
......@@ -2774,7 +2774,7 @@ pub fn saveState(comp: *Compilation) !void {
27742774 const ip = &zcu.intern_pool;
27752775 const header: Header = .{
27762776 .intern_pool = .{
2777 .items_len = @intCast(ip.items.len),
2777 //.items_len = @intCast(ip.items.len),
27782778 .extra_len = @intCast(ip.extra.items.len),
27792779 .limbs_len = @intCast(ip.limbs.items.len),
27802780 //.string_bytes_len = @intCast(ip.string_bytes.items.len),
......@@ -2792,8 +2792,8 @@ pub fn saveState(comp: *Compilation) !void {
27922792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
27932793 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));
27942794 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));
2795 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
2796 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
2795 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
2796 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
27972797 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
27982798 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
27992799
src/InternPool.zig+799-679
......@@ -8,7 +8,7 @@ tid_width: std.math.Log2Int(u32) = 0,
88tid_shift_31: std.math.Log2Int(u32) = 31,
99tid_shift_32: std.math.Log2Int(u32) = 31,
1010
11items: std.MultiArrayList(Item) = .{},
11//items: std.MultiArrayList(Item) = .{},
1212extra: std.ArrayListUnmanaged(u32) = .{},
1313/// On 32-bit systems, this array is ignored and extra is used for everything.
1414/// On 64-bit systems, this array is used for big integers and associated metadata.
......@@ -344,10 +344,12 @@ const Local = struct {
344344 shared: Shared align(std.atomic.cache_line),
345345 mutate: struct {
346346 arena: std.heap.ArenaAllocator.State,
347 items: Mutate,
347348 strings: Mutate,
348349 } align(std.atomic.cache_line),
349350
350351 const Shared = struct {
352 items: List(Item),
351353 strings: Strings,
352354 };
353355
......@@ -403,6 +405,11 @@ const Local = struct {
403405 } });
404406 }
405407
408 pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void {
409 try mutable.ensureUnusedCapacity(1);
410 mutable.appendAssumeCapacity(elem);
411 }
412
406413 pub fn appendAssumeCapacity(mutable: Mutable, elem: Elem) void {
407414 var mutable_view = mutable.view();
408415 defer mutable.lenPtr().* = @intCast(mutable_view.len);
......@@ -417,7 +424,7 @@ const Local = struct {
417424 const mutable_len = mutable.lenPtr();
418425 const start = mutable_len.*;
419426 const slice_len = @field(slice, @tagName(fields[0])).len;
420 assert(slice_len < mutable.capacityPtr().* - start);
427 assert(slice_len <= mutable.capacityPtr().* - start);
421428 mutable_len.* = @intCast(start + slice_len);
422429 const mutable_view = mutable.view();
423430 inline for (fields) |field| {
......@@ -552,6 +559,15 @@ const Local = struct {
552559 };
553560 }
554561
562 pub fn getMutableItems(local: *Local, gpa: std.mem.Allocator) List(Item).Mutable {
563 return .{
564 .gpa = gpa,
565 .arena = &local.mutate.arena,
566 .mutate = &local.mutate.items,
567 .list = &local.shared.items,
568 };
569 }
570
555571 /// In order to store references to strings in fewer bytes, we copy all
556572 /// string bytes into here. String bytes can be null. It is up to whomever
557573 /// is referencing the data here whether they want to store both index and length,
......@@ -566,9 +582,11 @@ const Local = struct {
566582 };
567583 }
568584};
585
569586pub fn getLocal(ip: *InternPool, tid: Zcu.PerThread.Id) *Local {
570587 return &ip.locals[@intFromEnum(tid)];
571588}
589
572590pub fn getLocalShared(ip: *const InternPool, tid: Zcu.PerThread.Id) *const Local.Shared {
573591 return &ip.locals[@intFromEnum(tid)].shared;
574592}
......@@ -646,6 +664,7 @@ const Shard = struct {
646664 };
647665 }
648666};
667
649668fn getShard(ip: *InternPool, tid: Zcu.PerThread.Id) *Shard {
650669 return &ip.shards[@intFromEnum(tid)];
651670}
......@@ -654,6 +673,7 @@ fn getTidMask(ip: *const InternPool) u32 {
654673 assert(std.math.isPowerOfTwo(ip.shards.len));
655674 return @intCast(ip.shards.len - 1);
656675}
676
657677fn getIndexMask(ip: *const InternPool, comptime BackingInt: type) u32 {
658678 return @as(u32, std.math.maxInt(BackingInt)) >> ip.tid_width;
659679}
......@@ -791,8 +811,7 @@ pub const String = enum(u32) {
791811
792812 fn toOverlongSlice(string: String, ip: *const InternPool) []const u8 {
793813 const unwrapped = string.unwrap(ip);
794 const strings = ip.getLocalShared(unwrapped.tid).strings.acquire();
795 return strings.view().items(.@"0")[unwrapped.index..];
814 return ip.getLocalShared(unwrapped.tid).strings.acquire().view().items(.@"0")[unwrapped.index..];
796815 }
797816};
798817
......@@ -2309,7 +2328,7 @@ pub const LoadedUnionType = struct {
23092328};
23102329
23112330pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2312 const data = ip.items.items(.data)[@intFromEnum(index)];
2331 const data = index.getData(ip);
23132332 const type_union = ip.extraDataTrail(Tag.TypeUnion, data);
23142333 const fields_len = type_union.data.fields_len;
23152334
......@@ -2731,7 +2750,7 @@ pub const LoadedStructType = struct {
27312750};
27322751
27332752pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2734 const item = ip.items.get(@intFromEnum(index));
2753 const item = index.getItem(ip);
27352754 switch (item.tag) {
27362755 .type_struct => {
27372756 if (item.data == 0) return .{
......@@ -2955,7 +2974,7 @@ const LoadedEnumType = struct {
29552974};
29562975
29572976pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2958 const item = ip.items.get(@intFromEnum(index));
2977 const item = index.getItem(ip);
29592978 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {
29602979 .type_enum_auto => {
29612980 const extra = ip.extraDataTrail(EnumAuto, item.data);
......@@ -3034,9 +3053,9 @@ pub const LoadedOpaqueType = struct {
30343053};
30353054
30363055pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
3037 assert(ip.items.items(.tag)[@intFromEnum(index)] == .type_opaque);
3038 const extra_index = ip.items.items(.data)[@intFromEnum(index)];
3039 const extra = ip.extraDataTrail(Tag.TypeOpaque, extra_index);
3056 const item = index.getItem(ip);
3057 assert(item.tag == .type_opaque);
3058 const extra = ip.extraDataTrail(Tag.TypeOpaque, item.data);
30403059 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))
30413060 0
30423061 else
......@@ -3211,6 +3230,38 @@ pub const Index = enum(u32) {
32113230 }
32123231 };
32133232
3233 pub fn getItem(index: Index, ip: *const InternPool) Item {
3234 const unwrapped = index.unwrap(ip);
3235 return ip.getLocalShared(unwrapped.tid).items.acquire().view().get(unwrapped.index);
3236 }
3237
3238 pub fn getTag(index: Index, ip: *const InternPool) Tag {
3239 const unwrapped = index.unwrap(ip);
3240 return ip.getLocalShared(unwrapped.tid).items.acquire().view().items(.tag)[unwrapped.index];
3241 }
3242
3243 pub fn getData(index: Index, ip: *const InternPool) u32 {
3244 const unwrapped = index.unwrap(ip);
3245 return ip.getLocalShared(unwrapped.tid).items.acquire().view().items(.data)[unwrapped.index];
3246 }
3247
3248 const Unwrapped = struct {
3249 tid: Zcu.PerThread.Id,
3250 index: u32,
3251
3252 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Index {
3253 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
3254 assert(unwrapped.index <= ip.getIndexMask(u31));
3255 return @enumFromInt(@intFromEnum(unwrapped.tid) << ip.tid_shift_31 | unwrapped.index);
3256 }
3257 };
3258 fn unwrap(index: Index, ip: *const InternPool) Unwrapped {
3259 return .{
3260 .tid = @enumFromInt(@intFromEnum(index) >> ip.tid_shift_31 & ip.getTidMask()),
3261 .index = @intFromEnum(index) & ip.getIndexMask(u31),
3262 };
3263 }
3264
32143265 /// This function is used in the debugger pretty formatters in tools/ to fetch the
32153266 /// Tag to encoding mapping to facilitate fancy debug printing for this type.
32163267 /// TODO merge this with `Tag.Payload`.
......@@ -4856,15 +4907,17 @@ pub const MemoizedCall = struct {
48564907
48574908pub fn init(ip: *InternPool, gpa: Allocator, total_threads: usize) !void {
48584909 errdefer ip.deinit(gpa);
4859 assert(ip.items.len == 0);
4910 assert(ip.locals.len == 0 and ip.shards.len == 0);
48604911
48614912 ip.locals = try gpa.alloc(Local, total_threads);
48624913 @memset(ip.locals, .{
48634914 .shared = .{
4915 .items = Local.List(Item).empty,
48644916 .strings = Local.Strings.empty,
48654917 },
48664918 .mutate = .{
48674919 .arena = .{},
4920 .items = Local.Mutate.empty,
48684921 .strings = Local.Mutate.empty,
48694922 },
48704923 });
......@@ -4918,7 +4971,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, total_threads: usize) !void {
49184971}
49194972
49204973pub fn deinit(ip: *InternPool, gpa: Allocator) void {
4921 ip.items.deinit(gpa);
49224974 ip.extra.deinit(gpa);
49234975 ip.limbs.deinit(gpa);
49244976
......@@ -4955,7 +5007,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
49555007
49565008pub fn indexToKey(ip: *const InternPool, index: Index) Key {
49575009 assert(index != .none);
4958 const item = ip.items.get(@intFromEnum(index));
5010 const item = index.getItem(ip);
49595011 const data = item.data;
49605012 return switch (item.tag) {
49615013 .removed => unreachable,
......@@ -5001,8 +5053,10 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
50015053 .type_pointer => .{ .ptr_type = ip.extraData(Tag.TypePointer, data) },
50025054
50035055 .type_slice => {
5004 assert(ip.items.items(.tag)[data] == .type_pointer);
5005 var ptr_info = ip.extraData(Tag.TypePointer, ip.items.items(.data)[data]);
5056 const many_ptr_index: Index = @enumFromInt(data);
5057 const many_ptr_item = many_ptr_index.getItem(ip);
5058 assert(many_ptr_item.tag == .type_pointer);
5059 var ptr_info = ip.extraData(Tag.TypePointer, many_ptr_item.data);
50065060 ptr_info.flags.size = .Slice;
50075061 return .{ .ptr_type = ptr_info };
50085062 },
......@@ -5196,7 +5250,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
51965250 .ptr_elem => {
51975251 // Avoid `indexToKey` recursion by asserting the tag encoding.
51985252 const info = ip.extraData(PtrBaseIndex, data);
5199 const index_item = ip.items.get(@intFromEnum(info.index));
5253 const index_item = info.index.getItem(ip);
52005254 return switch (index_item.tag) {
52015255 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .arr_elem = .{
52025256 .base = info.base,
......@@ -5209,7 +5263,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
52095263 .ptr_field => {
52105264 // Avoid `indexToKey` recursion by asserting the tag encoding.
52115265 const info = ip.extraData(PtrBaseIndex, data);
5212 const index_item = ip.items.get(@intFromEnum(info.index));
5266 const index_item = info.index.getItem(ip);
52135267 return switch (index_item.tag) {
52145268 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .field = .{
52155269 .base = info.base,
......@@ -5326,7 +5380,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
53265380 .func_coerced => .{ .func = ip.extraFuncCoerced(data) },
53275381 .only_possible_value => {
53285382 const ty: Index = @enumFromInt(data);
5329 const ty_item = ip.items.get(@intFromEnum(ty));
5383 const ty_item = ty.getItem(ip);
53305384 return switch (ty_item.tag) {
53315385 .type_array_big => {
53325386 const sentinel = @as(
......@@ -5557,7 +5611,7 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {
55575611
55585612fn extraFuncCoerced(ip: *const InternPool, extra_index: u32) Key.Func {
55595613 const func_coerced = ip.extraData(Tag.FuncCoerced, extra_index);
5560 const sub_item = ip.items.get(@intFromEnum(func_coerced.func));
5614 const sub_item = func_coerced.func.getItem(ip);
55615615 var func: Key.Func = switch (sub_item.tag) {
55625616 .func_instance => ip.extraFuncInstance(sub_item.data),
55635617 .func_decl => ip.extraFuncDecl(sub_item.data),
......@@ -5581,21 +5635,30 @@ fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key
55815635const GetOrPutKey = union(enum) {
55825636 existing: Index,
55835637 new: struct {
5638 ip: *InternPool,
5639 tid: Zcu.PerThread.Id,
55845640 shard: *Shard,
55855641 map_index: u32,
55865642 },
55875643
5588 fn set(gop: *GetOrPutKey, index: Index) Index {
5644 fn put(gop: *GetOrPutKey) Index {
5645 return gop.putAt(0);
5646 }
5647 fn putAt(gop: *GetOrPutKey, offset: u32) Index {
55895648 switch (gop.*) {
55905649 .existing => unreachable,
55915650 .new => |info| {
5651 const index = Index.Unwrapped.wrap(.{
5652 .tid = info.tid,
5653 .index = info.ip.getLocal(info.tid).mutate.items.len - 1 - offset,
5654 }, info.ip);
55925655 info.shard.shared.map.entries[info.map_index].release(index);
55935656 info.shard.mutate.map.len += 1;
55945657 info.shard.mutate.map.mutex.unlock();
5658 gop.* = .{ .existing = index };
5659 return index;
55955660 },
55965661 }
5597 gop.* = .{ .existing = index };
5598 return index;
55995662 }
56005663
56015664 fn assign(gop: *GetOrPutKey, new_gop: GetOrPutKey) void {
......@@ -5692,21 +5755,27 @@ fn getOrPutKey(
56925755 shard.shared.map.release(new_map);
56935756 }
56945757 map.entries[map_index].hash = hash;
5695 return .{ .new = .{ .shard = shard, .map_index = map_index } };
5758 return .{ .new = .{
5759 .ip = ip,
5760 .tid = tid,
5761 .shard = shard,
5762 .map_index = map_index,
5763 } };
56965764}
56975765
56985766pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index {
56995767 var gop = try ip.getOrPutKey(gpa, tid, key);
57005768 defer gop.deinit();
57015769 if (gop == .existing) return gop.existing;
5702 try ip.items.ensureUnusedCapacity(gpa, 1);
5770 const items = ip.getLocal(tid).getMutableItems(gpa);
5771 try items.ensureUnusedCapacity(1);
57035772 switch (key) {
57045773 .int_type => |int_type| {
57055774 const t: Tag = switch (int_type.signedness) {
57065775 .signed => .type_int_signed,
57075776 .unsigned => .type_int_unsigned,
57085777 };
5709 ip.items.appendAssumeCapacity(.{
5778 items.appendAssumeCapacity(.{
57105779 .tag = t,
57115780 .data = int_type.bits,
57125781 });
......@@ -5721,18 +5790,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
57215790 const ptr_type_index = try ip.get(gpa, tid, new_key);
57225791 gop.assign(try ip.getOrPutKey(gpa, tid, key));
57235792
5724 try ip.items.ensureUnusedCapacity(gpa, 1);
5725 ip.items.appendAssumeCapacity(.{
5793 try items.ensureUnusedCapacity(1);
5794 items.appendAssumeCapacity(.{
57265795 .tag = .type_slice,
57275796 .data = @intFromEnum(ptr_type_index),
57285797 });
5729 return gop.set(@enumFromInt(ip.items.len - 1));
5798 return gop.put();
57305799 }
57315800
57325801 var ptr_type_adjusted = ptr_type;
57335802 if (ptr_type.flags.size == .C) ptr_type_adjusted.flags.is_allowzero = true;
57345803
5735 ip.items.appendAssumeCapacity(.{
5804 items.appendAssumeCapacity(.{
57365805 .tag = .type_pointer,
57375806 .data = try ip.addExtra(gpa, ptr_type_adjusted),
57385807 });
......@@ -5743,19 +5812,19 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
57435812
57445813 if (std.math.cast(u32, array_type.len)) |len| {
57455814 if (array_type.sentinel == .none) {
5746 ip.items.appendAssumeCapacity(.{
5815 items.appendAssumeCapacity(.{
57475816 .tag = .type_array_small,
57485817 .data = try ip.addExtra(gpa, Vector{
57495818 .len = len,
57505819 .child = array_type.child,
57515820 }),
57525821 });
5753 return gop.set(@enumFromInt(ip.items.len - 1));
5822 return gop.put();
57545823 }
57555824 }
57565825
57575826 const length = Array.Length.init(array_type.len);
5758 ip.items.appendAssumeCapacity(.{
5827 items.appendAssumeCapacity(.{
57595828 .tag = .type_array_big,
57605829 .data = try ip.addExtra(gpa, Array{
57615830 .len0 = length.a,
......@@ -5766,7 +5835,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
57665835 });
57675836 },
57685837 .vector_type => |vector_type| {
5769 ip.items.appendAssumeCapacity(.{
5838 items.appendAssumeCapacity(.{
57705839 .tag = .type_vector,
57715840 .data = try ip.addExtra(gpa, Vector{
57725841 .len = vector_type.len,
......@@ -5776,20 +5845,20 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
57765845 },
57775846 .opt_type => |payload_type| {
57785847 assert(payload_type != .none);
5779 ip.items.appendAssumeCapacity(.{
5848 items.appendAssumeCapacity(.{
57805849 .tag = .type_optional,
57815850 .data = @intFromEnum(payload_type),
57825851 });
57835852 },
57845853 .anyframe_type => |payload_type| {
57855854 // payload_type might be none, indicating the type is `anyframe`.
5786 ip.items.appendAssumeCapacity(.{
5855 items.appendAssumeCapacity(.{
57875856 .tag = .type_anyframe,
57885857 .data = @intFromEnum(payload_type),
57895858 });
57905859 },
57915860 .error_union_type => |error_union_type| {
5792 ip.items.appendAssumeCapacity(if (error_union_type.error_set_type == .anyerror_type) .{
5861 items.appendAssumeCapacity(if (error_union_type.error_set_type == .anyerror_type) .{
57935862 .tag = .type_anyerror_union,
57945863 .data = @intFromEnum(error_union_type.payload_type),
57955864 } else .{
......@@ -5805,7 +5874,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58055874 addStringsToMap(ip, names_map, names);
58065875 const names_len = error_set_type.names.len;
58075876 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);
5808 ip.items.appendAssumeCapacity(.{
5877 items.appendAssumeCapacity(.{
58095878 .tag = .type_error_set,
58105879 .data = ip.addExtraAssumeCapacity(Tag.ErrorSet{
58115880 .names_len = names_len,
......@@ -5815,26 +5884,26 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58155884 ip.extra.appendSliceAssumeCapacity(@ptrCast(error_set_type.names.get(ip)));
58165885 },
58175886 .inferred_error_set_type => |ies_index| {
5818 ip.items.appendAssumeCapacity(.{
5887 items.appendAssumeCapacity(.{
58195888 .tag = .type_inferred_error_set,
58205889 .data = @intFromEnum(ies_index),
58215890 });
58225891 },
58235892 .simple_type => |simple_type| {
5824 ip.items.appendAssumeCapacity(.{
5893 items.appendAssumeCapacity(.{
58255894 .tag = .simple_type,
58265895 .data = @intFromEnum(simple_type),
58275896 });
58285897 },
58295898 .simple_value => |simple_value| {
5830 ip.items.appendAssumeCapacity(.{
5899 items.appendAssumeCapacity(.{
58315900 .tag = .simple_value,
58325901 .data = @intFromEnum(simple_value),
58335902 });
58345903 },
58355904 .undef => |ty| {
58365905 assert(ty != .none);
5837 ip.items.appendAssumeCapacity(.{
5906 items.appendAssumeCapacity(.{
58385907 .tag = .undef,
58395908 .data = @intFromEnum(ty),
58405909 });
......@@ -5853,7 +5922,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58535922 .variable => |variable| {
58545923 const has_init = variable.init != .none;
58555924 if (has_init) assert(variable.ty == ip.typeOf(variable.init));
5856 ip.items.appendAssumeCapacity(.{
5925 items.appendAssumeCapacity(.{
58575926 .tag = .variable,
58585927 .data = try ip.addExtra(gpa, Tag.Variable{
58595928 .ty = variable.ty,
......@@ -5873,7 +5942,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58735942 .slice => |slice| {
58745943 assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .Slice);
58755944 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);
5876 ip.items.appendAssumeCapacity(.{
5945 items.appendAssumeCapacity(.{
58775946 .tag = .ptr_slice,
58785947 .data = try ip.addExtra(gpa, PtrSlice{
58795948 .ty = slice.ty,
......@@ -5886,7 +5955,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58865955 .ptr => |ptr| {
58875956 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
58885957 assert(ptr_type.flags.size != .Slice);
5889 ip.items.appendAssumeCapacity(switch (ptr.base_addr) {
5958 items.appendAssumeCapacity(switch (ptr.base_addr) {
58905959 .decl => |decl| .{
58915960 .tag = .ptr_decl,
58925961 .data = try ip.addExtra(gpa, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),
......@@ -5975,8 +6044,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
59756044 .storage = .{ .u64 = base_index.index },
59766045 } });
59776046 gop.assign(try ip.getOrPutKey(gpa, tid, key));
5978 try ip.items.ensureUnusedCapacity(gpa, 1);
5979 ip.items.appendAssumeCapacity(.{
6047 try items.ensureUnusedCapacity(1);
6048 items.appendAssumeCapacity(.{
59806049 .tag = switch (ptr.base_addr) {
59816050 .arr_elem => .ptr_elem,
59826051 .field => .ptr_field,
......@@ -5984,7 +6053,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
59846053 },
59856054 .data = try ip.addExtra(gpa, PtrBaseIndex.init(ptr.ty, base_index.base, index_index, ptr.byte_offset)),
59866055 });
5987 return gop.set(@enumFromInt(ip.items.len - 1));
6056 return gop.put();
59886057 },
59896058 });
59906059 },
......@@ -5992,7 +6061,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
59926061 .opt => |opt| {
59936062 assert(ip.isOptionalType(opt.ty));
59946063 assert(opt.val == .none or ip.indexToKey(opt.ty).opt_type == ip.typeOf(opt.val));
5995 ip.items.appendAssumeCapacity(if (opt.val == .none) .{
6064 items.appendAssumeCapacity(if (opt.val == .none) .{
59966065 .tag = .opt_null,
59976066 .data = @intFromEnum(opt.ty),
59986067 } else .{
......@@ -6009,7 +6078,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60096078 switch (int.storage) {
60106079 .u64, .i64, .big_int => {},
60116080 .lazy_align, .lazy_size => |lazy_ty| {
6012 ip.items.appendAssumeCapacity(.{
6081 items.appendAssumeCapacity(.{
60136082 .tag = switch (int.storage) {
60146083 else => unreachable,
60156084 .lazy_align => .int_lazy_align,
......@@ -6020,20 +6089,20 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60206089 .lazy_ty = lazy_ty,
60216090 }),
60226091 });
6023 return gop.set(@enumFromInt(ip.items.len - 1));
6092 return gop.put();
60246093 },
60256094 }
60266095 switch (int.ty) {
60276096 .u8_type => switch (int.storage) {
60286097 .big_int => |big_int| {
6029 ip.items.appendAssumeCapacity(.{
6098 items.appendAssumeCapacity(.{
60306099 .tag = .int_u8,
60316100 .data = big_int.to(u8) catch unreachable,
60326101 });
60336102 break :b;
60346103 },
60356104 inline .u64, .i64 => |x| {
6036 ip.items.appendAssumeCapacity(.{
6105 items.appendAssumeCapacity(.{
60376106 .tag = .int_u8,
60386107 .data = @as(u8, @intCast(x)),
60396108 });
......@@ -6043,14 +6112,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60436112 },
60446113 .u16_type => switch (int.storage) {
60456114 .big_int => |big_int| {
6046 ip.items.appendAssumeCapacity(.{
6115 items.appendAssumeCapacity(.{
60476116 .tag = .int_u16,
60486117 .data = big_int.to(u16) catch unreachable,
60496118 });
60506119 break :b;
60516120 },
60526121 inline .u64, .i64 => |x| {
6053 ip.items.appendAssumeCapacity(.{
6122 items.appendAssumeCapacity(.{
60546123 .tag = .int_u16,
60556124 .data = @as(u16, @intCast(x)),
60566125 });
......@@ -6060,14 +6129,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60606129 },
60616130 .u32_type => switch (int.storage) {
60626131 .big_int => |big_int| {
6063 ip.items.appendAssumeCapacity(.{
6132 items.appendAssumeCapacity(.{
60646133 .tag = .int_u32,
60656134 .data = big_int.to(u32) catch unreachable,
60666135 });
60676136 break :b;
60686137 },
60696138 inline .u64, .i64 => |x| {
6070 ip.items.appendAssumeCapacity(.{
6139 items.appendAssumeCapacity(.{
60716140 .tag = .int_u32,
60726141 .data = @as(u32, @intCast(x)),
60736142 });
......@@ -6078,14 +6147,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60786147 .i32_type => switch (int.storage) {
60796148 .big_int => |big_int| {
60806149 const casted = big_int.to(i32) catch unreachable;
6081 ip.items.appendAssumeCapacity(.{
6150 items.appendAssumeCapacity(.{
60826151 .tag = .int_i32,
60836152 .data = @as(u32, @bitCast(casted)),
60846153 });
60856154 break :b;
60866155 },
60876156 inline .u64, .i64 => |x| {
6088 ip.items.appendAssumeCapacity(.{
6157 items.appendAssumeCapacity(.{
60896158 .tag = .int_i32,
60906159 .data = @as(u32, @bitCast(@as(i32, @intCast(x)))),
60916160 });
......@@ -6096,7 +6165,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60966165 .usize_type => switch (int.storage) {
60976166 .big_int => |big_int| {
60986167 if (big_int.to(u32)) |casted| {
6099 ip.items.appendAssumeCapacity(.{
6168 items.appendAssumeCapacity(.{
61006169 .tag = .int_usize,
61016170 .data = casted,
61026171 });
......@@ -6105,7 +6174,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61056174 },
61066175 inline .u64, .i64 => |x| {
61076176 if (std.math.cast(u32, x)) |casted| {
6108 ip.items.appendAssumeCapacity(.{
6177 items.appendAssumeCapacity(.{
61096178 .tag = .int_usize,
61106179 .data = casted,
61116180 });
......@@ -6117,14 +6186,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61176186 .comptime_int_type => switch (int.storage) {
61186187 .big_int => |big_int| {
61196188 if (big_int.to(u32)) |casted| {
6120 ip.items.appendAssumeCapacity(.{
6189 items.appendAssumeCapacity(.{
61216190 .tag = .int_comptime_int_u32,
61226191 .data = casted,
61236192 });
61246193 break :b;
61256194 } else |_| {}
61266195 if (big_int.to(i32)) |casted| {
6127 ip.items.appendAssumeCapacity(.{
6196 items.appendAssumeCapacity(.{
61286197 .tag = .int_comptime_int_i32,
61296198 .data = @as(u32, @bitCast(casted)),
61306199 });
......@@ -6133,14 +6202,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61336202 },
61346203 inline .u64, .i64 => |x| {
61356204 if (std.math.cast(u32, x)) |casted| {
6136 ip.items.appendAssumeCapacity(.{
6205 items.appendAssumeCapacity(.{
61376206 .tag = .int_comptime_int_u32,
61386207 .data = casted,
61396208 });
61406209 break :b;
61416210 }
61426211 if (std.math.cast(i32, x)) |casted| {
6143 ip.items.appendAssumeCapacity(.{
6212 items.appendAssumeCapacity(.{
61446213 .tag = .int_comptime_int_i32,
61456214 .data = @as(u32, @bitCast(casted)),
61466215 });
......@@ -6154,35 +6223,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61546223 switch (int.storage) {
61556224 .big_int => |big_int| {
61566225 if (big_int.to(u32)) |casted| {
6157 ip.items.appendAssumeCapacity(.{
6226 items.appendAssumeCapacity(.{
61586227 .tag = .int_small,
61596228 .data = try ip.addExtra(gpa, IntSmall{
61606229 .ty = int.ty,
61616230 .value = casted,
61626231 }),
61636232 });
6164 return gop.set(@enumFromInt(ip.items.len - 1));
6233 return gop.put();
61656234 } else |_| {}
61666235
61676236 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
6168 try addInt(ip, gpa, int.ty, tag, big_int.limbs);
6237 try addInt(ip, gpa, tid, int.ty, tag, big_int.limbs);
61696238 },
61706239 inline .u64, .i64 => |x| {
61716240 if (std.math.cast(u32, x)) |casted| {
6172 ip.items.appendAssumeCapacity(.{
6241 items.appendAssumeCapacity(.{
61736242 .tag = .int_small,
61746243 .data = try ip.addExtra(gpa, IntSmall{
61756244 .ty = int.ty,
61766245 .value = casted,
61776246 }),
61786247 });
6179 return gop.set(@enumFromInt(ip.items.len - 1));
6248 return gop.put();
61806249 }
61816250
61826251 var buf: [2]Limb = undefined;
61836252 const big_int = BigIntMutable.init(&buf, x).toConst();
61846253 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
6185 try addInt(ip, gpa, int.ty, tag, big_int.limbs);
6254 try addInt(ip, gpa, tid, int.ty, tag, big_int.limbs);
61866255 },
61876256 .lazy_align, .lazy_size => unreachable,
61886257 }
......@@ -6190,7 +6259,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61906259
61916260 .err => |err| {
61926261 assert(ip.isErrorSetType(err.ty));
6193 ip.items.appendAssumeCapacity(.{
6262 items.appendAssumeCapacity(.{
61946263 .tag = .error_set_error,
61956264 .data = try ip.addExtra(gpa, err),
61966265 });
......@@ -6198,7 +6267,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61986267
61996268 .error_union => |error_union| {
62006269 assert(ip.isErrorUnionType(error_union.ty));
6201 ip.items.appendAssumeCapacity(switch (error_union.val) {
6270 items.appendAssumeCapacity(switch (error_union.val) {
62026271 .err_name => |err_name| .{
62036272 .tag = .error_union_error,
62046273 .data = try ip.addExtra(gpa, Key.Error{
......@@ -6216,7 +6285,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
62166285 });
62176286 },
62186287
6219 .enum_literal => |enum_literal| ip.items.appendAssumeCapacity(.{
6288 .enum_literal => |enum_literal| items.appendAssumeCapacity(.{
62206289 .tag = .enum_literal,
62216290 .data = @intFromEnum(enum_literal),
62226291 }),
......@@ -6228,50 +6297,50 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
62286297 .enum_type => assert(ip.typeOf(enum_tag.int) == ip.loadEnumType(enum_tag.ty).tag_ty),
62296298 else => unreachable,
62306299 }
6231 ip.items.appendAssumeCapacity(.{
6300 items.appendAssumeCapacity(.{
62326301 .tag = .enum_tag,
62336302 .data = try ip.addExtra(gpa, enum_tag),
62346303 });
62356304 },
62366305
6237 .empty_enum_value => |enum_or_union_ty| ip.items.appendAssumeCapacity(.{
6306 .empty_enum_value => |enum_or_union_ty| items.appendAssumeCapacity(.{
62386307 .tag = .only_possible_value,
62396308 .data = @intFromEnum(enum_or_union_ty),
62406309 }),
62416310
62426311 .float => |float| {
62436312 switch (float.ty) {
6244 .f16_type => ip.items.appendAssumeCapacity(.{
6313 .f16_type => items.appendAssumeCapacity(.{
62456314 .tag = .float_f16,
62466315 .data = @as(u16, @bitCast(float.storage.f16)),
62476316 }),
6248 .f32_type => ip.items.appendAssumeCapacity(.{
6317 .f32_type => items.appendAssumeCapacity(.{
62496318 .tag = .float_f32,
62506319 .data = @as(u32, @bitCast(float.storage.f32)),
62516320 }),
6252 .f64_type => ip.items.appendAssumeCapacity(.{
6321 .f64_type => items.appendAssumeCapacity(.{
62536322 .tag = .float_f64,
62546323 .data = try ip.addExtra(gpa, Float64.pack(float.storage.f64)),
62556324 }),
6256 .f80_type => ip.items.appendAssumeCapacity(.{
6325 .f80_type => items.appendAssumeCapacity(.{
62576326 .tag = .float_f80,
62586327 .data = try ip.addExtra(gpa, Float80.pack(float.storage.f80)),
62596328 }),
6260 .f128_type => ip.items.appendAssumeCapacity(.{
6329 .f128_type => items.appendAssumeCapacity(.{
62616330 .tag = .float_f128,
62626331 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),
62636332 }),
62646333 .c_longdouble_type => switch (float.storage) {
6265 .f80 => |x| ip.items.appendAssumeCapacity(.{
6334 .f80 => |x| items.appendAssumeCapacity(.{
62666335 .tag = .float_c_longdouble_f80,
62676336 .data = try ip.addExtra(gpa, Float80.pack(x)),
62686337 }),
6269 inline .f16, .f32, .f64, .f128 => |x| ip.items.appendAssumeCapacity(.{
6338 inline .f16, .f32, .f64, .f128 => |x| items.appendAssumeCapacity(.{
62706339 .tag = .float_c_longdouble_f128,
62716340 .data = try ip.addExtra(gpa, Float128.pack(x)),
62726341 }),
62736342 },
6274 .comptime_float_type => ip.items.appendAssumeCapacity(.{
6343 .comptime_float_type => items.appendAssumeCapacity(.{
62756344 .tag = .float_comptime_float,
62766345 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),
62776346 }),
......@@ -6331,11 +6400,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
63316400 }
63326401
63336402 if (len == 0) {
6334 ip.items.appendAssumeCapacity(.{
6403 items.appendAssumeCapacity(.{
63356404 .tag = .only_possible_value,
63366405 .data = @intFromEnum(aggregate.ty),
63376406 });
6338 return gop.set(@enumFromInt(ip.items.len - 1));
6407 return gop.put();
63396408 }
63406409
63416410 switch (ty_key) {
......@@ -6364,11 +6433,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
63646433 // This encoding works thanks to the fact that, as we just verified,
63656434 // the type itself contains a slice of values that can be provided
63666435 // in the aggregate fields.
6367 ip.items.appendAssumeCapacity(.{
6436 items.appendAssumeCapacity(.{
63686437 .tag = .only_possible_value,
63696438 .data = @intFromEnum(aggregate.ty),
63706439 });
6371 return gop.set(@enumFromInt(ip.items.len - 1));
6440 return gop.put();
63726441 },
63736442 else => {},
63746443 }
......@@ -6388,7 +6457,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
63886457 .storage = .{ .u64 = bytes.at(0, ip) },
63896458 } });
63906459 gop.assign(try ip.getOrPutKey(gpa, tid, key));
6391 try ip.items.ensureUnusedCapacity(gpa, 1);
6460 try items.ensureUnusedCapacity(1);
63926461 break :elem elem;
63936462 },
63946463 .elems => |elems| elems[0],
......@@ -6399,14 +6468,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
63996468 gpa,
64006469 @typeInfo(Repeated).Struct.fields.len,
64016470 );
6402 ip.items.appendAssumeCapacity(.{
6471 items.appendAssumeCapacity(.{
64036472 .tag = .repeated,
64046473 .data = ip.addExtraAssumeCapacity(Repeated{
64056474 .ty = aggregate.ty,
64066475 .elem_val = elem,
64076476 }),
64086477 });
6409 return gop.set(@enumFromInt(ip.items.len - 1));
6478 return gop.put();
64106479 }
64116480
64126481 if (child == .u8_type) bytes: {
......@@ -6442,21 +6511,21 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
64426511 @intCast(len_including_sentinel),
64436512 .maybe_embedded_nulls,
64446513 );
6445 ip.items.appendAssumeCapacity(.{
6514 items.appendAssumeCapacity(.{
64466515 .tag = .bytes,
64476516 .data = ip.addExtraAssumeCapacity(Bytes{
64486517 .ty = aggregate.ty,
64496518 .bytes = string,
64506519 }),
64516520 });
6452 return gop.set(@enumFromInt(ip.items.len - 1));
6521 return gop.put();
64536522 }
64546523
64556524 try ip.extra.ensureUnusedCapacity(
64566525 gpa,
64576526 @typeInfo(Tag.Aggregate).Struct.fields.len + @as(usize, @intCast(len_including_sentinel + 1)),
64586527 );
6459 ip.items.appendAssumeCapacity(.{
6528 items.appendAssumeCapacity(.{
64606529 .tag = .aggregate,
64616530 .data = ip.addExtraAssumeCapacity(Tag.Aggregate{
64626531 .ty = aggregate.ty,
......@@ -6469,7 +6538,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
64696538 .un => |un| {
64706539 assert(un.ty != .none);
64716540 assert(un.val != .none);
6472 ip.items.appendAssumeCapacity(.{
6541 items.appendAssumeCapacity(.{
64736542 .tag = .union_value,
64746543 .data = try ip.addExtra(gpa, un),
64756544 });
......@@ -6479,7 +6548,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
64796548 for (memoized_call.arg_values) |arg| assert(arg != .none);
64806549 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(MemoizedCall).Struct.fields.len +
64816550 memoized_call.arg_values.len);
6482 ip.items.appendAssumeCapacity(.{
6551 items.appendAssumeCapacity(.{
64836552 .tag = .memoized_call,
64846553 .data = ip.addExtraAssumeCapacity(MemoizedCall{
64856554 .func = memoized_call.func,
......@@ -6490,7 +6559,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
64906559 ip.extra.appendSliceAssumeCapacity(@ptrCast(memoized_call.arg_values));
64916560 },
64926561 }
6493 return gop.set(@enumFromInt(ip.items.len - 1));
6562 return gop.put();
64946563}
64956564
64966565pub const UnionTypeInit = struct {
......@@ -6544,6 +6613,8 @@ pub fn getUnionType(
65446613 defer gop.deinit();
65456614 if (gop == .existing) return .{ .existing = gop.existing };
65466615
6616 const items = ip.getLocal(tid).getMutableItems(gpa);
6617
65476618 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;
65486619 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
65496620 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeUnion).Struct.fields.len +
......@@ -6556,7 +6627,7 @@ pub fn getUnionType(
65566627 // zig fmt: on
65576628 ini.fields_len + // field types
65586629 align_elements_len);
6559 try ip.items.ensureUnusedCapacity(gpa, 1);
6630 try items.ensureUnusedCapacity(1);
65606631
65616632 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeUnion{
65626633 .flags = .{
......@@ -6582,7 +6653,7 @@ pub fn getUnionType(
65826653 },
65836654 });
65846655
6585 ip.items.appendAssumeCapacity(.{
6656 items.appendAssumeCapacity(.{
65866657 .tag = .type_union,
65876658 .data = extra_index,
65886659 });
......@@ -6618,7 +6689,7 @@ pub fn getUnionType(
66186689 }
66196690
66206691 return .{ .wip = .{
6621 .index = gop.set(@enumFromInt(ip.items.len - 1)),
6692 .index = gop.put(),
66226693 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,
66236694 .namespace_extra_index = if (ini.has_namespace)
66246695 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?
......@@ -6640,8 +6711,8 @@ pub const WipNamespaceType = struct {
66406711 }
66416712 return wip.index;
66426713 }
6643 pub fn cancel(wip: WipNamespaceType, ip: *InternPool) void {
6644 ip.remove(wip.index);
6714 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
6715 ip.remove(tid, wip.index);
66456716 }
66466717
66476718 pub const Result = union(enum) {
......@@ -6692,6 +6763,8 @@ pub fn getStructType(
66926763 defer gop.deinit();
66936764 if (gop == .existing) return .{ .existing = gop.existing };
66946765
6766 const items = ip.getLocal(tid).getMutableItems(gpa);
6767
66956768 const names_map = try ip.addMap(gpa, ini.fields_len);
66966769 errdefer _ = ip.maps.pop();
66976770
......@@ -6728,7 +6801,7 @@ pub fn getStructType(
67286801 .is_reified = ini.key == .reified,
67296802 },
67306803 });
6731 try ip.items.append(gpa, .{
6804 try items.append(.{
67326805 .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed,
67336806 .data = extra_index,
67346807 });
......@@ -6747,7 +6820,7 @@ pub fn getStructType(
67476820 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
67486821 }
67496822 return .{ .wip = .{
6750 .index = gop.set(@enumFromInt(ip.items.len - 1)),
6823 .index = gop.put(),
67516824 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,
67526825 .namespace_extra_index = if (ini.has_namespace)
67536826 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?
......@@ -6800,7 +6873,7 @@ pub fn getStructType(
68006873 .is_reified = ini.key == .reified,
68016874 },
68026875 });
6803 try ip.items.append(gpa, .{
6876 try items.append(.{
68046877 .tag = .type_struct,
68056878 .data = extra_index,
68066879 });
......@@ -6836,7 +6909,7 @@ pub fn getStructType(
68366909 }
68376910 ip.extra.appendNTimesAssumeCapacity(std.math.maxInt(u32), ini.fields_len);
68386911 return .{ .wip = .{
6839 .index = gop.set(@enumFromInt(ip.items.len - 1)),
6912 .index = gop.put(),
68406913 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,
68416914 .namespace_extra_index = namespace_extra_index,
68426915 } };
......@@ -6859,6 +6932,8 @@ pub fn getAnonStructType(
68596932 assert(ini.types.len == ini.values.len);
68606933 for (ini.types) |elem| assert(elem != .none);
68616934
6935 const items = ip.getLocal(tid).getMutableItems(gpa);
6936
68626937 const prev_extra_len = ip.extra.items.len;
68636938 const fields_len: u32 = @intCast(ini.types.len);
68646939
......@@ -6866,7 +6941,7 @@ pub fn getAnonStructType(
68666941 gpa,
68676942 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
68686943 );
6869 try ip.items.ensureUnusedCapacity(gpa, 1);
6944 try items.ensureUnusedCapacity(1);
68706945
68716946 const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{
68726947 .fields_len = fields_len,
......@@ -6888,11 +6963,11 @@ pub fn getAnonStructType(
68886963 return gop.existing;
68896964 }
68906965
6891 ip.items.appendAssumeCapacity(.{
6966 items.appendAssumeCapacity(.{
68926967 .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,
68936968 .data = extra_index,
68946969 });
6895 return gop.set(@enumFromInt(ip.items.len - 1));
6970 return gop.put();
68966971}
68976972
68986973/// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`.
......@@ -6930,7 +7005,9 @@ pub fn getFuncType(
69307005 @intFromBool(key.comptime_bits != 0) +
69317006 @intFromBool(key.noalias_bits != 0) +
69327007 params_len);
6933 try ip.items.ensureUnusedCapacity(gpa, 1);
7008
7009 const items = ip.getLocal(tid).getMutableItems(gpa);
7010 try items.ensureUnusedCapacity(1);
69347011
69357012 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
69367013 .params_len = params_len,
......@@ -6962,11 +7039,11 @@ pub fn getFuncType(
69627039 return gop.existing;
69637040 }
69647041
6965 ip.items.appendAssumeCapacity(.{
7042 items.appendAssumeCapacity(.{
69667043 .tag = .type_function,
69677044 .data = func_type_extra_index,
69687045 });
6969 return gop.set(@enumFromInt(ip.items.len - 1));
7046 return gop.put();
69707047}
69717048
69727049pub fn getExternFunc(
......@@ -6981,12 +7058,13 @@ pub fn getExternFunc(
69817058 const prev_extra_len = ip.extra.items.len;
69827059 const extra_index = try ip.addExtra(gpa, @as(Tag.ExternFunc, key));
69837060 errdefer ip.extra.items.len = prev_extra_len;
6984 try ip.items.append(gpa, .{
7061 const items = ip.getLocal(tid).getMutableItems(gpa);
7062 try items.append(.{
69857063 .tag = .extern_func,
69867064 .data = extra_index,
69877065 });
6988 errdefer ip.items.len -= 1;
6989 return gop.set(@enumFromInt(ip.items.len - 1));
7066 errdefer ip.items.lenPtr().* -= 1;
7067 return gop.put();
69907068}
69917069
69927070pub const GetFuncDeclKey = struct {
......@@ -7013,7 +7091,9 @@ pub fn getFuncDecl(
70137091 const prev_extra_len = ip.extra.items.len;
70147092
70157093 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncDecl).Struct.fields.len);
7016 try ip.items.ensureUnusedCapacity(gpa, 1);
7094
7095 const items = ip.getLocal(tid).getMutableItems(gpa);
7096 try items.ensureUnusedCapacity(1);
70177097
70187098 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{
70197099 .analysis = .{
......@@ -7043,11 +7123,11 @@ pub fn getFuncDecl(
70437123 return gop.existing;
70447124 }
70457125
7046 ip.items.appendAssumeCapacity(.{
7126 items.appendAssumeCapacity(.{
70477127 .tag = .func_decl,
70487128 .data = func_decl_extra_index,
70497129 });
7050 return gop.set(@enumFromInt(ip.items.len - 1));
7130 return gop.put();
70517131}
70527132
70537133pub const GetFuncDeclIesKey = struct {
......@@ -7095,7 +7175,26 @@ pub fn getFuncDeclIes(
70957175 @intFromBool(key.comptime_bits != 0) +
70967176 @intFromBool(key.noalias_bits != 0) +
70977177 params_len);
7098 try ip.items.ensureUnusedCapacity(gpa, 4);
7178
7179 const items = ip.getLocal(tid).getMutableItems(gpa);
7180 try items.ensureUnusedCapacity(4);
7181
7182 const func_index = Index.Unwrapped.wrap(.{
7183 .tid = tid,
7184 .index = items.lenPtr().* + 0,
7185 }, ip);
7186 const error_union_type = Index.Unwrapped.wrap(.{
7187 .tid = tid,
7188 .index = items.lenPtr().* + 1,
7189 }, ip);
7190 const error_set_type = Index.Unwrapped.wrap(.{
7191 .tid = tid,
7192 .index = items.lenPtr().* + 2,
7193 }, ip);
7194 const func_ty = Index.Unwrapped.wrap(.{
7195 .tid = tid,
7196 .index = items.lenPtr().* + 3,
7197 }, ip);
70997198
71007199 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{
71017200 .analysis = .{
......@@ -7107,36 +7206,18 @@ pub fn getFuncDeclIes(
71077206 .inferred_error_set = true,
71087207 },
71097208 .owner_decl = key.owner_decl,
7110 .ty = @enumFromInt(ip.items.len + 3),
7209 .ty = func_ty,
71117210 .zir_body_inst = key.zir_body_inst,
71127211 .lbrace_line = key.lbrace_line,
71137212 .rbrace_line = key.rbrace_line,
71147213 .lbrace_column = key.lbrace_column,
71157214 .rbrace_column = key.rbrace_column,
71167215 });
7117
7118 ip.items.appendAssumeCapacity(.{
7119 .tag = .func_decl,
7120 .data = func_decl_extra_index,
7121 });
71227216 ip.extra.appendAssumeCapacity(@intFromEnum(Index.none));
71237217
7124 ip.items.appendAssumeCapacity(.{
7125 .tag = .type_error_union,
7126 .data = ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7127 .error_set_type = @enumFromInt(ip.items.len + 1),
7128 .payload_type = key.bare_return_type,
7129 }),
7130 });
7131
7132 ip.items.appendAssumeCapacity(.{
7133 .tag = .type_inferred_error_set,
7134 .data = @intCast(ip.items.len - 2),
7135 });
7136
71377218 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
71387219 .params_len = params_len,
7139 .return_type = @enumFromInt(ip.items.len - 2),
7220 .return_type = error_union_type,
71407221 .flags = .{
71417222 .cc = key.cc orelse .Unspecified,
71427223 .is_var_args = key.is_var_args,
......@@ -7152,45 +7233,57 @@ pub fn getFuncDeclIes(
71527233 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);
71537234 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);
71547235 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));
7236
7237 items.appendSliceAssumeCapacity(.{
7238 .tag = &.{
7239 .func_decl,
7240 .type_error_union,
7241 .type_inferred_error_set,
7242 .type_function,
7243 },
7244 .data = &.{
7245 func_decl_extra_index,
7246 ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7247 .error_set_type = error_set_type,
7248 .payload_type = key.bare_return_type,
7249 }),
7250 @intFromEnum(func_index),
7251 func_type_extra_index,
7252 },
7253 });
71557254 errdefer {
7156 ip.items.len -= 4;
7255 items.lenPtr().* -= 4;
71577256 ip.extra.items.len = prev_extra_len;
71587257 }
71597258
7160 ip.items.appendAssumeCapacity(.{
7161 .tag = .type_function,
7162 .data = func_type_extra_index,
7163 });
7164
7165 var gop = try ip.getOrPutKey(gpa, tid, .{
7259 var func_gop = try ip.getOrPutKey(gpa, tid, .{
71667260 .func = extraFuncDecl(ip, func_decl_extra_index),
71677261 });
7168 defer gop.deinit();
7169 if (gop == .existing) {
7262 defer func_gop.deinit();
7263 if (func_gop == .existing) {
71707264 // An existing function type was found; undo the additions to our two arrays.
7171 ip.items.len -= 4;
7265 items.lenPtr().* -= 4;
71727266 ip.extra.items.len = prev_extra_len;
7173 return gop.existing;
7267 return func_gop.existing;
71747268 }
7175
7176 var eu_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
7177 .error_set_type = @enumFromInt(ip.items.len - 2),
7269 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
7270 .error_set_type = error_set_type,
71787271 .payload_type = key.bare_return_type,
71797272 } });
7180 defer eu_gop.deinit();
7181 var ies_gop = try ip.getOrPutKey(gpa, tid, .{
7182 .inferred_error_set_type = @enumFromInt(ip.items.len - 4),
7273 defer error_union_type_gop.deinit();
7274 var error_set_type_gop = try ip.getOrPutKey(gpa, tid, .{
7275 .inferred_error_set_type = func_index,
71837276 });
7184 defer ies_gop.deinit();
7185 var ty_gop = try ip.getOrPutKey(gpa, tid, .{
7277 defer error_set_type_gop.deinit();
7278 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{
71867279 .func_type = extraFuncType(ip, func_type_extra_index),
71877280 });
7188 defer ty_gop.deinit();
7189 const index = gop.set(@enumFromInt(ip.items.len - 4));
7190 _ = eu_gop.set(@enumFromInt(@intFromEnum(index) + 1));
7191 _ = ies_gop.set(@enumFromInt(@intFromEnum(index) + 2));
7192 _ = ty_gop.set(@enumFromInt(@intFromEnum(index) + 3));
7193 return index;
7281 defer func_ty_gop.deinit();
7282 assert(func_gop.putAt(3) == func_index);
7283 assert(error_union_type_gop.putAt(2) == error_union_type);
7284 assert(error_set_type_gop.putAt(1) == error_set_type);
7285 assert(func_ty_gop.putAt(0) == func_ty);
7286 return func_index;
71947287}
71957288
71967289pub fn getErrorSetType(
......@@ -7227,11 +7320,12 @@ pub fn getErrorSetType(
72277320 return gop.existing;
72287321 }
72297322
7230 try ip.items.append(gpa, .{
7323 const items = ip.getLocal(tid).getMutableItems(gpa);
7324 try items.append(.{
72317325 .tag = .type_error_set,
72327326 .data = error_set_extra_index,
72337327 });
7234 errdefer ip.items.len -= 1;
7328 errdefer items.lenPtr().* -= 1;
72357329
72367330 const names_map = try ip.addMap(gpa, names.len);
72377331 assert(names_map == predicted_names_map);
......@@ -7239,7 +7333,7 @@ pub fn getErrorSetType(
72397333
72407334 addStringsToMap(ip, names_map, names);
72417335
7242 return gop.set(@enumFromInt(ip.items.len - 1));
7336 return gop.put();
72437337}
72447338
72457339pub const GetFuncInstanceKey = struct {
......@@ -7312,15 +7406,14 @@ pub fn getFuncInstance(
73127406 return gop.existing;
73137407 }
73147408
7315 const func_index: Index = @enumFromInt(ip.items.len);
7316
7317 try ip.items.append(gpa, .{
7409 const items = ip.getLocal(tid).getMutableItems(gpa);
7410 const func_index = Index.Unwrapped.wrap(.{ .tid = tid, .index = items.lenPtr().* }, ip);
7411 try items.append(.{
73187412 .tag = .func_instance,
73197413 .data = func_extra_index,
73207414 });
7321 errdefer ip.items.len -= 1;
7322
7323 return gop.set(try finishFuncInstance(
7415 errdefer items.lenPtr().* -= 1;
7416 try finishFuncInstance(
73247417 ip,
73257418 gpa,
73267419 tid,
......@@ -7329,7 +7422,8 @@ pub fn getFuncInstance(
73297422 func_extra_index,
73307423 arg.alignment,
73317424 arg.section,
7332 ));
7425 );
7426 return gop.put();
73337427}
73347428
73357429/// This function exists separately than `getFuncInstance` because it needs to
......@@ -7361,12 +7455,26 @@ pub fn getFuncInstanceIes(
73617455 @typeInfo(Tag.TypeFunction).Struct.fields.len +
73627456 @intFromBool(arg.noalias_bits != 0) +
73637457 params_len);
7364 try ip.items.ensureUnusedCapacity(gpa, 4);
73657458
7366 const func_index: Index = @enumFromInt(ip.items.len);
7367 const error_union_type: Index = @enumFromInt(ip.items.len + 1);
7368 const error_set_type: Index = @enumFromInt(ip.items.len + 2);
7369 const func_ty: Index = @enumFromInt(ip.items.len + 3);
7459 const items = ip.getLocal(tid).getMutableItems(gpa);
7460 try items.ensureUnusedCapacity(4);
7461
7462 const func_index = Index.Unwrapped.wrap(.{
7463 .tid = tid,
7464 .index = items.lenPtr().* + 0,
7465 }, ip);
7466 const error_union_type = Index.Unwrapped.wrap(.{
7467 .tid = tid,
7468 .index = items.lenPtr().* + 1,
7469 }, ip);
7470 const error_set_type = Index.Unwrapped.wrap(.{
7471 .tid = tid,
7472 .index = items.lenPtr().* + 2,
7473 }, ip);
7474 const func_ty = Index.Unwrapped.wrap(.{
7475 .tid = tid,
7476 .index = items.lenPtr().* + 3,
7477 }, ip);
73707478
73717479 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{
73727480 .analysis = .{
......@@ -7406,57 +7514,52 @@ pub fn getFuncInstanceIes(
74067514 if (arg.noalias_bits != 0) ip.extra.appendAssumeCapacity(arg.noalias_bits);
74077515 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.param_types));
74087516
7409 // TODO: add appendSliceAssumeCapacity to MultiArrayList.
7410 ip.items.appendAssumeCapacity(.{
7411 .tag = .func_instance,
7412 .data = func_extra_index,
7413 });
7414 ip.items.appendAssumeCapacity(.{
7415 .tag = .type_error_union,
7416 .data = ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7417 .error_set_type = error_set_type,
7418 .payload_type = arg.bare_return_type,
7419 }),
7420 });
7421 ip.items.appendAssumeCapacity(.{
7422 .tag = .type_inferred_error_set,
7423 .data = @intFromEnum(func_index),
7424 });
7425 ip.items.appendAssumeCapacity(.{
7426 .tag = .type_function,
7427 .data = func_type_extra_index,
7517 items.appendSliceAssumeCapacity(.{
7518 .tag = &.{
7519 .func_instance,
7520 .type_error_union,
7521 .type_inferred_error_set,
7522 .type_function,
7523 },
7524 .data = &.{
7525 func_extra_index,
7526 ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7527 .error_set_type = error_set_type,
7528 .payload_type = arg.bare_return_type,
7529 }),
7530 @intFromEnum(func_index),
7531 func_type_extra_index,
7532 },
74287533 });
74297534 errdefer {
7430 ip.items.len -= 4;
7535 items.lenPtr().* -= 4;
74317536 ip.extra.items.len = prev_extra_len;
74327537 }
74337538
7434 var gop = try ip.getOrPutKey(gpa, tid, .{
7539 var func_gop = try ip.getOrPutKey(gpa, tid, .{
74357540 .func = extraFuncInstance(ip, func_extra_index),
74367541 });
7437 defer gop.deinit();
7438 if (gop == .existing) {
7542 defer func_gop.deinit();
7543 if (func_gop == .existing) {
74397544 // Hot path: undo the additions to our two arrays.
7440 ip.items.len -= 4;
7545 items.lenPtr().* -= 4;
74417546 ip.extra.items.len = prev_extra_len;
7442 return gop.existing;
7547 return func_gop.existing;
74437548 }
7444
7445 // Synchronize the map with items.
7446 var eu_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
7549 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
74477550 .error_set_type = error_set_type,
74487551 .payload_type = arg.bare_return_type,
74497552 } });
7450 defer eu_gop.deinit();
7451 var ies_gop = try ip.getOrPutKey(gpa, tid, .{
7553 defer error_union_type_gop.deinit();
7554 var error_set_type_gop = try ip.getOrPutKey(gpa, tid, .{
74527555 .inferred_error_set_type = func_index,
74537556 });
7454 defer ies_gop.deinit();
7455 var ty_gop = try ip.getOrPutKey(gpa, tid, .{
7557 defer error_set_type_gop.deinit();
7558 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{
74567559 .func_type = extraFuncType(ip, func_type_extra_index),
74577560 });
7458 defer ty_gop.deinit();
7459 const index = gop.set(try finishFuncInstance(
7561 defer func_ty_gop.deinit();
7562 try finishFuncInstance(
74607563 ip,
74617564 gpa,
74627565 tid,
......@@ -7465,11 +7568,12 @@ pub fn getFuncInstanceIes(
74657568 func_extra_index,
74667569 arg.alignment,
74677570 arg.section,
7468 ));
7469 _ = eu_gop.set(@enumFromInt(@intFromEnum(index) + 1));
7470 _ = ies_gop.set(@enumFromInt(@intFromEnum(index) + 2));
7471 _ = ty_gop.set(@enumFromInt(@intFromEnum(index) + 3));
7472 return index;
7571 );
7572 assert(func_gop.putAt(3) == func_index);
7573 assert(error_union_type_gop.putAt(2) == error_union_type);
7574 assert(error_set_type_gop.putAt(1) == error_set_type);
7575 assert(func_ty_gop.putAt(0) == func_ty);
7576 return func_index;
74737577}
74747578
74757579fn finishFuncInstance(
......@@ -7481,7 +7585,7 @@ fn finishFuncInstance(
74817585 func_extra_index: u32,
74827586 alignment: Alignment,
74837587 section: OptionalNullTerminatedString,
7484) Allocator.Error!Index {
7588) Allocator.Error!void {
74857589 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));
74867590 const decl_index = try ip.createDecl(gpa, .{
74877591 .name = undefined,
......@@ -7510,8 +7614,6 @@ fn finishFuncInstance(
75107614 decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
75117615 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
75127616 }, .no_embedded_nulls);
7513
7514 return func_index;
75157617}
75167618
75177619pub const EnumTypeInit = struct {
......@@ -7589,8 +7691,8 @@ pub const WipEnumType = struct {
75897691 return null;
75907692 }
75917693
7592 pub fn cancel(wip: WipEnumType, ip: *InternPool) void {
7593 ip.remove(wip.index);
7694 pub fn cancel(wip: WipEnumType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
7695 ip.remove(tid, wip.index);
75947696 }
75957697
75967698 pub const Result = union(enum) {
......@@ -7618,7 +7720,8 @@ pub fn getEnumType(
76187720 defer gop.deinit();
76197721 if (gop == .existing) return .{ .existing = gop.existing };
76207722
7621 try ip.items.ensureUnusedCapacity(gpa, 1);
7723 const items = ip.getLocal(tid).getMutableItems(gpa);
7724 try items.ensureUnusedCapacity(1);
76227725
76237726 const names_map = try ip.addMap(gpa, ini.fields_len);
76247727 errdefer _ = ip.maps.pop();
......@@ -7650,7 +7753,7 @@ pub fn getEnumType(
76507753 inline else => |x| x.zir_index,
76517754 }.toOptional(),
76527755 });
7653 ip.items.appendAssumeCapacity(.{
7756 items.appendAssumeCapacity(.{
76547757 .tag = .type_enum_auto,
76557758 .data = extra_index,
76567759 });
......@@ -7661,7 +7764,7 @@ pub fn getEnumType(
76617764 const names_start = ip.extra.items.len;
76627765 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);
76637766 return .{ .wip = .{
7664 .index = gop.set(@enumFromInt(ip.items.len - 1)),
7767 .index = gop.put(),
76657768 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
76667769 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
76677770 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
......@@ -7706,7 +7809,7 @@ pub fn getEnumType(
77067809 inline else => |x| x.zir_index,
77077810 }.toOptional(),
77087811 });
7709 ip.items.appendAssumeCapacity(.{
7812 items.appendAssumeCapacity(.{
77107813 .tag = switch (ini.tag_mode) {
77117814 .auto => unreachable,
77127815 .explicit => .type_enum_explicit,
......@@ -7725,7 +7828,7 @@ pub fn getEnumType(
77257828 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);
77267829 }
77277830 return .{ .wip = .{
7728 .index = gop.set(@enumFromInt(ip.items.len - 1)),
7831 .index = gop.put(),
77297832 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
77307833 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
77317834 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
......@@ -7760,7 +7863,8 @@ pub fn getGeneratedTagEnumType(
77607863 assert(ip.isIntegerType(ini.tag_ty));
77617864 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);
77627865
7763 try ip.items.ensureUnusedCapacity(gpa, 1);
7866 const items = ip.getLocal(tid).getMutableItems(gpa);
7867 try items.ensureUnusedCapacity(1);
77647868
77657869 const names_map = try ip.addMap(gpa, ini.names.len);
77667870 errdefer _ = ip.maps.pop();
......@@ -7774,7 +7878,7 @@ pub fn getGeneratedTagEnumType(
77747878 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +
77757879 1 + // owner_union
77767880 fields_len); // field names
7777 ip.items.appendAssumeCapacity(.{
7881 items.appendAssumeCapacity(.{
77787882 .tag = .type_enum_auto,
77797883 .data = ip.addExtraAssumeCapacity(EnumAuto{
77807884 .decl = ini.decl,
......@@ -7803,7 +7907,7 @@ pub fn getGeneratedTagEnumType(
78037907 // We don't clean up the values map on error!
78047908 errdefer @compileError("error path leaks values_map");
78057909
7806 ip.items.appendAssumeCapacity(.{
7910 items.appendAssumeCapacity(.{
78077911 .tag = switch (ini.tag_mode) {
78087912 .explicit => .type_enum_explicit,
78097913 .nonexhaustive => .type_enum_nonexhaustive,
......@@ -7835,7 +7939,7 @@ pub fn getGeneratedTagEnumType(
78357939 .generated_tag = .{ .union_type = ini.owner_union_ty },
78367940 } });
78377941 defer gop.deinit();
7838 return gop.set(@enumFromInt(ip.items.len - 1));
7942 return gop.put();
78397943}
78407944
78417945pub const OpaqueTypeInit = struct {
......@@ -7870,7 +7974,10 @@ pub fn getOpaqueType(
78707974 } });
78717975 defer gop.deinit();
78727976 if (gop == .existing) return .{ .existing = gop.existing };
7873 try ip.items.ensureUnusedCapacity(gpa, 1);
7977
7978 const items = ip.getLocal(tid).getMutableItems(gpa);
7979 try items.ensureUnusedCapacity(1);
7980
78747981 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeOpaque).Struct.fields.len + switch (ini.key) {
78757982 .declared => |d| d.captures.len,
78767983 .reified => 0,
......@@ -7886,7 +7993,7 @@ pub fn getOpaqueType(
78867993 .reified => std.math.maxInt(u32),
78877994 },
78887995 });
7889 ip.items.appendAssumeCapacity(.{
7996 items.appendAssumeCapacity(.{
78907997 .tag = .type_opaque,
78917998 .data = extra_index,
78927999 });
......@@ -7895,7 +8002,7 @@ pub fn getOpaqueType(
78958002 .reified => {},
78968003 }
78978004 return .{ .wip = .{
7898 .index = gop.set(@enumFromInt(ip.items.len - 1)),
8005 .index = gop.put(),
78998006 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,
79008007 .namespace_extra_index = if (ini.has_namespace)
79018008 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?
......@@ -7958,37 +8065,50 @@ fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex
79588065/// This operation only happens under compile error conditions.
79598066/// Leak the index until the next garbage collection.
79608067/// Invalidates all references to this index.
7961pub fn remove(ip: *InternPool, index: Index) void {
8068pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
8069 const unwrapped = index.unwrap(ip);
79628070 if (@intFromEnum(index) < static_keys.len) {
8071 if (tid != .main or unwrapped.tid != .main) @panic("This operation is impossible to be thread-safe");
79638072 // The item being removed replaced a special index via `InternPool.resolveBuiltinType`.
79648073 // Restore the original item at this index.
8074 var items = ip.getLocalShared(unwrapped.tid).items.view();
79658075 switch (static_keys[@intFromEnum(index)]) {
7966 .simple_type => |s| {
7967 ip.items.set(@intFromEnum(index), .{
7968 .tag = .simple_type,
7969 .data = @intFromEnum(s),
7970 });
7971 },
8076 .simple_type => |s| items.set(@intFromEnum(index), .{
8077 .tag = .simple_type,
8078 .data = @intFromEnum(s),
8079 }),
79728080 else => unreachable,
79738081 }
79748082 return;
79758083 }
79768084
7977 if (@intFromEnum(index) == ip.items.len - 1) {
7978 // Happy case - we can just drop the item without affecting any other indices.
7979 ip.items.len -= 1;
7980 } else {
7981 // We must preserve the item so that indices following it remain valid.
7982 // Thus, we will rewrite the tag to `removed`, leaking the item until
7983 // next GC but causing `KeyAdapter` to ignore it.
7984 ip.items.set(@intFromEnum(index), .{ .tag = .removed, .data = undefined });
8085 if (unwrapped.tid == tid) {
8086 const items_len = &ip.getLocal(tid).mutate.items.len;
8087 if (unwrapped.index == items_len.* - 1) {
8088 // Happy case - we can just drop the item without affecting any other indices.
8089 items_len.* -= 1;
8090 return;
8091 }
79858092 }
8093
8094 // We must preserve the item so that indices following it remain valid.
8095 // Thus, we will rewrite the tag to `removed`, leaking the item until
8096 // next GC but causing `KeyAdapter` to ignore it.
8097 const items = ip.getLocalShared(unwrapped.tid).items.view();
8098 @atomicStore(Tag, &items.items(.tag)[unwrapped.index], .removed, .release);
79868099}
79878100
7988fn addInt(ip: *InternPool, gpa: Allocator, ty: Index, tag: Tag, limbs: []const Limb) !void {
8101fn addInt(
8102 ip: *InternPool,
8103 gpa: Allocator,
8104 tid: Zcu.PerThread.Id,
8105 ty: Index,
8106 tag: Tag,
8107 limbs: []const Limb,
8108) !void {
79898109 const limbs_len: u32 = @intCast(limbs.len);
79908110 try ip.reserveLimbs(gpa, @typeInfo(Int).Struct.fields.len + limbs_len);
7991 ip.items.appendAssumeCapacity(.{
8111 ip.getLocal(tid).getMutableItems(gpa).appendAssumeCapacity(.{
79928112 .tag = tag,
79938113 .data = ip.addLimbsExtraAssumeCapacity(Int{
79948114 .ty = ty,
......@@ -8235,13 +8355,13 @@ pub fn childType(ip: *const InternPool, i: Index) Index {
82358355}
82368356
82378357/// Given a slice type, returns the type of the ptr field.
8238pub fn slicePtrType(ip: *const InternPool, i: Index) Index {
8239 switch (i) {
8358pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
8359 switch (index) {
82408360 .slice_const_u8_type => return .manyptr_const_u8_type,
82418361 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
82428362 else => {},
82438363 }
8244 const item = ip.items.get(@intFromEnum(i));
8364 const item = index.getItem(ip);
82458365 switch (item.tag) {
82468366 .type_slice => return @enumFromInt(item.data),
82478367 else => unreachable, // not a slice type
......@@ -8249,8 +8369,8 @@ pub fn slicePtrType(ip: *const InternPool, i: Index) Index {
82498369}
82508370
82518371/// Given a slice value, returns the value of the ptr field.
8252pub fn slicePtr(ip: *const InternPool, i: Index) Index {
8253 const item = ip.items.get(@intFromEnum(i));
8372pub fn slicePtr(ip: *const InternPool, index: Index) Index {
8373 const item = index.getItem(ip);
82548374 switch (item.tag) {
82558375 .ptr_slice => return ip.extraData(PtrSlice, item.data).ptr,
82568376 else => unreachable, // not a slice value
......@@ -8258,8 +8378,8 @@ pub fn slicePtr(ip: *const InternPool, i: Index) Index {
82588378}
82598379
82608380/// Given a slice value, returns the value of the len field.
8261pub fn sliceLen(ip: *const InternPool, i: Index) Index {
8262 const item = ip.items.get(@intFromEnum(i));
8381pub fn sliceLen(ip: *const InternPool, index: Index) Index {
8382 const item = index.getItem(ip);
82638383 switch (item.tag) {
82648384 .ptr_slice => return ip.extraData(PtrSlice, item.data).len,
82658385 else => unreachable, // not a slice value
......@@ -8296,8 +8416,6 @@ pub fn getCoerced(
82968416 const old_ty = ip.typeOf(val);
82978417 if (old_ty == new_ty) return val;
82988418
8299 const tags = ip.items.items(.tag);
8300
83018419 switch (val) {
83028420 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),
83038421 .null_value => {
......@@ -8323,15 +8441,14 @@ pub fn getCoerced(
83238441 } }),
83248442 };
83258443 },
8326 else => switch (tags[@intFromEnum(val)]) {
8444 else => switch (val.getTag(ip)) {
83278445 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
83288446 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
83298447 .func_coerced => {
8330 const extra_index = ip.items.items(.data)[@intFromEnum(val)];
83318448 const func: Index = @enumFromInt(
8332 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],
8449 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],
83338450 );
8334 switch (tags[@intFromEnum(func)]) {
8451 switch (func.getTag(ip)) {
83358452 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
83368453 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
83378454 else => unreachable,
......@@ -8575,10 +8692,8 @@ fn getCoercedFuncDecl(
85758692 val: Index,
85768693 new_ty: Index,
85778694) Allocator.Error!Index {
8578 const datas = ip.items.items(.data);
8579 const extra_index = datas[@intFromEnum(val)];
85808695 const prev_ty: Index = @enumFromInt(
8581 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],
8696 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],
85828697 );
85838698 if (new_ty == prev_ty) return val;
85848699 return getCoercedFunc(ip, gpa, tid, val, new_ty);
......@@ -8591,10 +8706,8 @@ fn getCoercedFuncInstance(
85918706 val: Index,
85928707 new_ty: Index,
85938708) Allocator.Error!Index {
8594 const datas = ip.items.items(.data);
8595 const extra_index = datas[@intFromEnum(val)];
85968709 const prev_ty: Index = @enumFromInt(
8597 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],
8710 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],
85988711 );
85998712 if (new_ty == prev_ty) return val;
86008713 return getCoercedFunc(ip, gpa, tid, val, new_ty);
......@@ -8609,7 +8722,9 @@ fn getCoercedFunc(
86098722) Allocator.Error!Index {
86108723 const prev_extra_len = ip.extra.items.len;
86118724 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len);
8612 try ip.items.ensureUnusedCapacity(gpa, 1);
8725
8726 const items = ip.getLocal(tid).getMutableItems(gpa);
8727 try items.ensureUnusedCapacity(1);
86138728
86148729 const extra_index = ip.addExtraAssumeCapacity(Tag.FuncCoerced{
86158730 .ty = ty,
......@@ -8626,11 +8741,11 @@ fn getCoercedFunc(
86268741 return gop.existing;
86278742 }
86288743
8629 ip.items.appendAssumeCapacity(.{
8744 items.appendAssumeCapacity(.{
86308745 .tag = .func_coerced,
86318746 .data = extra_index,
86328747 });
8633 return gop.set(@enumFromInt(ip.items.len - 1));
8748 return gop.put();
86348749}
86358750
86368751/// Asserts `val` has an integer type.
......@@ -8661,11 +8776,9 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, in
86618776}
86628777
86638778pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {
8664 assert(val != .none);
8665 const tags = ip.items.items(.tag);
8666 const datas = ip.items.items(.data);
8667 switch (tags[@intFromEnum(val)]) {
8668 .type_function => return extraFuncType(ip, datas[@intFromEnum(val)]),
8779 const item = val.getItem(ip);
8780 switch (item.tag) {
8781 .type_function => return extraFuncType(ip, item.data),
86698782 else => return null,
86708783 }
86718784}
......@@ -8686,7 +8799,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
86868799 .c_ulonglong_type,
86878800 .comptime_int_type,
86888801 => true,
8689 else => switch (ip.items.items(.tag)[@intFromEnum(ty)]) {
8802 else => switch (ty.getTag(ip)) {
86908803 .type_int_signed,
86918804 .type_int_unsigned,
86928805 => true,
......@@ -8762,7 +8875,7 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
87628875
87638876/// The is only legal because the initializer is not part of the hash.
87648877pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
8765 const item = ip.items.get(@intFromEnum(index));
8878 const item = index.getItem(ip);
87668879 assert(item.tag == .variable);
87678880 ip.extra.items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?] = @intFromEnum(init_index);
87688881}
......@@ -8773,7 +8886,11 @@ pub fn dump(ip: *const InternPool) void {
87738886}
87748887
87758888fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8776 const items_size = (1 + 4) * ip.items.len;
8889 var items_len: usize = 0;
8890 for (ip.locals) |*local| {
8891 items_len += local.mutate.items.len;
8892 }
8893 const items_size = (1 + 4) * items_len;
87778894 const extra_size = 4 * ip.extra.items.len;
87788895 const limbs_size = 8 * ip.limbs.items.len;
87798896 const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl);
......@@ -8790,7 +8907,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
87908907 \\
87918908 , .{
87928909 total_size,
8793 ip.items.len,
8910 items_len,
87948911 items_size,
87958912 ip.extra.items.len,
87968913 extra_size,
......@@ -8800,217 +8917,221 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
88008917 decls_size,
88018918 });
88028919
8803 const tags = ip.items.items(.tag);
8804 const datas = ip.items.items(.data);
88058920 const TagStats = struct {
88068921 count: usize = 0,
88078922 bytes: usize = 0,
88088923 };
88098924 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);
8810 for (tags, datas) |tag, data| {
8811 const gop = try counts.getOrPut(tag);
8812 if (!gop.found_existing) gop.value_ptr.* = .{};
8813 gop.value_ptr.count += 1;
8814 gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) {
8815 // Note that in this case, we have technically leaked some extra data
8816 // bytes which we do not account for here.
8817 .removed => 0,
8818
8819 .type_int_signed => 0,
8820 .type_int_unsigned => 0,
8821 .type_array_small => @sizeOf(Vector),
8822 .type_array_big => @sizeOf(Array),
8823 .type_vector => @sizeOf(Vector),
8824 .type_pointer => @sizeOf(Tag.TypePointer),
8825 .type_slice => 0,
8826 .type_optional => 0,
8827 .type_anyframe => 0,
8828 .type_error_union => @sizeOf(Key.ErrorUnionType),
8829 .type_anyerror_union => 0,
8830 .type_error_set => b: {
8831 const info = ip.extraData(Tag.ErrorSet, data);
8832 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
8833 },
8834 .type_inferred_error_set => 0,
8835 .type_enum_explicit, .type_enum_nonexhaustive => b: {
8836 const info = ip.extraData(EnumExplicit, data);
8837 var ints = @typeInfo(EnumExplicit).Struct.fields.len;
8838 if (info.zir_index == .none) ints += 1;
8839 ints += if (info.captures_len != std.math.maxInt(u32))
8840 info.captures_len
8841 else
8842 @typeInfo(PackedU64).Struct.fields.len;
8843 ints += info.fields_len;
8844 if (info.values_map != .none) ints += info.fields_len;
8845 break :b @sizeOf(u32) * ints;
8846 },
8847 .type_enum_auto => b: {
8848 const info = ip.extraData(EnumAuto, data);
8849 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;
8850 break :b @sizeOf(u32) * ints;
8851 },
8852 .type_opaque => b: {
8853 const info = ip.extraData(Tag.TypeOpaque, data);
8854 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;
8855 break :b @sizeOf(u32) * ints;
8856 },
8857 .type_struct => b: {
8858 if (data == 0) break :b 0;
8859 const extra = ip.extraDataTrail(Tag.TypeStruct, data);
8860 const info = extra.data;
8861 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;
8862 if (info.flags.any_captures) {
8863 const captures_len = ip.extra.items[extra.end];
8864 ints += 1 + captures_len;
8865 }
8866 ints += info.fields_len; // types
8867 if (!info.flags.is_tuple) {
8868 ints += 1; // names_map
8869 ints += info.fields_len; // names
8870 }
8871 if (info.flags.any_default_inits)
8872 ints += info.fields_len; // inits
8873 ints += @intFromBool(info.flags.has_namespace); // namespace
8874 if (info.flags.any_aligned_fields)
8875 ints += (info.fields_len + 3) / 4; // aligns
8876 if (info.flags.any_comptime_fields)
8877 ints += (info.fields_len + 31) / 32; // comptime bits
8878 if (!info.flags.is_extern)
8879 ints += info.fields_len; // runtime order
8880 ints += info.fields_len; // offsets
8881 break :b @sizeOf(u32) * ints;
8882 },
8883 .type_struct_anon => b: {
8884 const info = ip.extraData(TypeStructAnon, data);
8885 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);
8886 },
8887 .type_struct_packed => b: {
8888 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
8889 const captures_len = if (extra.data.flags.any_captures)
8890 ip.extra.items[extra.end]
8891 else
8892 0;
8893 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
8894 @intFromBool(extra.data.flags.any_captures) + captures_len +
8895 extra.data.fields_len * 2);
8896 },
8897 .type_struct_packed_inits => b: {
8898 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
8899 const captures_len = if (extra.data.flags.any_captures)
8900 ip.extra.items[extra.end]
8901 else
8902 0;
8903 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
8904 @intFromBool(extra.data.flags.any_captures) + captures_len +
8905 extra.data.fields_len * 3);
8906 },
8907 .type_tuple_anon => b: {
8908 const info = ip.extraData(TypeStructAnon, data);
8909 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);
8910 },
8911
8912 .type_union => b: {
8913 const extra = ip.extraDataTrail(Tag.TypeUnion, data);
8914 const captures_len = if (extra.data.flags.any_captures)
8915 ip.extra.items[extra.end]
8916 else
8917 0;
8918 const per_field = @sizeOf(u32); // field type
8919 // 1 byte per field for alignment, rounded up to the nearest 4 bytes
8920 const alignments = if (extra.data.flags.any_aligned_fields)
8921 ((extra.data.fields_len + 3) / 4) * 4
8922 else
8923 0;
8924 break :b @sizeOf(Tag.TypeUnion) +
8925 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +
8926 (extra.data.fields_len * per_field) + alignments;
8927 },
8925 for (ip.locals) |*local| {
8926 const items = local.shared.items.view();
8927 for (
8928 items.items(.tag)[0..local.mutate.items.len],
8929 items.items(.data)[0..local.mutate.items.len],
8930 ) |tag, data| {
8931 const gop = try counts.getOrPut(tag);
8932 if (!gop.found_existing) gop.value_ptr.* = .{};
8933 gop.value_ptr.count += 1;
8934 gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) {
8935 // Note that in this case, we have technically leaked some extra data
8936 // bytes which we do not account for here.
8937 .removed => 0,
8938
8939 .type_int_signed => 0,
8940 .type_int_unsigned => 0,
8941 .type_array_small => @sizeOf(Vector),
8942 .type_array_big => @sizeOf(Array),
8943 .type_vector => @sizeOf(Vector),
8944 .type_pointer => @sizeOf(Tag.TypePointer),
8945 .type_slice => 0,
8946 .type_optional => 0,
8947 .type_anyframe => 0,
8948 .type_error_union => @sizeOf(Key.ErrorUnionType),
8949 .type_anyerror_union => 0,
8950 .type_error_set => b: {
8951 const info = ip.extraData(Tag.ErrorSet, data);
8952 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
8953 },
8954 .type_inferred_error_set => 0,
8955 .type_enum_explicit, .type_enum_nonexhaustive => b: {
8956 const info = ip.extraData(EnumExplicit, data);
8957 var ints = @typeInfo(EnumExplicit).Struct.fields.len;
8958 if (info.zir_index == .none) ints += 1;
8959 ints += if (info.captures_len != std.math.maxInt(u32))
8960 info.captures_len
8961 else
8962 @typeInfo(PackedU64).Struct.fields.len;
8963 ints += info.fields_len;
8964 if (info.values_map != .none) ints += info.fields_len;
8965 break :b @sizeOf(u32) * ints;
8966 },
8967 .type_enum_auto => b: {
8968 const info = ip.extraData(EnumAuto, data);
8969 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;
8970 break :b @sizeOf(u32) * ints;
8971 },
8972 .type_opaque => b: {
8973 const info = ip.extraData(Tag.TypeOpaque, data);
8974 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;
8975 break :b @sizeOf(u32) * ints;
8976 },
8977 .type_struct => b: {
8978 if (data == 0) break :b 0;
8979 const extra = ip.extraDataTrail(Tag.TypeStruct, data);
8980 const info = extra.data;
8981 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;
8982 if (info.flags.any_captures) {
8983 const captures_len = ip.extra.items[extra.end];
8984 ints += 1 + captures_len;
8985 }
8986 ints += info.fields_len; // types
8987 if (!info.flags.is_tuple) {
8988 ints += 1; // names_map
8989 ints += info.fields_len; // names
8990 }
8991 if (info.flags.any_default_inits)
8992 ints += info.fields_len; // inits
8993 ints += @intFromBool(info.flags.has_namespace); // namespace
8994 if (info.flags.any_aligned_fields)
8995 ints += (info.fields_len + 3) / 4; // aligns
8996 if (info.flags.any_comptime_fields)
8997 ints += (info.fields_len + 31) / 32; // comptime bits
8998 if (!info.flags.is_extern)
8999 ints += info.fields_len; // runtime order
9000 ints += info.fields_len; // offsets
9001 break :b @sizeOf(u32) * ints;
9002 },
9003 .type_struct_anon => b: {
9004 const info = ip.extraData(TypeStructAnon, data);
9005 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);
9006 },
9007 .type_struct_packed => b: {
9008 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
9009 const captures_len = if (extra.data.flags.any_captures)
9010 ip.extra.items[extra.end]
9011 else
9012 0;
9013 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
9014 @intFromBool(extra.data.flags.any_captures) + captures_len +
9015 extra.data.fields_len * 2);
9016 },
9017 .type_struct_packed_inits => b: {
9018 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
9019 const captures_len = if (extra.data.flags.any_captures)
9020 ip.extra.items[extra.end]
9021 else
9022 0;
9023 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
9024 @intFromBool(extra.data.flags.any_captures) + captures_len +
9025 extra.data.fields_len * 3);
9026 },
9027 .type_tuple_anon => b: {
9028 const info = ip.extraData(TypeStructAnon, data);
9029 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);
9030 },
89289031
8929 .type_function => b: {
8930 const info = ip.extraData(Tag.TypeFunction, data);
8931 break :b @sizeOf(Tag.TypeFunction) +
8932 (@sizeOf(Index) * info.params_len) +
8933 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
8934 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
8935 },
9032 .type_union => b: {
9033 const extra = ip.extraDataTrail(Tag.TypeUnion, data);
9034 const captures_len = if (extra.data.flags.any_captures)
9035 ip.extra.items[extra.end]
9036 else
9037 0;
9038 const per_field = @sizeOf(u32); // field type
9039 // 1 byte per field for alignment, rounded up to the nearest 4 bytes
9040 const alignments = if (extra.data.flags.any_aligned_fields)
9041 ((extra.data.fields_len + 3) / 4) * 4
9042 else
9043 0;
9044 break :b @sizeOf(Tag.TypeUnion) +
9045 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +
9046 (extra.data.fields_len * per_field) + alignments;
9047 },
89369048
8937 .undef => 0,
8938 .simple_type => 0,
8939 .simple_value => 0,
8940 .ptr_decl => @sizeOf(PtrDecl),
8941 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),
8942 .ptr_anon_decl => @sizeOf(PtrAnonDecl),
8943 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),
8944 .ptr_comptime_field => @sizeOf(PtrComptimeField),
8945 .ptr_int => @sizeOf(PtrInt),
8946 .ptr_eu_payload => @sizeOf(PtrBase),
8947 .ptr_opt_payload => @sizeOf(PtrBase),
8948 .ptr_elem => @sizeOf(PtrBaseIndex),
8949 .ptr_field => @sizeOf(PtrBaseIndex),
8950 .ptr_slice => @sizeOf(PtrSlice),
8951 .opt_null => 0,
8952 .opt_payload => @sizeOf(Tag.TypeValue),
8953 .int_u8 => 0,
8954 .int_u16 => 0,
8955 .int_u32 => 0,
8956 .int_i32 => 0,
8957 .int_usize => 0,
8958 .int_comptime_int_u32 => 0,
8959 .int_comptime_int_i32 => 0,
8960 .int_small => @sizeOf(IntSmall),
9049 .type_function => b: {
9050 const info = ip.extraData(Tag.TypeFunction, data);
9051 break :b @sizeOf(Tag.TypeFunction) +
9052 (@sizeOf(Index) * info.params_len) +
9053 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
9054 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
9055 },
89619056
8962 .int_positive,
8963 .int_negative,
8964 => b: {
8965 const int = ip.limbData(Int, data);
8966 break :b @sizeOf(Int) + int.limbs_len * 8;
8967 },
9057 .undef => 0,
9058 .simple_type => 0,
9059 .simple_value => 0,
9060 .ptr_decl => @sizeOf(PtrDecl),
9061 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),
9062 .ptr_anon_decl => @sizeOf(PtrAnonDecl),
9063 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),
9064 .ptr_comptime_field => @sizeOf(PtrComptimeField),
9065 .ptr_int => @sizeOf(PtrInt),
9066 .ptr_eu_payload => @sizeOf(PtrBase),
9067 .ptr_opt_payload => @sizeOf(PtrBase),
9068 .ptr_elem => @sizeOf(PtrBaseIndex),
9069 .ptr_field => @sizeOf(PtrBaseIndex),
9070 .ptr_slice => @sizeOf(PtrSlice),
9071 .opt_null => 0,
9072 .opt_payload => @sizeOf(Tag.TypeValue),
9073 .int_u8 => 0,
9074 .int_u16 => 0,
9075 .int_u32 => 0,
9076 .int_i32 => 0,
9077 .int_usize => 0,
9078 .int_comptime_int_u32 => 0,
9079 .int_comptime_int_i32 => 0,
9080 .int_small => @sizeOf(IntSmall),
9081
9082 .int_positive,
9083 .int_negative,
9084 => b: {
9085 const int = ip.limbData(Int, data);
9086 break :b @sizeOf(Int) + int.limbs_len * 8;
9087 },
89689088
8969 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),
9089 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),
89709090
8971 .error_set_error, .error_union_error => @sizeOf(Key.Error),
8972 .error_union_payload => @sizeOf(Tag.TypeValue),
8973 .enum_literal => 0,
8974 .enum_tag => @sizeOf(Tag.EnumTag),
9091 .error_set_error, .error_union_error => @sizeOf(Key.Error),
9092 .error_union_payload => @sizeOf(Tag.TypeValue),
9093 .enum_literal => 0,
9094 .enum_tag => @sizeOf(Tag.EnumTag),
89759095
8976 .bytes => b: {
8977 const info = ip.extraData(Bytes, data);
8978 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
8979 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);
8980 },
8981 .aggregate => b: {
8982 const info = ip.extraData(Tag.Aggregate, data);
8983 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
8984 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);
8985 },
8986 .repeated => @sizeOf(Repeated),
8987
8988 .float_f16 => 0,
8989 .float_f32 => 0,
8990 .float_f64 => @sizeOf(Float64),
8991 .float_f80 => @sizeOf(Float80),
8992 .float_f128 => @sizeOf(Float128),
8993 .float_c_longdouble_f80 => @sizeOf(Float80),
8994 .float_c_longdouble_f128 => @sizeOf(Float128),
8995 .float_comptime_float => @sizeOf(Float128),
8996 .variable => @sizeOf(Tag.Variable),
8997 .extern_func => @sizeOf(Tag.ExternFunc),
8998 .func_decl => @sizeOf(Tag.FuncDecl),
8999 .func_instance => b: {
9000 const info = ip.extraData(Tag.FuncInstance, data);
9001 const ty = ip.typeOf(info.generic_owner);
9002 const params_len = ip.indexToKey(ty).func_type.param_types.len;
9003 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;
9004 },
9005 .func_coerced => @sizeOf(Tag.FuncCoerced),
9006 .only_possible_value => 0,
9007 .union_value => @sizeOf(Key.Union),
9096 .bytes => b: {
9097 const info = ip.extraData(Bytes, data);
9098 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
9099 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);
9100 },
9101 .aggregate => b: {
9102 const info = ip.extraData(Tag.Aggregate, data);
9103 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
9104 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);
9105 },
9106 .repeated => @sizeOf(Repeated),
9107
9108 .float_f16 => 0,
9109 .float_f32 => 0,
9110 .float_f64 => @sizeOf(Float64),
9111 .float_f80 => @sizeOf(Float80),
9112 .float_f128 => @sizeOf(Float128),
9113 .float_c_longdouble_f80 => @sizeOf(Float80),
9114 .float_c_longdouble_f128 => @sizeOf(Float128),
9115 .float_comptime_float => @sizeOf(Float128),
9116 .variable => @sizeOf(Tag.Variable),
9117 .extern_func => @sizeOf(Tag.ExternFunc),
9118 .func_decl => @sizeOf(Tag.FuncDecl),
9119 .func_instance => b: {
9120 const info = ip.extraData(Tag.FuncInstance, data);
9121 const ty = ip.typeOf(info.generic_owner);
9122 const params_len = ip.indexToKey(ty).func_type.param_types.len;
9123 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;
9124 },
9125 .func_coerced => @sizeOf(Tag.FuncCoerced),
9126 .only_possible_value => 0,
9127 .union_value => @sizeOf(Key.Union),
90089128
9009 .memoized_call => b: {
9010 const info = ip.extraData(MemoizedCall, data);
9011 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);
9012 },
9013 });
9129 .memoized_call => b: {
9130 const info = ip.extraData(MemoizedCall, data);
9131 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);
9132 },
9133 });
9134 }
90149135 }
90159136 const SortContext = struct {
90169137 map: *std.AutoArrayHashMap(Tag, TagStats),
......@@ -9031,97 +9152,103 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
90319152}
90329153
90339154fn dumpAllFallible(ip: *const InternPool) anyerror!void {
9034 const tags = ip.items.items(.tag);
9035 const datas = ip.items.items(.data);
90369155 var bw = std.io.bufferedWriter(std.io.getStdErr().writer());
90379156 const w = bw.writer();
9038 for (tags, datas, 0..) |tag, data, i| {
9039 try w.print("${d} = {s}(", .{ i, @tagName(tag) });
9040 switch (tag) {
9041 .removed => {},
9042
9043 .simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(data)))}),
9044 .simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(data)))}),
9045
9046 .type_int_signed,
9047 .type_int_unsigned,
9048 .type_array_small,
9049 .type_array_big,
9050 .type_vector,
9051 .type_pointer,
9052 .type_optional,
9053 .type_anyframe,
9054 .type_error_union,
9055 .type_anyerror_union,
9056 .type_error_set,
9057 .type_inferred_error_set,
9058 .type_enum_explicit,
9059 .type_enum_nonexhaustive,
9060 .type_enum_auto,
9061 .type_opaque,
9062 .type_struct,
9063 .type_struct_anon,
9064 .type_struct_packed,
9065 .type_struct_packed_inits,
9066 .type_tuple_anon,
9067 .type_union,
9068 .type_function,
9069 .undef,
9070 .ptr_decl,
9071 .ptr_comptime_alloc,
9072 .ptr_anon_decl,
9073 .ptr_anon_decl_aligned,
9074 .ptr_comptime_field,
9075 .ptr_int,
9076 .ptr_eu_payload,
9077 .ptr_opt_payload,
9078 .ptr_elem,
9079 .ptr_field,
9080 .ptr_slice,
9081 .opt_payload,
9082 .int_u8,
9083 .int_u16,
9084 .int_u32,
9085 .int_i32,
9086 .int_usize,
9087 .int_comptime_int_u32,
9088 .int_comptime_int_i32,
9089 .int_small,
9090 .int_positive,
9091 .int_negative,
9092 .int_lazy_align,
9093 .int_lazy_size,
9094 .error_set_error,
9095 .error_union_error,
9096 .error_union_payload,
9097 .enum_literal,
9098 .enum_tag,
9099 .bytes,
9100 .aggregate,
9101 .repeated,
9102 .float_f16,
9103 .float_f32,
9104 .float_f64,
9105 .float_f80,
9106 .float_f128,
9107 .float_c_longdouble_f80,
9108 .float_c_longdouble_f128,
9109 .float_comptime_float,
9110 .variable,
9111 .extern_func,
9112 .func_decl,
9113 .func_instance,
9114 .func_coerced,
9115 .union_value,
9116 .memoized_call,
9117 => try w.print("{d}", .{data}),
9118
9119 .opt_null,
9120 .type_slice,
9121 .only_possible_value,
9122 => try w.print("${d}", .{data}),
9157 for (ip.locals, 0..) |*local, tid| {
9158 const items = local.shared.items.view();
9159 for (
9160 items.items(.tag)[0..local.mutate.items.len],
9161 items.items(.data)[0..local.mutate.items.len],
9162 0..,
9163 ) |tag, data, index| {
9164 const i = Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip);
9165 try w.print("${d} = {s}(", .{ i, @tagName(tag) });
9166 switch (tag) {
9167 .removed => {},
9168
9169 .simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(data)))}),
9170 .simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(data)))}),
9171
9172 .type_int_signed,
9173 .type_int_unsigned,
9174 .type_array_small,
9175 .type_array_big,
9176 .type_vector,
9177 .type_pointer,
9178 .type_optional,
9179 .type_anyframe,
9180 .type_error_union,
9181 .type_anyerror_union,
9182 .type_error_set,
9183 .type_inferred_error_set,
9184 .type_enum_explicit,
9185 .type_enum_nonexhaustive,
9186 .type_enum_auto,
9187 .type_opaque,
9188 .type_struct,
9189 .type_struct_anon,
9190 .type_struct_packed,
9191 .type_struct_packed_inits,
9192 .type_tuple_anon,
9193 .type_union,
9194 .type_function,
9195 .undef,
9196 .ptr_decl,
9197 .ptr_comptime_alloc,
9198 .ptr_anon_decl,
9199 .ptr_anon_decl_aligned,
9200 .ptr_comptime_field,
9201 .ptr_int,
9202 .ptr_eu_payload,
9203 .ptr_opt_payload,
9204 .ptr_elem,
9205 .ptr_field,
9206 .ptr_slice,
9207 .opt_payload,
9208 .int_u8,
9209 .int_u16,
9210 .int_u32,
9211 .int_i32,
9212 .int_usize,
9213 .int_comptime_int_u32,
9214 .int_comptime_int_i32,
9215 .int_small,
9216 .int_positive,
9217 .int_negative,
9218 .int_lazy_align,
9219 .int_lazy_size,
9220 .error_set_error,
9221 .error_union_error,
9222 .error_union_payload,
9223 .enum_literal,
9224 .enum_tag,
9225 .bytes,
9226 .aggregate,
9227 .repeated,
9228 .float_f16,
9229 .float_f32,
9230 .float_f64,
9231 .float_f80,
9232 .float_f128,
9233 .float_c_longdouble_f80,
9234 .float_c_longdouble_f128,
9235 .float_comptime_float,
9236 .variable,
9237 .extern_func,
9238 .func_decl,
9239 .func_instance,
9240 .func_coerced,
9241 .union_value,
9242 .memoized_call,
9243 => try w.print("{d}", .{data}),
9244
9245 .opt_null,
9246 .type_slice,
9247 .only_possible_value,
9248 => try w.print("${d}", .{data}),
9249 }
9250 try w.writeAll(")\n");
91239251 }
9124 try w.writeAll(")\n");
91259252 }
91269253 try bw.flush();
91279254}
......@@ -9139,15 +9266,24 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
91399266 const w = bw.writer();
91409267
91419268 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};
9142 const datas = ip.items.items(.data);
9143 for (ip.items.items(.tag), 0..) |tag, i| {
9144 if (tag != .func_instance) continue;
9145 const info = ip.extraData(Tag.FuncInstance, datas[i]);
9146
9147 const gop = try instances.getOrPut(arena, info.generic_owner);
9148 if (!gop.found_existing) gop.value_ptr.* = .{};
9149
9150 try gop.value_ptr.append(arena, @enumFromInt(i));
9269 for (ip.locals, 0..) |*local, tid| {
9270 const items = local.shared.items.view();
9271 for (
9272 items.items(.tag)[0..local.mutate.items.len],
9273 items.items(.data)[0..local.mutate.items.len],
9274 0..,
9275 ) |tag, data, index| {
9276 if (tag != .func_instance) continue;
9277 const info = ip.extraData(Tag.FuncInstance, data);
9278
9279 const gop = try instances.getOrPut(arena, info.generic_owner);
9280 if (!gop.found_existing) gop.value_ptr.* = .{};
9281
9282 try gop.value_ptr.append(
9283 arena,
9284 Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip),
9285 );
9286 }
91519287 }
91529288
91539289 const SortContext = struct {
......@@ -9163,7 +9299,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
91639299 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));
91649300 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });
91659301 for (entry.value_ptr.items) |index| {
9166 const func = ip.extraFuncInstance(datas[@intFromEnum(index)]);
9302 const func = ip.extraFuncInstance(index.getData(ip));
91679303 const owner_decl = ip.declPtrConst(func.owner_decl);
91689304 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});
91699305 for (func.comptime_args.get(ip)) |arg| {
......@@ -9518,7 +9654,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
95189654
95199655 // This optimization on tags is needed so that indexToKey can call
95209656 // typeOf without being recursive.
9521 _ => switch (ip.items.items(.tag)[@intFromEnum(index)]) {
9657 _ => switch (index.getTag(ip)) {
95229658 .removed => unreachable,
95239659
95249660 .type_int_signed,
......@@ -9551,7 +9687,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
95519687 .undef,
95529688 .opt_null,
95539689 .only_possible_value,
9554 => @enumFromInt(ip.items.items(.data)[@intFromEnum(index)]),
9690 => @enumFromInt(index.getData(ip)),
95559691
95569692 .simple_value => unreachable, // handled via Index above
95579693
......@@ -9584,7 +9720,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
95849720 .aggregate,
95859721 .repeated,
95869722 => |t| {
9587 const extra_index = ip.items.items(.data)[@intFromEnum(index)];
9723 const extra_index = index.getData(ip);
95889724 const field_index = std.meta.fieldIndex(t.Payload(), "ty").?;
95899725 return @enumFromInt(ip.extra.items[extra_index + field_index]);
95909726 },
......@@ -9602,7 +9738,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
96029738 // Note these are stored in limbs data, not extra data.
96039739 .int_positive,
96049740 .int_negative,
9605 => ip.limbData(Int, ip.items.items(.data)[@intFromEnum(index)]).ty,
9741 => ip.limbData(Int, index.getData(ip)).ty,
96069742
96079743 .enum_literal => .enum_literal_type,
96089744 .float_f16 => .f16_type,
......@@ -9651,11 +9787,11 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
96519787}
96529788
96539789pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
9654 const item = ip.items.get(@intFromEnum(ty));
9790 const item = ty.getItem(ip);
96559791 const child_item = switch (item.tag) {
9656 .type_pointer => ip.items.get(ip.extra.items[
9792 .type_pointer => @as(Index, @enumFromInt(ip.extra.items[
96579793 item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?
9658 ]),
9794 ])).getItem(ip),
96599795 .type_function => item,
96609796 else => unreachable,
96619797 };
......@@ -9668,47 +9804,47 @@ pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
96689804pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
96699805 return switch (ty) {
96709806 .noreturn_type => true,
9671 else => switch (ip.items.items(.tag)[@intFromEnum(ty)]) {
9672 .type_error_set => ip.extra.items[ip.items.items(.data)[@intFromEnum(ty)] + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,
9807 else => switch (ty.getTag(ip)) {
9808 .type_error_set => ip.extra.items[ty.getData(ip) + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,
96739809 else => false,
96749810 },
96759811 };
96769812}
96779813
96789814pub fn isUndef(ip: *const InternPool, val: Index) bool {
9679 return val == .undef or ip.items.items(.tag)[@intFromEnum(val)] == .undef;
9815 return val == .undef or val.getTag(ip) == .undef;
96809816}
96819817
96829818pub fn isVariable(ip: *const InternPool, val: Index) bool {
9683 return ip.items.items(.tag)[@intFromEnum(val)] == .variable;
9819 return val.getTag(ip) == .variable;
96849820}
96859821
96869822pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
9687 var base = @intFromEnum(val);
9823 var base = val;
96889824 while (true) {
9689 switch (ip.items.items(.tag)[base]) {
9825 switch (base.getTag(ip)) {
96909826 .ptr_decl => return @enumFromInt(ip.extra.items[
9691 ip.items.items(.data)[base] + std.meta.fieldIndex(PtrDecl, "decl").?
9827 base.getData(ip) + std.meta.fieldIndex(PtrDecl, "decl").?
96929828 ]),
96939829 inline .ptr_eu_payload,
96949830 .ptr_opt_payload,
96959831 .ptr_elem,
96969832 .ptr_field,
9697 => |tag| base = ip.extra.items[
9698 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "base").?
9699 ],
9700 .ptr_slice => base = ip.extra.items[
9701 ip.items.items(.data)[base] + std.meta.fieldIndex(PtrSlice, "ptr").?
9702 ],
9833 => |tag| base = @enumFromInt(ip.extra.items[
9834 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "base").?
9835 ]),
9836 .ptr_slice => base = @enumFromInt(ip.extra.items[
9837 base.getData(ip) + std.meta.fieldIndex(PtrSlice, "ptr").?
9838 ]),
97039839 else => return .none,
97049840 }
97059841 }
97069842}
97079843
97089844pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag {
9709 var base = @intFromEnum(val);
9845 var base = val;
97109846 while (true) {
9711 switch (ip.items.items(.tag)[base]) {
9847 switch (base.getTag(ip)) {
97129848 .ptr_decl => return .decl,
97139849 .ptr_comptime_alloc => return .comptime_alloc,
97149850 .ptr_anon_decl,
......@@ -9720,12 +9856,12 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
97209856 .ptr_opt_payload,
97219857 .ptr_elem,
97229858 .ptr_field,
9723 => |tag| base = ip.extra.items[
9724 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "base").?
9725 ],
9726 inline .ptr_slice => |tag| base = ip.extra.items[
9727 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "ptr").?
9728 ],
9859 => |tag| base = @enumFromInt(ip.extra.items[
9860 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "base").?
9861 ]),
9862 inline .ptr_slice => |tag| base = @enumFromInt(ip.extra.items[
9863 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "ptr").?
9864 ]),
97299865 else => return null,
97309866 }
97319867 }
......@@ -9834,7 +9970,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
98349970 .empty_struct => unreachable,
98359971 .generic_poison => unreachable,
98369972
9837 _ => switch (ip.items.items(.tag)[@intFromEnum(index)]) {
9973 _ => switch (index.getTag(ip)) {
98389974 .removed => unreachable,
98399975
98409976 .type_int_signed,
......@@ -9941,24 +10077,22 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
994110077 };
994210078}
994310079
9944pub fn isFuncBody(ip: *const InternPool, i: Index) bool {
9945 assert(i != .none);
9946 return switch (ip.items.items(.tag)[@intFromEnum(i)]) {
10080pub fn isFuncBody(ip: *const InternPool, index: Index) bool {
10081 return switch (index.getTag(ip)) {
994710082 .func_decl, .func_instance, .func_coerced => true,
994810083 else => false,
994910084 };
995010085}
995110086
9952pub fn funcAnalysis(ip: *const InternPool, i: Index) *FuncAnalysis {
9953 assert(i != .none);
9954 const item = ip.items.get(@intFromEnum(i));
10087pub fn funcAnalysis(ip: *const InternPool, index: Index) *FuncAnalysis {
10088 const item = index.getItem(ip);
995510089 const extra_index = switch (item.tag) {
995610090 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
995710091 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
995810092 .func_coerced => i: {
995910093 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;
996010094 const func_index: Index = @enumFromInt(ip.extra.items[extra_index]);
9961 const sub_item = ip.items.get(@intFromEnum(func_index));
10095 const sub_item = func_index.getItem(ip);
996210096 break :i switch (sub_item.tag) {
996310097 .func_decl => sub_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
996410098 .func_instance => sub_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
......@@ -9974,22 +10108,21 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {
997410108 return funcAnalysis(ip, i).inferred_error_set;
997510109}
997610110
9977pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index {
9978 assert(i != .none);
9979 const item = ip.items.get(@intFromEnum(i));
10111pub fn funcZirBodyInst(ip: *const InternPool, index: Index) TrackedInst.Index {
10112 const item = index.getItem(ip);
998010113 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;
998110114 const extra_index = switch (item.tag) {
998210115 .func_decl => item.data + zir_body_inst_field_index,
9983 .func_instance => b: {
10116 .func_instance => ei: {
998410117 const generic_owner_field_index = std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?;
9985 const func_decl_index = ip.extra.items[item.data + generic_owner_field_index];
9986 assert(ip.items.items(.tag)[func_decl_index] == .func_decl);
9987 break :b ip.items.items(.data)[func_decl_index] + zir_body_inst_field_index;
10118 const func_decl_index: Index = @enumFromInt(ip.extra.items[item.data + generic_owner_field_index]);
10119 const func_decl_item = func_decl_index.getItem(ip);
10120 assert(func_decl_item.tag == .func_decl);
10121 break :ei func_decl_item.data + zir_body_inst_field_index;
998810122 },
998910123 .func_coerced => {
9990 const datas = ip.items.items(.data);
999110124 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
9992 datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10125 item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
999310126 ]);
999410127 return ip.funcZirBodyInst(uncoerced_func_index);
999510128 },
......@@ -9999,15 +10132,14 @@ pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index {
999910132}
1000010133
1000110134pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {
10002 assert(ies_index != .none);
10003 const tags = ip.items.items(.tag);
10004 assert(tags[@intFromEnum(ies_index)] == .type_inferred_error_set);
10005 const func_index = ip.items.items(.data)[@intFromEnum(ies_index)];
10006 switch (tags[func_index]) {
10135 const item = ies_index.getItem(ip);
10136 assert(item.tag == .type_inferred_error_set);
10137 const func_index: Index = @enumFromInt(item.data);
10138 switch (func_index.getTag(ip)) {
1000710139 .func_decl, .func_instance => {},
1000810140 else => unreachable, // assertion failed
1000910141 }
10010 return @enumFromInt(func_index);
10142 return func_index;
1001110143}
1001210144
1001310145/// Returns a mutable pointer to the resolved error set type of an inferred
......@@ -10026,21 +10158,19 @@ pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {
1002610158/// error set function. The returned pointer is invalidated when anything is
1002710159/// added to `ip`.
1002810160pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
10029 const tags = ip.items.items(.tag);
10030 const datas = ip.items.items(.data);
1003110161 assert(funcHasInferredErrorSet(ip, func_index));
10032 const func_start = datas[@intFromEnum(func_index)];
10033 const extra_index = switch (tags[@intFromEnum(func_index)]) {
10034 .func_decl => func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10035 .func_instance => func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10162 const func_item = func_index.getItem(ip);
10163 const extra_index = switch (func_item.tag) {
10164 .func_decl => func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10165 .func_instance => func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
1003610166 .func_coerced => i: {
1003710167 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
10038 func_start + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10168 func_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
1003910169 ]);
10040 const uncoerced_func_start = datas[@intFromEnum(uncoerced_func_index)];
10041 break :i switch (tags[@intFromEnum(uncoerced_func_index)]) {
10042 .func_decl => uncoerced_func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10043 .func_instance => uncoerced_func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10170 const uncoerced_func_item = uncoerced_func_index.getItem(ip);
10171 break :i switch (uncoerced_func_item.tag) {
10172 .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10173 .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
1004410174 else => unreachable,
1004510175 };
1004610176 },
......@@ -10049,35 +10179,28 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
1004910179 return @ptrCast(&ip.extra.items[extra_index]);
1005010180}
1005110181
10052pub fn funcDeclInfo(ip: *const InternPool, i: Index) Key.Func {
10053 const tags = ip.items.items(.tag);
10054 const datas = ip.items.items(.data);
10055 assert(tags[@intFromEnum(i)] == .func_decl);
10056 return extraFuncDecl(ip, datas[@intFromEnum(i)]);
10182pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
10183 const item = index.getItem(ip);
10184 assert(item.tag == .func_decl);
10185 return extraFuncDecl(ip, item.data);
1005710186}
1005810187
10059pub fn funcDeclOwner(ip: *const InternPool, i: Index) DeclIndex {
10060 return funcDeclInfo(ip, i).owner_decl;
10188pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
10189 return funcDeclInfo(ip, index).owner_decl;
1006110190}
1006210191
10063pub fn funcTypeParamsLen(ip: *const InternPool, i: Index) u32 {
10064 const tags = ip.items.items(.tag);
10065 const datas = ip.items.items(.data);
10066 assert(tags[@intFromEnum(i)] == .type_function);
10067 const start = datas[@intFromEnum(i)];
10068 return ip.extra.items[start + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];
10192pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {
10193 const item = index.getItem(ip);
10194 assert(item.tag == .type_function);
10195 return ip.extra.items[item.data + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];
1006910196}
1007010197
10071pub fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {
10072 const tags = ip.items.items(.tag);
10073 return switch (tags[@intFromEnum(i)]) {
10074 .func_coerced => {
10075 const datas = ip.items.items(.data);
10076 return @enumFromInt(ip.extra.items[
10077 datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10078 ]);
10079 },
10080 .func_instance, .func_decl => i,
10198pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
10199 return switch (index.getTag(ip)) {
10200 .func_coerced => @enumFromInt(ip.extra.items[
10201 index.getData(ip) + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10202 ]),
10203 .func_instance, .func_decl => index,
1008110204 else => unreachable,
1008210205 };
1008310206}
......@@ -10085,7 +10208,12 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {
1008510208/// Having resolved a builtin type to a real struct/union/enum (which is now at `resolverd_index`),
1008610209/// make `want_index` refer to this type instead. This invalidates `resolved_index`, so must be
1008710210/// called only when it is guaranteed that no reference to `resolved_index` exists.
10088pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: Index) void {
10211pub fn resolveBuiltinType(
10212 ip: *InternPool,
10213 tid: Zcu.PerThread.Id,
10214 want_index: Index,
10215 resolved_index: Index,
10216) void {
1008910217 assert(@intFromEnum(want_index) >= @intFromEnum(Index.first_type));
1009010218 assert(@intFromEnum(want_index) <= @intFromEnum(Index.last_type));
1009110219
......@@ -10097,20 +10225,12 @@ pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: In
1009710225 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));
1009810226
1009910227 // Copy the data
10100 const item = ip.items.get(@intFromEnum(resolved_index));
10101 ip.items.set(@intFromEnum(want_index), item);
10102
10103 if (std.debug.runtime_safety) {
10104 // Make the value unreachable - this is a weird value which will make (incorrect) existing
10105 // references easier to spot
10106 ip.items.set(@intFromEnum(resolved_index), .{
10107 .tag = .simple_value,
10108 .data = @intFromEnum(SimpleValue.@"unreachable"),
10109 });
10110 } else {
10111 // Here we could add the index to a free-list for reuse, but since
10112 // there is so little garbage created this way it's not worth it.
10113 }
10228 const resolved_item = resolved_index.getItem(ip);
10229 const want_unwrapped = want_index.unwrap(ip);
10230 if (tid != .main or want_unwrapped.tid != .main) @panic("This operation is impossible to be thread-safe");
10231 var want_items = ip.getLocalShared(want_unwrapped.tid).items.view();
10232 want_items.set(want_unwrapped.index, resolved_item);
10233 ip.remove(tid, resolved_index);
1011410234}
1011510235
1011610236pub fn anonStructFieldTypes(ip: *const InternPool, i: Index) []const Index {
src/Sema.zig+13-12
......@@ -2717,10 +2717,11 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
27172717/// Given an `InternPool.WipNamespaceType` or `InternPool.WipEnumType`, apply
27182718/// `sema.builtin_type_target_index` to it if necessary.
27192719fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
2720 const pt = sema.pt;
27202721 if (sema.builtin_type_target_index == .none) return wip_ty;
27212722 var new = wip_ty;
27222723 new.index = sema.builtin_type_target_index;
2723 sema.pt.zcu.intern_pool.resolveBuiltinType(new.index, wip_ty.index);
2724 pt.zcu.intern_pool.resolveBuiltinType(pt.tid, new.index, wip_ty.index);
27242725 return new;
27252726}
27262727
......@@ -2740,7 +2741,7 @@ fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
27402741 if (!was_outdated) return false;
27412742 _ = zcu.outdated_ready.swapRemove(decl_as_depender);
27422743 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
2743 zcu.intern_pool.remove(ty);
2744 zcu.intern_pool.remove(pt.tid, ty);
27442745 zcu.declPtr(decl_index).analysis = .dependency_failure;
27452746 try zcu.markDependeeOutdated(.{ .decl_val = decl_index });
27462747 return true;
......@@ -2819,7 +2820,7 @@ fn zirStructDecl(
28192820 },
28202821 .wip => |wip| wip,
28212822 });
2822 errdefer wip_ty.cancel(ip);
2823 errdefer wip_ty.cancel(ip, pt.tid);
28232824
28242825 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
28252826 block,
......@@ -3056,7 +3057,7 @@ fn zirEnumDecl(
30563057 // have finished constructing the type and are in the process of analyzing it.
30573058 var done = false;
30583059
3059 errdefer if (!done) wip_ty.cancel(ip);
3060 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
30603061
30613062 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
30623063 block,
......@@ -3324,7 +3325,7 @@ fn zirUnionDecl(
33243325 },
33253326 .wip => |wip| wip,
33263327 });
3327 errdefer wip_ty.cancel(ip);
3328 errdefer wip_ty.cancel(ip, pt.tid);
33283329
33293330 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
33303331 block,
......@@ -3414,7 +3415,7 @@ fn zirOpaqueDecl(
34143415 },
34153416 .wip => |wip| wip,
34163417 };
3417 errdefer wip_ty.cancel(ip);
3418 errdefer wip_ty.cancel(ip, pt.tid);
34183419
34193420 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
34203421 block,
......@@ -21705,7 +21706,7 @@ fn zirReify(
2170521706 .existing => |ty| return Air.internedToRef(ty),
2170621707 .wip => |wip| wip,
2170721708 };
21708 errdefer wip_ty.cancel(ip);
21709 errdefer wip_ty.cancel(ip, pt.tid);
2170921710
2171021711 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
2171121712 block,
......@@ -21901,7 +21902,7 @@ fn reifyEnum(
2190121902 .wip => |wip| wip,
2190221903 .existing => |ty| return Air.internedToRef(ty),
2190321904 };
21904 errdefer wip_ty.cancel(ip);
21905 errdefer wip_ty.cancel(ip, pt.tid);
2190521906
2190621907 if (tag_ty.zigTypeTag(mod) != .Int) {
2190721908 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
......@@ -22052,7 +22053,7 @@ fn reifyUnion(
2205222053 .wip => |wip| wip,
2205322054 .existing => |ty| return Air.internedToRef(ty),
2205422055 };
22055 errdefer wip_ty.cancel(ip);
22056 errdefer wip_ty.cancel(ip, pt.tid);
2205622057
2205722058 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
2205822059 block,
......@@ -22158,7 +22159,7 @@ fn reifyUnion(
2215822159 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));
2215922160 break :tag_ty .{ enum_tag_ty, false };
2216022161 };
22161 errdefer if (!has_explicit_tag) ip.remove(enum_tag_ty); // remove generated tag type on error
22162 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
2216222163
2216322164 for (field_types) |field_ty_ip| {
2216422165 const field_ty = Type.fromInterned(field_ty_ip);
......@@ -22305,7 +22306,7 @@ fn reifyStruct(
2230522306 .wip => |wip| wip,
2230622307 .existing => |ty| return Air.internedToRef(ty),
2230722308 };
22308 errdefer wip_ty.cancel(ip);
22309 errdefer wip_ty.cancel(ip, pt.tid);
2230922310
2231022311 if (is_tuple) switch (layout) {
2231122312 .@"extern" => return sema.fail(block, src, "extern tuples are not supported", .{}),
......@@ -36924,7 +36925,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3692436925 .none,
3692536926 => unreachable,
3692636927
36927 _ => switch (ip.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
36928 _ => switch (ty.toIntern().getTag(ip)) {
3692836929 .removed => unreachable,
3692936930
3693036931 .type_int_signed, // i0 handled above
src/Type.zig+1-1
......@@ -3686,7 +3686,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
36863686 .empty_struct => unreachable,
36873687 .generic_poison => unreachable,
36883688
3689 else => switch (ip.items.items(.tag)[@intFromEnum(ty_ip)]) {
3689 else => switch (ty_ip.getTag(ip)) {
36903690 .type_struct,
36913691 .type_struct_packed,
36923692 .type_struct_packed_inits,
src/Zcu.zig-36
......@@ -3071,42 +3071,6 @@ pub const SemaDeclResult = packed struct {
30713071 invalidate_decl_ref: bool,
30723072};
30733073
3074pub fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
3075 const decl = zcu.declPtr(decl_index);
3076
3077 assert(decl.has_tv);
3078 assert(decl.owns_tv);
3079
3080 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
3081
3082 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
3083 .Fn => @panic("TODO: update fn instance"),
3084 .Type => {},
3085 else => unreachable,
3086 }
3087
3088 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
3089 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
3090 //
3091 // However, as soon as we make that, the context that created us will require re-analysis anyway
3092 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
3093 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
3094 // why should we bother implementing it here too when the Sema logic will be hit right after?
3095 //
3096 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
3097 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
3098 // with a new Decl.
3099 //
3100 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
3101 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
3102 zcu.intern_pool.remove(decl.val.toIntern());
3103 decl.analysis = .dependency_failure;
3104 return .{
3105 .invalidate_decl_val = true,
3106 .invalidate_decl_ref = true,
3107 };
3108}
3109
31103074pub const ImportFileResult = struct {
31113075 file: *File,
31123076 file_index: File.Index,
src/Zcu/PerThread.zig+42-5
......@@ -574,7 +574,7 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
574574 if (decl.val.ip_index != func_index) {
575575 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
576576 ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
577 ip.remove(func_index);
577 ip.remove(pt.tid, func_index);
578578 @panic("TODO: remove orphaned function from binary");
579579 }
580580
......@@ -823,7 +823,7 @@ fn getFileRootStruct(
823823 .existing => unreachable, // we wouldn't be analysing the file root if this type existed
824824 .wip => |wip| wip,
825825 };
826 errdefer wip_ty.cancel(ip);
826 errdefer wip_ty.cancel(ip, pt.tid);
827827
828828 if (zcu.comp.debug_incremental) {
829829 try ip.addDependency(
......@@ -885,7 +885,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
885885 ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{
886886 .decl = file_root_decl,
887887 }));
888 ip.remove(decl.val.toIntern());
888 ip.remove(pt.tid, decl.val.toIntern());
889889 decl.val = undefined;
890890 _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);
891891 return true;
......@@ -959,7 +959,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
959959 assert(file.zir_loaded);
960960
961961 const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index);
962 errdefer zcu.intern_pool.remove(struct_ty);
962 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);
963963
964964 switch (zcu.comp.cache_use) {
965965 .whole => |whole| if (whole.cache_manifest) |man| {
......@@ -1002,7 +1002,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
10021002
10031003 if (decl.zir_decl_index == .none and decl.owns_tv) {
10041004 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).
1005 return zcu.semaAnonOwnerDecl(decl_index);
1005 return pt.semaAnonOwnerDecl(decl_index);
10061006 }
10071007
10081008 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
......@@ -1270,6 +1270,43 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
12701270 return result;
12711271}
12721272
1273pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1274 const zcu = pt.zcu;
1275 const decl = zcu.declPtr(decl_index);
1276
1277 assert(decl.has_tv);
1278 assert(decl.owns_tv);
1279
1280 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
1281
1282 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
1283 .Fn => @panic("TODO: update fn instance"),
1284 .Type => {},
1285 else => unreachable,
1286 }
1287
1288 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
1289 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
1290 //
1291 // However, as soon as we make that, the context that created us will require re-analysis anyway
1292 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
1293 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
1294 // why should we bother implementing it here too when the Sema logic will be hit right after?
1295 //
1296 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
1297 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
1298 // with a new Decl.
1299 //
1300 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
1301 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
1302 zcu.intern_pool.remove(pt.tid, decl.val.toIntern());
1303 decl.analysis = .dependency_failure;
1304 return .{
1305 .invalidate_decl_val = true,
1306 .invalidate_decl_ref = true,
1307 };
1308}
1309
12731310pub fn embedFile(
12741311 pt: Zcu.PerThread,
12751312 cur_file: *Zcu.File,