authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-02-01 16:58:52+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-02-02 11:02:03+00:00
log9eda6ccefce370c76209ea50dd57fe65bfe25536
treed5b4af496b8a6d1811788557d85e340ce26ef2bc
parent5a3ae38f3b79a69cb6f4ad28934a51165cae2ef1

InternPool: use separate key for slices

This change eliminates some problematic recursive logic in InternPool, and provides a safer API.

11 files changed, 533 insertions(+), 546 deletions(-)

src/InternPool.zig+179-221
......@@ -326,6 +326,7 @@ pub const Key = union(enum) {
326326 empty_enum_value: Index,
327327 float: Float,
328328 ptr: Ptr,
329 slice: Slice,
329330 opt: Opt,
330331 /// An instance of a struct, array, or vector.
331332 /// Each element/field stored as an `Index`.
......@@ -493,7 +494,7 @@ pub const Key = union(enum) {
493494 start: u32,
494495 len: u32,
495496
496 pub fn get(slice: Slice, ip: *const InternPool) []RuntimeOrder {
497 pub fn get(slice: RuntimeOrder.Slice, ip: *const InternPool) []RuntimeOrder {
497498 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);
498499 }
499500 };
......@@ -1197,8 +1198,6 @@ pub const Key = union(enum) {
11971198 ty: Index,
11981199 /// The value of the address that the pointer points to.
11991200 addr: Addr,
1200 /// This could be `none` if size is not a slice.
1201 len: Index = .none,
12021201
12031202 pub const Addr = union(enum) {
12041203 const Tag = @typeInfo(Addr).Union.tag_type.?;
......@@ -1232,6 +1231,15 @@ pub const Key = union(enum) {
12321231 };
12331232 };
12341233
1234 pub const Slice = struct {
1235 /// This is the slice type, not the element type.
1236 ty: Index,
1237 /// The slice's `ptr` field. Must be a many-ptr with the same properties as `ty`.
1238 ptr: Index,
1239 /// The slice's `len` field. Must be a `usize`.
1240 len: Index,
1241 };
1242
12351243 /// `null` is represented by the `val` field being `none`.
12361244 pub const Opt = extern struct {
12371245 /// This is the optional type; not the payload type.
......@@ -1354,12 +1362,14 @@ pub const Key = union(enum) {
13541362 return hasher.final();
13551363 },
13561364
1365 .slice => |slice| Hash.hash(seed, asBytes(&slice.ty) ++ asBytes(&slice.ptr) ++ asBytes(&slice.len)),
1366
13571367 .ptr => |ptr| {
13581368 // Int-to-ptr pointers are hashed separately than decl-referencing pointers.
13591369 // This is sound due to pointer provenance rules.
13601370 const addr: @typeInfo(Key.Ptr.Addr).Union.tag_type.? = ptr.addr;
13611371 const seed2 = seed + @intFromEnum(addr);
1362 const common = asBytes(&ptr.ty) ++ asBytes(&ptr.len);
1372 const common = asBytes(&ptr.ty);
13631373 return switch (ptr.addr) {
13641374 .decl => |x| Hash.hash(seed2, common ++ asBytes(&x)),
13651375
......@@ -1624,9 +1634,17 @@ pub const Key = union(enum) {
16241634 return a_ty_info.eql(b_ty_info, ip);
16251635 },
16261636
1637 .slice => |a_info| {
1638 const b_info = b.slice;
1639 if (a_info.ty != b_info.ty) return false;
1640 if (a_info.ptr != b_info.ptr) return false;
1641 if (a_info.len != b_info.len) return false;
1642 return true;
1643 },
1644
16271645 .ptr => |a_info| {
16281646 const b_info = b.ptr;
1629 if (a_info.ty != b_info.ty or a_info.len != b_info.len) return false;
1647 if (a_info.ty != b_info.ty) return false;
16301648
16311649 const AddrTag = @typeInfo(Key.Ptr.Addr).Union.tag_type.?;
16321650 if (@as(AddrTag, a_info.addr) != @as(AddrTag, b_info.addr)) return false;
......@@ -1829,6 +1847,7 @@ pub const Key = union(enum) {
18291847 => .type_type,
18301848
18311849 inline .ptr,
1850 .slice,
18321851 .int,
18331852 .float,
18341853 .opt,
......@@ -3983,77 +4002,11 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
39834002 },
39844003 .ptr_slice => {
39854004 const info = ip.extraData(PtrSlice, data);
3986 const ptr_item = ip.items.get(@intFromEnum(info.ptr));
3987 return .{
3988 .ptr = .{
3989 .ty = info.ty,
3990 .addr = switch (ptr_item.tag) {
3991 .ptr_decl => .{
3992 .decl = ip.extraData(PtrDecl, ptr_item.data).decl,
3993 },
3994 .ptr_mut_decl => b: {
3995 const sub_info = ip.extraData(PtrMutDecl, ptr_item.data);
3996 break :b .{ .mut_decl = .{
3997 .decl = sub_info.decl,
3998 .runtime_index = sub_info.runtime_index,
3999 } };
4000 },
4001 .ptr_anon_decl => .{
4002 .anon_decl = .{
4003 .val = ip.extraData(PtrAnonDecl, ptr_item.data).val,
4004 .orig_ty = info.ty,
4005 },
4006 },
4007 .ptr_anon_decl_aligned => b: {
4008 const sub_info = ip.extraData(PtrAnonDeclAligned, ptr_item.data);
4009 break :b .{ .anon_decl = .{
4010 .val = sub_info.val,
4011 .orig_ty = sub_info.orig_ty,
4012 } };
4013 },
4014 .ptr_comptime_field => .{
4015 .comptime_field = ip.extraData(PtrComptimeField, ptr_item.data).field_val,
4016 },
4017 .ptr_int => .{
4018 .int = ip.extraData(PtrBase, ptr_item.data).base,
4019 },
4020 .ptr_eu_payload => .{
4021 .eu_payload = ip.extraData(PtrBase, ptr_item.data).base,
4022 },
4023 .ptr_opt_payload => .{
4024 .opt_payload = ip.extraData(PtrBase, ptr_item.data).base,
4025 },
4026 .ptr_elem => b: {
4027 // Avoid `indexToKey` recursion by asserting the tag encoding.
4028 const sub_info = ip.extraData(PtrBaseIndex, ptr_item.data);
4029 const index_item = ip.items.get(@intFromEnum(sub_info.index));
4030 break :b switch (index_item.tag) {
4031 .int_usize => .{ .elem = .{
4032 .base = sub_info.base,
4033 .index = index_item.data,
4034 } },
4035 .int_positive => @panic("TODO"), // implement along with behavior test coverage
4036 else => unreachable,
4037 };
4038 },
4039 .ptr_field => b: {
4040 // Avoid `indexToKey` recursion by asserting the tag encoding.
4041 const sub_info = ip.extraData(PtrBaseIndex, ptr_item.data);
4042 const index_item = ip.items.get(@intFromEnum(sub_info.index));
4043 break :b switch (index_item.tag) {
4044 .int_usize => .{ .field = .{
4045 .base = sub_info.base,
4046 .index = index_item.data,
4047 } },
4048 .int_positive => @panic("TODO"), // implement along with behavior test coverage
4049 else => unreachable,
4050 };
4051 },
4052 else => unreachable,
4053 },
4054 .len = info.len,
4055 },
4056 };
4005 return .{ .slice = .{
4006 .ty = info.ty,
4007 .ptr = info.ptr,
4008 .len = info.len,
4009 } };
40574010 },
40584011 .int_u8 => .{ .int = .{
40594012 .ty = .u8_type,
......@@ -4735,153 +4688,139 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
47354688 });
47364689 },
47374690
4691 .slice => |slice| {
4692 assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .Slice);
4693 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);
4694 ip.items.appendAssumeCapacity(.{
4695 .tag = .ptr_slice,
4696 .data = try ip.addExtra(gpa, PtrSlice{
4697 .ty = slice.ty,
4698 .ptr = slice.ptr,
4699 .len = slice.len,
4700 }),
4701 });
4702 },
4703
47384704 .ptr => |ptr| {
47394705 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
4740 switch (ptr.len) {
4741 .none => {
4742 assert(ptr_type.flags.size != .Slice);
4743 switch (ptr.addr) {
4744 .decl => |decl| ip.items.appendAssumeCapacity(.{
4745 .tag = .ptr_decl,
4746 .data = try ip.addExtra(gpa, PtrDecl{
4747 .ty = ptr.ty,
4748 .decl = decl,
4749 }),
4706 assert(ptr_type.flags.size != .Slice);
4707 switch (ptr.addr) {
4708 .decl => |decl| ip.items.appendAssumeCapacity(.{
4709 .tag = .ptr_decl,
4710 .data = try ip.addExtra(gpa, PtrDecl{
4711 .ty = ptr.ty,
4712 .decl = decl,
4713 }),
4714 }),
4715 .mut_decl => |mut_decl| ip.items.appendAssumeCapacity(.{
4716 .tag = .ptr_mut_decl,
4717 .data = try ip.addExtra(gpa, PtrMutDecl{
4718 .ty = ptr.ty,
4719 .decl = mut_decl.decl,
4720 .runtime_index = mut_decl.runtime_index,
4721 }),
4722 }),
4723 .anon_decl => |anon_decl| ip.items.appendAssumeCapacity(
4724 if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) .{
4725 .tag = .ptr_anon_decl,
4726 .data = try ip.addExtra(gpa, PtrAnonDecl{
4727 .ty = ptr.ty,
4728 .val = anon_decl.val,
47504729 }),
4751 .mut_decl => |mut_decl| ip.items.appendAssumeCapacity(.{
4752 .tag = .ptr_mut_decl,
4753 .data = try ip.addExtra(gpa, PtrMutDecl{
4754 .ty = ptr.ty,
4755 .decl = mut_decl.decl,
4756 .runtime_index = mut_decl.runtime_index,
4757 }),
4730 } else .{
4731 .tag = .ptr_anon_decl_aligned,
4732 .data = try ip.addExtra(gpa, PtrAnonDeclAligned{
4733 .ty = ptr.ty,
4734 .val = anon_decl.val,
4735 .orig_ty = anon_decl.orig_ty,
47584736 }),
4759 .anon_decl => |anon_decl| ip.items.appendAssumeCapacity(
4760 if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) .{
4761 .tag = .ptr_anon_decl,
4762 .data = try ip.addExtra(gpa, PtrAnonDecl{
4763 .ty = ptr.ty,
4764 .val = anon_decl.val,
4765 }),
4766 } else .{
4767 .tag = .ptr_anon_decl_aligned,
4768 .data = try ip.addExtra(gpa, PtrAnonDeclAligned{
4769 .ty = ptr.ty,
4770 .val = anon_decl.val,
4771 .orig_ty = anon_decl.orig_ty,
4772 }),
4773 },
4774 ),
4775 .comptime_field => |field_val| {
4776 assert(field_val != .none);
4777 ip.items.appendAssumeCapacity(.{
4778 .tag = .ptr_comptime_field,
4779 .data = try ip.addExtra(gpa, PtrComptimeField{
4780 .ty = ptr.ty,
4781 .field_val = field_val,
4782 }),
4783 });
4737 },
4738 ),
4739 .comptime_field => |field_val| {
4740 assert(field_val != .none);
4741 ip.items.appendAssumeCapacity(.{
4742 .tag = .ptr_comptime_field,
4743 .data = try ip.addExtra(gpa, PtrComptimeField{
4744 .ty = ptr.ty,
4745 .field_val = field_val,
4746 }),
4747 });
4748 },
4749 .int, .eu_payload, .opt_payload => |base| {
4750 switch (ptr.addr) {
4751 .int => assert(ip.typeOf(base) == .usize_type),
4752 .eu_payload => assert(ip.indexToKey(
4753 ip.indexToKey(ip.typeOf(base)).ptr_type.child,
4754 ) == .error_union_type),
4755 .opt_payload => assert(ip.indexToKey(
4756 ip.indexToKey(ip.typeOf(base)).ptr_type.child,
4757 ) == .opt_type),
4758 else => unreachable,
4759 }
4760 ip.items.appendAssumeCapacity(.{
4761 .tag = switch (ptr.addr) {
4762 .int => .ptr_int,
4763 .eu_payload => .ptr_eu_payload,
4764 .opt_payload => .ptr_opt_payload,
4765 else => unreachable,
47844766 },
4785 .int, .eu_payload, .opt_payload => |base| {
4786 switch (ptr.addr) {
4787 .int => assert(ip.typeOf(base) == .usize_type),
4788 .eu_payload => assert(ip.indexToKey(
4789 ip.indexToKey(ip.typeOf(base)).ptr_type.child,
4790 ) == .error_union_type),
4791 .opt_payload => assert(ip.indexToKey(
4792 ip.indexToKey(ip.typeOf(base)).ptr_type.child,
4793 ) == .opt_type),
4794 else => unreachable,
4795 }
4796 ip.items.appendAssumeCapacity(.{
4797 .tag = switch (ptr.addr) {
4798 .int => .ptr_int,
4799 .eu_payload => .ptr_eu_payload,
4800 .opt_payload => .ptr_opt_payload,
4801 else => unreachable,
4767 .data = try ip.addExtra(gpa, PtrBase{
4768 .ty = ptr.ty,
4769 .base = base,
4770 }),
4771 });
4772 },
4773 .elem, .field => |base_index| {
4774 const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type;
4775 switch (ptr.addr) {
4776 .elem => assert(base_ptr_type.flags.size == .Many),
4777 .field => {
4778 assert(base_ptr_type.flags.size == .One);
4779 switch (ip.indexToKey(base_ptr_type.child)) {
4780 .anon_struct_type => |anon_struct_type| {
4781 assert(ptr.addr == .field);
4782 assert(base_index.index < anon_struct_type.types.len);
48024783 },
4803 .data = try ip.addExtra(gpa, PtrBase{
4804 .ty = ptr.ty,
4805 .base = base,
4806 }),
4807 });
4808 },
4809 .elem, .field => |base_index| {
4810 const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type;
4811 switch (ptr.addr) {
4812 .elem => assert(base_ptr_type.flags.size == .Many),
4813 .field => {
4814 assert(base_ptr_type.flags.size == .One);
4815 switch (ip.indexToKey(base_ptr_type.child)) {
4816 .anon_struct_type => |anon_struct_type| {
4817 assert(ptr.addr == .field);
4818 assert(base_index.index < anon_struct_type.types.len);
4819 },
4820 .struct_type => |struct_type| {
4821 assert(ptr.addr == .field);
4822 assert(base_index.index < struct_type.field_types.len);
4823 },
4824 .union_type => |union_key| {
4825 const union_type = ip.loadUnionType(union_key);
4826 assert(ptr.addr == .field);
4827 assert(base_index.index < union_type.field_names.len);
4828 },
4829 .ptr_type => |slice_type| {
4830 assert(ptr.addr == .field);
4831 assert(slice_type.flags.size == .Slice);
4832 assert(base_index.index < 2);
4833 },
4834 else => unreachable,
4835 }
4784 .struct_type => |struct_type| {
4785 assert(ptr.addr == .field);
4786 assert(base_index.index < struct_type.field_types.len);
4787 },
4788 .union_type => |union_key| {
4789 const union_type = ip.loadUnionType(union_key);
4790 assert(ptr.addr == .field);
4791 assert(base_index.index < union_type.field_names.len);
4792 },
4793 .ptr_type => |slice_type| {
4794 assert(ptr.addr == .field);
4795 assert(slice_type.flags.size == .Slice);
4796 assert(base_index.index < 2);
48364797 },
48374798 else => unreachable,
48384799 }
4839 _ = ip.map.pop();
4840 const index_index = try ip.get(gpa, .{ .int = .{
4841 .ty = .usize_type,
4842 .storage = .{ .u64 = base_index.index },
4843 } });
4844 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);
4845 try ip.items.ensureUnusedCapacity(gpa, 1);
4846 ip.items.appendAssumeCapacity(.{
4847 .tag = switch (ptr.addr) {
4848 .elem => .ptr_elem,
4849 .field => .ptr_field,
4850 else => unreachable,
4851 },
4852 .data = try ip.addExtra(gpa, PtrBaseIndex{
4853 .ty = ptr.ty,
4854 .base = base_index.base,
4855 .index = index_index,
4856 }),
4857 });
48584800 },
4801 else => unreachable,
48594802 }
4860 },
4861 else => {
4862 // TODO: change Key.Ptr for slices to reference the manyptr value
4863 // rather than having an addr field directly. Then we can avoid
4864 // these problematic calls to pop(), get(), and getOrPutAdapted().
4865 assert(ptr_type.flags.size == .Slice);
48664803 _ = ip.map.pop();
4867 var new_key = key;
4868 new_key.ptr.ty = ip.slicePtrType(ptr.ty);
4869 new_key.ptr.len = .none;
4870 assert(ip.indexToKey(new_key.ptr.ty).ptr_type.flags.size == .Many);
4871 const ptr_index = try ip.get(gpa, new_key);
4804 const index_index = try ip.get(gpa, .{ .int = .{
4805 .ty = .usize_type,
4806 .storage = .{ .u64 = base_index.index },
4807 } });
48724808 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);
48734809 try ip.items.ensureUnusedCapacity(gpa, 1);
48744810 ip.items.appendAssumeCapacity(.{
4875 .tag = .ptr_slice,
4876 .data = try ip.addExtra(gpa, PtrSlice{
4811 .tag = switch (ptr.addr) {
4812 .elem => .ptr_elem,
4813 .field => .ptr_field,
4814 else => unreachable,
4815 },
4816 .data = try ip.addExtra(gpa, PtrBaseIndex{
48774817 .ty = ptr.ty,
4878 .ptr = ptr_index,
4879 .len = ptr.len,
4818 .base = base_index.base,
4819 .index = index_index,
48804820 }),
48814821 });
48824822 },
48834823 }
4884 assert(ptr.ty == ip.indexToKey(@as(Index, @enumFromInt(ip.items.len - 1))).ptr.ty);
48854824 },
48864825
48874826 .opt => |opt| {
......@@ -6844,14 +6783,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
68446783 .val = .none,
68456784 } });
68466785
6847 if (ip.isPointerType(new_ty)) return ip.get(gpa, .{ .ptr = .{
6848 .ty = new_ty,
6849 .addr = .{ .int = .zero_usize },
6850 .len = switch (ip.indexToKey(new_ty).ptr_type.flags.size) {
6851 .One, .Many, .C => .none,
6852 .Slice => try ip.get(gpa, .{ .undef = .usize_type }),
6853 },
6854 } });
6786 if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) {
6787 .One, .Many, .C => return ip.get(gpa, .{ .ptr = .{
6788 .ty = new_ty,
6789 .addr = .{ .int = .zero_usize },
6790 } }),
6791 .Slice => return ip.get(gpa, .{ .slice = .{
6792 .ty = new_ty,
6793 .ptr = try ip.get(gpa, .{ .ptr = .{
6794 .ty = ip.slicePtrType(new_ty),
6795 .addr = .{ .int = .zero_usize },
6796 } }),
6797 .len = try ip.get(gpa, .{ .undef = .usize_type }),
6798 } }),
6799 };
68556800 },
68566801 else => switch (tags[@intFromEnum(val)]) {
68576802 .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty),
......@@ -6929,11 +6874,18 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
69296874 },
69306875 else => {},
69316876 },
6932 .ptr => |ptr| if (ip.isPointerType(new_ty))
6877 .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .Slice)
6878 return ip.get(gpa, .{ .slice = .{
6879 .ty = new_ty,
6880 .ptr = try ip.getCoerced(gpa, slice.ptr, ip.slicePtrType(new_ty)),
6881 .len = slice.len,
6882 } })
6883 else if (ip.isIntegerType(new_ty))
6884 return ip.getCoerced(gpa, slice.ptr, new_ty),
6885 .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .Slice)
69336886 return ip.get(gpa, .{ .ptr = .{
69346887 .ty = new_ty,
69356888 .addr = ptr.addr,
6936 .len = ptr.len,
69376889 } })
69386890 else if (ip.isIntegerType(new_ty))
69396891 switch (ptr.addr) {
......@@ -6942,14 +6894,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
69426894 },
69436895 .opt => |opt| switch (ip.indexToKey(new_ty)) {
69446896 .ptr_type => |ptr_type| return switch (opt.val) {
6945 .none => try ip.get(gpa, .{ .ptr = .{
6946 .ty = new_ty,
6947 .addr = .{ .int = .zero_usize },
6948 .len = switch (ptr_type.flags.size) {
6949 .One, .Many, .C => .none,
6950 .Slice => try ip.get(gpa, .{ .undef = .usize_type }),
6951 },
6952 } }),
6897 .none => switch (ptr_type.flags.size) {
6898 .One, .Many, .C => try ip.get(gpa, .{ .ptr = .{
6899 .ty = new_ty,
6900 .addr = .{ .int = .zero_usize },
6901 } }),
6902 .Slice => try ip.get(gpa, .{ .slice = .{
6903 .ty = new_ty,
6904 .ptr = try ip.get(gpa, .{ .ptr = .{
6905 .ty = ip.slicePtrType(new_ty),
6906 .addr = .{ .int = .zero_usize },
6907 } }),
6908 .len = try ip.get(gpa, .{ .undef = .usize_type }),
6909 } }),
6910 },
69536911 else => |payload| try ip.getCoerced(gpa, payload, new_ty),
69546912 },
69556913 .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{
src/Module.zig+21-14
......@@ -5278,9 +5278,12 @@ pub fn populateTestFunctions(
52785278
52795279 const test_fn_fields = .{
52805280 // name
5281 try mod.intern(.{ .ptr = .{
5281 try mod.intern(.{ .slice = .{
52825282 .ty = .slice_const_u8_type,
5283 .addr = .{ .decl = test_name_decl_index },
5283 .ptr = try mod.intern(.{ .ptr = .{
5284 .ty = .manyptr_const_u8_type,
5285 .addr = .{ .decl = test_name_decl_index },
5286 } }),
52845287 .len = try mod.intern(.{ .int = .{
52855288 .ty = .usize_type,
52865289 .storage = .{ .u64 = test_decl_name.len },
......@@ -5331,9 +5334,12 @@ pub fn populateTestFunctions(
53315334 },
53325335 });
53335336 const new_val = decl.val;
5334 const new_init = try mod.intern(.{ .ptr = .{
5337 const new_init = try mod.intern(.{ .slice = .{
53355338 .ty = new_ty.toIntern(),
5336 .addr = .{ .decl = array_decl_index },
5339 .ptr = try mod.intern(.{ .ptr = .{
5340 .ty = new_ty.slicePtrFieldType(mod).toIntern(),
5341 .addr = .{ .decl = array_decl_index },
5342 } }),
53375343 .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(),
53385344 } });
53395345 ip.mutateVarInit(decl.val.toIntern(), new_init);
......@@ -5423,16 +5429,17 @@ pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void {
54235429 .err_name => {},
54245430 .payload => |payload| try mod.markReferencedDeclsAlive(Value.fromInterned(payload)),
54255431 },
5426 .ptr => |ptr| {
5427 switch (ptr.addr) {
5428 .decl => |decl| try mod.markDeclIndexAlive(decl),
5429 .anon_decl => {},
5430 .mut_decl => |mut_decl| try mod.markDeclIndexAlive(mut_decl.decl),
5431 .int, .comptime_field => {},
5432 .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(Value.fromInterned(parent)),
5433 .elem, .field => |base_index| try mod.markReferencedDeclsAlive(Value.fromInterned(base_index.base)),
5434 }
5435 if (ptr.len != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(ptr.len));
5432 .slice => |slice| {
5433 try mod.markReferencedDeclsAlive(Value.fromInterned(slice.ptr));
5434 try mod.markReferencedDeclsAlive(Value.fromInterned(slice.len));
5435 },
5436 .ptr => |ptr| switch (ptr.addr) {
5437 .decl => |decl| try mod.markDeclIndexAlive(decl),
5438 .anon_decl => {},
5439 .mut_decl => |mut_decl| try mod.markDeclIndexAlive(mut_decl.decl),
5440 .int, .comptime_field => {},
5441 .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(Value.fromInterned(parent)),
5442 .elem, .field => |base_index| try mod.markReferencedDeclsAlive(Value.fromInterned(base_index.base)),
54365443 },
54375444 .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(opt.val)),
54385445 .aggregate => |aggregate| for (aggregate.storage.values()) |elem|
src/Sema.zig+165-124
......@@ -17375,16 +17375,19 @@ fn zirBuiltinSrc(
1737517375 .sentinel = .zero_u8,
1737617376 .child = .u8_type,
1737717377 } });
17378 break :v try ip.get(gpa, .{ .ptr = .{
17378 break :v try ip.get(gpa, .{ .slice = .{
1737917379 .ty = .slice_const_u8_sentinel_0_type,
17380 .ptr = try ip.get(gpa, .{ .ptr = .{
17381 .ty = .manyptr_const_u8_sentinel_0_type,
17382 .addr = .{ .anon_decl = .{
17383 .orig_ty = .slice_const_u8_sentinel_0_type,
17384 .val = try ip.get(gpa, .{ .aggregate = .{
17385 .ty = array_ty,
17386 .storage = .{ .bytes = bytes },
17387 } }),
17388 } },
17389 } }),
1738017390 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
17381 .addr = .{ .anon_decl = .{
17382 .orig_ty = .slice_const_u8_sentinel_0_type,
17383 .val = try ip.get(gpa, .{ .aggregate = .{
17384 .ty = array_ty,
17385 .storage = .{ .bytes = bytes },
17386 } }),
17387 } },
1738817391 } });
1738917392 };
1739017393
......@@ -17396,16 +17399,19 @@ fn zirBuiltinSrc(
1739617399 .sentinel = .zero_u8,
1739717400 .child = .u8_type,
1739817401 } });
17399 break :v try ip.get(gpa, .{ .ptr = .{
17402 break :v try ip.get(gpa, .{ .slice = .{
1740017403 .ty = .slice_const_u8_sentinel_0_type,
17404 .ptr = try ip.get(gpa, .{ .ptr = .{
17405 .ty = .manyptr_const_u8_sentinel_0_type,
17406 .addr = .{ .anon_decl = .{
17407 .orig_ty = .slice_const_u8_sentinel_0_type,
17408 .val = try ip.get(gpa, .{ .aggregate = .{
17409 .ty = array_ty,
17410 .storage = .{ .bytes = bytes },
17411 } }),
17412 } },
17413 } }),
1740117414 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
17402 .addr = .{ .anon_decl = .{
17403 .orig_ty = .slice_const_u8_sentinel_0_type,
17404 .val = try ip.get(gpa, .{ .aggregate = .{
17405 .ty = array_ty,
17406 .storage = .{ .bytes = bytes },
17407 } }),
17408 } },
1740917415 } });
1741017416 };
1741117417
......@@ -17517,12 +17523,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1751717523 .is_const = true,
1751817524 },
1751917525 })).toIntern();
17520 break :v try mod.intern(.{ .ptr = .{
17526 break :v try mod.intern(.{ .slice = .{
1752117527 .ty = ptr_ty,
17522 .addr = .{ .anon_decl = .{
17523 .orig_ty = ptr_ty,
17524 .val = new_decl_val,
17525 } },
17528 .ptr = try mod.intern(.{ .ptr = .{
17529 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
17530 .addr = .{ .anon_decl = .{
17531 .orig_ty = ptr_ty,
17532 .val = new_decl_val,
17533 } },
17534 } }),
1752617535 .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),
1752717536 } });
1752817537 };
......@@ -17796,12 +17805,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1779617805 .ty = new_decl_ty.toIntern(),
1779717806 .storage = .{ .bytes = name },
1779817807 } });
17799 break :v try mod.intern(.{ .ptr = .{
17808 break :v try mod.intern(.{ .slice = .{
1780017809 .ty = .slice_const_u8_sentinel_0_type,
17801 .addr = .{ .anon_decl = .{
17802 .val = new_decl_val,
17803 .orig_ty = .slice_const_u8_sentinel_0_type,
17804 } },
17810 .ptr = try mod.intern(.{ .ptr = .{
17811 .ty = .manyptr_const_u8_sentinel_0_type,
17812 .addr = .{ .anon_decl = .{
17813 .val = new_decl_val,
17814 .orig_ty = .slice_const_u8_sentinel_0_type,
17815 } },
17816 } }),
1780517817 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1780617818 } });
1780717819 };
......@@ -17838,12 +17850,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1783817850 .ty = array_errors_ty.toIntern(),
1783917851 .storage = .{ .elems = vals },
1784017852 } });
17841 break :v try mod.intern(.{ .ptr = .{
17853 break :v try mod.intern(.{ .slice = .{
1784217854 .ty = slice_errors_ty.toIntern(),
17843 .addr = .{ .anon_decl = .{
17844 .orig_ty = slice_errors_ty.toIntern(),
17845 .val = new_decl_val,
17846 } },
17855 .ptr = try mod.intern(.{ .ptr = .{
17856 .ty = slice_errors_ty.slicePtrFieldType(mod).toIntern(),
17857 .addr = .{ .anon_decl = .{
17858 .orig_ty = slice_errors_ty.toIntern(),
17859 .val = new_decl_val,
17860 } },
17861 } }),
1784717862 .len = (try mod.intValue(Type.usize, vals.len)).toIntern(),
1784817863 } });
1784917864 } else .none;
......@@ -17925,12 +17940,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1792517940 .ty = new_decl_ty.toIntern(),
1792617941 .storage = .{ .bytes = name },
1792717942 } });
17928 break :v try mod.intern(.{ .ptr = .{
17943 break :v try mod.intern(.{ .slice = .{
1792917944 .ty = .slice_const_u8_sentinel_0_type,
17930 .addr = .{ .anon_decl = .{
17931 .val = new_decl_val,
17932 .orig_ty = .slice_const_u8_sentinel_0_type,
17933 } },
17945 .ptr = try mod.intern(.{ .ptr = .{
17946 .ty = .manyptr_const_u8_sentinel_0_type,
17947 .addr = .{ .anon_decl = .{
17948 .val = new_decl_val,
17949 .orig_ty = .slice_const_u8_sentinel_0_type,
17950 } },
17951 } }),
1793417952 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1793517953 } });
1793617954 };
......@@ -17963,12 +17981,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1796317981 .is_const = true,
1796417982 },
1796517983 })).toIntern();
17966 break :v try mod.intern(.{ .ptr = .{
17984 break :v try mod.intern(.{ .slice = .{
1796717985 .ty = ptr_ty,
17968 .addr = .{ .anon_decl = .{
17969 .val = new_decl_val,
17970 .orig_ty = ptr_ty,
17971 } },
17986 .ptr = try mod.intern(.{ .ptr = .{
17987 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
17988 .addr = .{ .anon_decl = .{
17989 .val = new_decl_val,
17990 .orig_ty = ptr_ty,
17991 } },
17992 } }),
1797217993 .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),
1797317994 } });
1797417995 };
......@@ -18051,12 +18072,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1805118072 .ty = new_decl_ty.toIntern(),
1805218073 .storage = .{ .bytes = name },
1805318074 } });
18054 break :v try mod.intern(.{ .ptr = .{
18075 break :v try mod.intern(.{ .slice = .{
1805518076 .ty = .slice_const_u8_sentinel_0_type,
18056 .addr = .{ .anon_decl = .{
18057 .val = new_decl_val,
18058 .orig_ty = .slice_const_u8_sentinel_0_type,
18059 } },
18077 .ptr = try mod.intern(.{ .ptr = .{
18078 .ty = .manyptr_const_u8_sentinel_0_type,
18079 .addr = .{ .anon_decl = .{
18080 .val = new_decl_val,
18081 .orig_ty = .slice_const_u8_sentinel_0_type,
18082 } },
18083 } }),
1806018084 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1806118085 } });
1806218086 };
......@@ -18097,12 +18121,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1809718121 .is_const = true,
1809818122 },
1809918123 })).toIntern();
18100 break :v try mod.intern(.{ .ptr = .{
18124 break :v try mod.intern(.{ .slice = .{
1810118125 .ty = ptr_ty,
18102 .addr = .{ .anon_decl = .{
18103 .orig_ty = ptr_ty,
18104 .val = new_decl_val,
18105 } },
18126 .ptr = try mod.intern(.{ .ptr = .{
18127 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
18128 .addr = .{ .anon_decl = .{
18129 .orig_ty = ptr_ty,
18130 .val = new_decl_val,
18131 } },
18132 } }),
1810618133 .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),
1810718134 } });
1810818135 };
......@@ -18199,12 +18226,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1819918226 .ty = new_decl_ty.toIntern(),
1820018227 .storage = .{ .bytes = bytes },
1820118228 } });
18202 break :v try mod.intern(.{ .ptr = .{
18229 break :v try mod.intern(.{ .slice = .{
1820318230 .ty = .slice_const_u8_sentinel_0_type,
18204 .addr = .{ .anon_decl = .{
18205 .val = new_decl_val,
18206 .orig_ty = .slice_const_u8_sentinel_0_type,
18207 } },
18231 .ptr = try mod.intern(.{ .ptr = .{
18232 .ty = .manyptr_const_u8_sentinel_0_type,
18233 .addr = .{ .anon_decl = .{
18234 .val = new_decl_val,
18235 .orig_ty = .slice_const_u8_sentinel_0_type,
18236 } },
18237 } }),
1820818238 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
1820918239 } });
1821018240 };
......@@ -18259,12 +18289,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1825918289 .ty = new_decl_ty.toIntern(),
1826018290 .storage = .{ .bytes = name },
1826118291 } });
18262 break :v try mod.intern(.{ .ptr = .{
18292 break :v try mod.intern(.{ .slice = .{
1826318293 .ty = .slice_const_u8_sentinel_0_type,
18264 .addr = .{ .anon_decl = .{
18265 .val = new_decl_val,
18266 .orig_ty = .slice_const_u8_sentinel_0_type,
18267 } },
18294 .ptr = try mod.intern(.{ .ptr = .{
18295 .ty = .manyptr_const_u8_sentinel_0_type,
18296 .addr = .{ .anon_decl = .{
18297 .val = new_decl_val,
18298 .orig_ty = .slice_const_u8_sentinel_0_type,
18299 } },
18300 } }),
1826818301 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1826918302 } });
1827018303 };
......@@ -18315,12 +18348,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1831518348 .is_const = true,
1831618349 },
1831718350 })).toIntern();
18318 break :v try mod.intern(.{ .ptr = .{
18351 break :v try mod.intern(.{ .slice = .{
1831918352 .ty = ptr_ty,
18320 .addr = .{ .anon_decl = .{
18321 .orig_ty = ptr_ty,
18322 .val = new_decl_val,
18323 } },
18353 .ptr = try mod.intern(.{ .ptr = .{
18354 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
18355 .addr = .{ .anon_decl = .{
18356 .orig_ty = ptr_ty,
18357 .val = new_decl_val,
18358 } },
18359 } }),
1832418360 .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),
1832518361 } });
1832618362 };
......@@ -18453,12 +18489,15 @@ fn typeInfoDecls(
1845318489 .is_const = true,
1845418490 },
1845518491 })).toIntern();
18456 return try mod.intern(.{ .ptr = .{
18492 return try mod.intern(.{ .slice = .{
1845718493 .ty = ptr_ty,
18458 .addr = .{ .anon_decl = .{
18459 .orig_ty = ptr_ty,
18460 .val = new_decl_val,
18461 } },
18494 .ptr = try mod.intern(.{ .ptr = .{
18495 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
18496 .addr = .{ .anon_decl = .{
18497 .orig_ty = ptr_ty,
18498 .val = new_decl_val,
18499 } },
18500 } }),
1846218501 .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),
1846318502 } });
1846418503}
......@@ -18498,12 +18537,15 @@ fn typeInfoNamespaceDecls(
1849818537 .ty = new_decl_ty.toIntern(),
1849918538 .storage = .{ .bytes = name },
1850018539 } });
18501 break :v try mod.intern(.{ .ptr = .{
18540 break :v try mod.intern(.{ .slice = .{
1850218541 .ty = .slice_const_u8_sentinel_0_type,
18503 .addr = .{ .anon_decl = .{
18504 .orig_ty = .slice_const_u8_sentinel_0_type,
18505 .val = new_decl_val,
18506 } },
18542 .ptr = try mod.intern(.{ .ptr = .{
18543 .ty = .manyptr_const_u8_sentinel_0_type,
18544 .addr = .{ .anon_decl = .{
18545 .orig_ty = .slice_const_u8_sentinel_0_type,
18546 .val = new_decl_val,
18547 } },
18548 } }),
1850718549 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1850818550 } });
1850918551 };
......@@ -22738,9 +22780,12 @@ fn ptrCastFull(
2273822780 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {
2273922781 if (ptr_val.isUndef(mod)) return mod.undefRef(dest_ty);
2274022782 const arr_len = try mod.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod));
22741 return Air.internedToRef((try mod.intern(.{ .ptr = .{
22783 return Air.internedToRef((try mod.intern(.{ .slice = .{
2274222784 .ty = dest_ty.toIntern(),
22743 .addr = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr,
22785 .ptr = try mod.intern(.{ .ptr = .{
22786 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),
22787 .addr = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr,
22788 } }),
2274422789 .len = arr_len.toIntern(),
2274522790 } })));
2274622791 } else {
......@@ -28765,21 +28810,24 @@ fn coerceExtra(
2876528810 if (inst_child_ty.structFieldCount(mod) == 0) {
2876628811 // Optional slice is represented with a null pointer so
2876728812 // we use a dummy pointer value with the required alignment.
28768 return Air.internedToRef((try mod.intern(.{ .ptr = .{
28813 return Air.internedToRef((try mod.intern(.{ .slice = .{
2876928814 .ty = dest_ty.toIntern(),
28770 .addr = .{ .int = if (dest_info.flags.alignment != .none)
28771 (try mod.intValue(
28772 Type.usize,
28773 dest_info.flags.alignment.toByteUnitsOptional().?,
28774 )).toIntern()
28775 else
28776 try mod.intern_pool.getCoercedInts(
28777 mod.gpa,
28778 mod.intern_pool.indexToKey(
28779 (try Type.fromInterned(dest_info.child).lazyAbiAlignment(mod)).toIntern(),
28780 ).int,
28781 .usize_type,
28782 ) },
28815 .ptr = try mod.intern(.{ .ptr = .{
28816 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),
28817 .addr = .{ .int = if (dest_info.flags.alignment != .none)
28818 (try mod.intValue(
28819 Type.usize,
28820 dest_info.flags.alignment.toByteUnitsOptional().?,
28821 )).toIntern()
28822 else
28823 try mod.intern_pool.getCoercedInts(
28824 mod.gpa,
28825 mod.intern_pool.indexToKey(
28826 (try Type.fromInterned(dest_info.child).lazyAbiAlignment(mod)).toIntern(),
28827 ).int,
28828 .usize_type,
28829 ) },
28830 } }),
2878328831 .len = (try mod.intValue(Type.usize, 0)).toIntern(),
2878428832 } })));
2878528833 }
......@@ -31276,7 +31324,7 @@ fn beginComptimePtrLoad(
3127631324 },
3127731325 Value.slice_len_index => TypedValue{
3127831326 .ty = Type.usize,
31279 .val = Value.fromInterned(ip.indexToKey(try tv.val.intern(tv.ty, mod)).ptr.len),
31327 .val = Value.fromInterned(ip.indexToKey(try tv.val.intern(tv.ty, mod)).slice.len),
3128031328 },
3128131329 else => unreachable,
3128231330 };
......@@ -31445,13 +31493,16 @@ fn coerceArrayPtrToSlice(
3144531493 if (try sema.resolveValue(inst)) |val| {
3144631494 const ptr_array_ty = sema.typeOf(inst);
3144731495 const array_ty = ptr_array_ty.childType(mod);
31448 const slice_val = try mod.intern(.{ .ptr = .{
31496 const slice_val = try mod.intern(.{ .slice = .{
3144931497 .ty = dest_ty.toIntern(),
31450 .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) {
31451 .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) },
31452 .ptr => |ptr| ptr.addr,
31453 else => unreachable,
31454 },
31498 .ptr = try mod.intern(.{ .ptr = .{
31499 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),
31500 .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) {
31501 .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) },
31502 .ptr => |ptr| ptr.addr,
31503 else => unreachable,
31504 },
31505 } }),
3145531506 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),
3145631507 } });
3145731508 return Air.internedToRef(slice_val);
......@@ -35211,51 +35262,43 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
3521135262 (try val.getUnsignedIntAdvanced(mod, sema)).?,
3521235263 ),
3521335264 },
35265 .slice => |slice| {
35266 const ptr = try sema.resolveLazyValue(Value.fromInterned(slice.ptr));
35267 const len = try sema.resolveLazyValue(Value.fromInterned(slice.len));
35268 if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val;
35269 return Value.fromInterned(try mod.intern(.{ .slice = .{
35270 .ty = slice.ty,
35271 .ptr = ptr.toIntern(),
35272 .len = len.toIntern(),
35273 } }));
35274 },
3521435275 .ptr => |ptr| {
35215 const resolved_len = switch (ptr.len) {
35216 .none => .none,
35217 else => (try sema.resolveLazyValue(Value.fromInterned(ptr.len))).toIntern(),
35218 };
3521935276 switch (ptr.addr) {
35220 .decl, .mut_decl, .anon_decl => return if (resolved_len == ptr.len)
35221 val
35222 else
35223 Value.fromInterned((try mod.intern(.{ .ptr = .{
35224 .ty = ptr.ty,
35225 .addr = switch (ptr.addr) {
35226 .decl => |decl| .{ .decl = decl },
35227 .mut_decl => |mut_decl| .{ .mut_decl = mut_decl },
35228 .anon_decl => |anon_decl| .{ .anon_decl = anon_decl },
35229 else => unreachable,
35230 },
35231 .len = resolved_len,
35232 } }))),
35277 .decl, .mut_decl, .anon_decl => return val,
3523335278 .comptime_field => |field_val| {
3523435279 const resolved_field_val =
3523535280 (try sema.resolveLazyValue(Value.fromInterned(field_val))).toIntern();
35236 return if (resolved_field_val == field_val and resolved_len == ptr.len)
35281 return if (resolved_field_val == field_val)
3523735282 val
3523835283 else
3523935284 Value.fromInterned((try mod.intern(.{ .ptr = .{
3524035285 .ty = ptr.ty,
3524135286 .addr = .{ .comptime_field = resolved_field_val },
35242 .len = resolved_len,
3524335287 } })));
3524435288 },
3524535289 .int => |int| {
3524635290 const resolved_int = (try sema.resolveLazyValue(Value.fromInterned(int))).toIntern();
35247 return if (resolved_int == int and resolved_len == ptr.len)
35291 return if (resolved_int == int)
3524835292 val
3524935293 else
3525035294 Value.fromInterned((try mod.intern(.{ .ptr = .{
3525135295 .ty = ptr.ty,
3525235296 .addr = .{ .int = resolved_int },
35253 .len = resolved_len,
3525435297 } })));
3525535298 },
3525635299 .eu_payload, .opt_payload => |base| {
3525735300 const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base))).toIntern();
35258 return if (resolved_base == base and resolved_len == ptr.len)
35301 return if (resolved_base == base)
3525935302 val
3526035303 else
3526135304 Value.fromInterned((try mod.intern(.{ .ptr = .{
......@@ -35265,12 +35308,11 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
3526535308 .opt_payload => .{ .opt_payload = resolved_base },
3526635309 else => unreachable,
3526735310 },
35268 .len = ptr.len,
3526935311 } })));
3527035312 },
3527135313 .elem, .field => |base_index| {
3527235314 const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base_index.base))).toIntern();
35273 return if (resolved_base == base_index.base and resolved_len == ptr.len)
35315 return if (resolved_base == base_index.base)
3527435316 val
3527535317 else
3527635318 Value.fromInterned((try mod.intern(.{ .ptr = .{
......@@ -35286,7 +35328,6 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
3528635328 } },
3528735329 else => unreachable,
3528835330 },
35289 .len = ptr.len,
3529035331 } })));
3529135332 },
3529235333 }
src/TypedValue.zig+46-42
......@@ -264,52 +264,56 @@ pub fn print(
264264 .float => |float| switch (float.storage) {
265265 inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}),
266266 },
267 .ptr => |ptr| {
268 if (ptr.addr == .int) {
269 switch (ip.indexToKey(ptr.addr.int)) {
270 .int => |i| switch (i.storage) {
271 inline else => |addr| return writer.print("{x:0>8}", .{addr}),
272 },
273 .undef => return writer.writeAll("undefined"),
274 else => unreachable,
275 }
267 .slice => |slice| {
268 const ptr_ty = switch (ip.indexToKey(slice.ptr)) {
269 .ptr => |ptr| ty: {
270 if (ptr.addr == .int) return print(.{
271 .ty = Type.fromInterned(ptr.ty),
272 .val = Value.fromInterned(slice.ptr),
273 }, writer, level - 1, mod);
274 break :ty ip.indexToKey(ptr.ty).ptr_type;
275 },
276 .undef => |ptr_ty| ip.indexToKey(ptr_ty).ptr_type,
277 else => unreachable,
278 };
279 if (level == 0) {
280 return writer.writeAll(".{ ... }");
276281 }
277
278 const ptr_ty = ip.indexToKey(ty.toIntern()).ptr_type;
279 if (ptr_ty.flags.size == .Slice) {
280 if (level == 0) {
281 return writer.writeAll(".{ ... }");
282 }
283 const elem_ty = Type.fromInterned(ptr_ty.child);
284 const len = Value.fromInterned(ptr.len).toUnsignedInt(mod);
285 if (elem_ty.eql(Type.u8, mod)) str: {
286 const max_len = @min(len, max_string_len);
287 var buf: [max_string_len]u8 = undefined;
288 for (buf[0..max_len], 0..) |*c, i| {
289 const maybe_elem = try val.maybeElemValue(mod, i);
290 const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }");
291 if (elem.isUndef(mod)) break :str;
292 c.* = @as(u8, @intCast(elem.toUnsignedInt(mod)));
293 }
294 const truncated = if (len > max_string_len) " (truncated)" else "";
295 return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
296 }
297 try writer.writeAll(".{ ");
298 const max_len = @min(len, max_aggregate_items);
299 for (0..max_len) |i| {
300 if (i != 0) try writer.writeAll(", ");
282 const elem_ty = Type.fromInterned(ptr_ty.child);
283 const len = Value.fromInterned(slice.len).toUnsignedInt(mod);
284 if (elem_ty.eql(Type.u8, mod)) str: {
285 const max_len = @min(len, max_string_len);
286 var buf: [max_string_len]u8 = undefined;
287 for (buf[0..max_len], 0..) |*c, i| {
301288 const maybe_elem = try val.maybeElemValue(mod, i);
302 const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }");
303 try print(.{
304 .ty = elem_ty,
305 .val = elem,
306 }, writer, level - 1, mod);
307 }
308 if (len > max_aggregate_items) {
309 try writer.writeAll(", ...");
289 const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }");
290 if (elem.isUndef(mod)) break :str;
291 c.* = @as(u8, @intCast(elem.toUnsignedInt(mod)));
310292 }
311 return writer.writeAll(" }");
293 const truncated = if (len > max_string_len) " (truncated)" else "";
294 return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
295 }
296 try writer.writeAll(".{ ");
297 const max_len = @min(len, max_aggregate_items);
298 for (0..max_len) |i| {
299 if (i != 0) try writer.writeAll(", ");
300 const maybe_elem = try val.maybeElemValue(mod, i);
301 const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }");
302 try print(.{
303 .ty = elem_ty,
304 .val = elem,
305 }, writer, level - 1, mod);
312306 }
307 if (len > max_aggregate_items) {
308 try writer.writeAll(", ...");
309 }
310 return writer.writeAll(" }");
311 },
312 .ptr => |ptr| {
313 if (ptr.addr == .int) {}
314
315 const ptr_ty = ip.indexToKey(ty.toIntern()).ptr_type;
316 if (ptr_ty.flags.size == .Slice) {}
313317
314318 switch (ptr.addr) {
315319 .decl => |decl_index| {
src/arch/wasm/CodeGen.zig+12-3
......@@ -3179,9 +3179,6 @@ fn lowerAnonDeclRef(
31793179
31803180fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
31813181 const mod = func.bin_file.base.comp.module.?;
3182 if (tv.ty.isSlice(mod)) {
3183 return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) };
3184 }
31853182
31863183 const decl = mod.declPtr(decl_index);
31873184 // check if decl is an alias to a function, in which case we
......@@ -3335,6 +3332,18 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33353332 .f64 => |f64_val| return WValue{ .float64 = f64_val },
33363333 else => unreachable,
33373334 },
3335 .slice => |slice| {
3336 var ptr = ip.indexToKey(slice.ptr).ptr;
3337 const owner_decl = while (true) switch (ptr.addr) {
3338 .decl => |decl| break decl,
3339 .mut_decl => |mut_decl| break mut_decl.decl,
3340 .int, .anon_decl => return func.fail("Wasm TODO: lower slice where ptr is not owned by decl", .{}),
3341 .opt_payload, .eu_payload => |base| ptr = ip.indexToKey(base).ptr,
3342 .elem, .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr,
3343 .comptime_field => unreachable,
3344 };
3345 return .{ .memory = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, owner_decl) };
3346 },
33383347 .ptr => |ptr| switch (ptr.addr) {
33393348 .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0),
33403349 .mut_decl => |mut_decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, mut_decl.decl, 0),
src/codegen.zig+15-16
......@@ -322,24 +322,24 @@ pub fn generateSymbol(
322322 },
323323 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),
324324 },
325 .ptr => |ptr| {
326 // generate ptr
327 switch (try lowerParentPtr(bin_file, src_loc, switch (ptr.len) {
328 .none => typed_value.val,
329 else => typed_value.val.slicePtr(mod),
330 }.toIntern(), code, debug_output, reloc_info)) {
325 .ptr => switch (try lowerParentPtr(bin_file, src_loc, typed_value.val.toIntern(), code, debug_output, reloc_info)) {
326 .ok => {},
327 .fail => |em| return .{ .fail = em },
328 },
329 .slice => |slice| {
330 switch (try generateSymbol(bin_file, src_loc, .{
331 .ty = typed_value.ty.slicePtrFieldType(mod),
332 .val = Value.fromInterned(slice.ptr),
333 }, code, debug_output, reloc_info)) {
331334 .ok => {},
332335 .fail => |em| return .{ .fail = em },
333336 }
334 if (ptr.len != .none) {
335 // generate len
336 switch (try generateSymbol(bin_file, src_loc, .{
337 .ty = Type.usize,
338 .val = Value.fromInterned(ptr.len),
339 }, code, debug_output, reloc_info)) {
340 .ok => {},
341 .fail => |em| return Result{ .fail = em },
342 }
337 switch (try generateSymbol(bin_file, src_loc, .{
338 .ty = Type.usize,
339 .val = Value.fromInterned(slice.len),
340 }, code, debug_output, reloc_info)) {
341 .ok => {},
342 .fail => |em| return .{ .fail = em },
343343 }
344344 },
345345 .opt => {
......@@ -676,7 +676,6 @@ fn lowerParentPtr(
676676) CodeGenError!Result {
677677 const mod = bin_file.comp.module.?;
678678 const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr;
679 assert(ptr.len == .none);
680679 return switch (ptr.addr) {
681680 .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info),
682681 .mut_decl => |md| try lowerDeclRef(bin_file, src_loc, md.decl, code, debug_output, reloc_info),
src/codegen/c.zig+28-43
......@@ -1207,50 +1207,35 @@ pub const DeclGen = struct {
12071207 try writer.print("{x}", .{try dg.fmtIntLiteral(repr_ty, repr_val, location)});
12081208 if (!empty) try writer.writeByte(')');
12091209 },
1210 .ptr => |ptr| {
1211 if (ptr.len != .none) {
1212 if (!location.isInitializer()) {
1213 try writer.writeByte('(');
1214 try dg.renderType(writer, ty);
1215 try writer.writeByte(')');
1216 }
1217 try writer.writeByte('{');
1218 }
1219 const ptr_location = switch (ptr.len) {
1220 .none => location,
1221 else => initializer_type,
1222 };
1223 const ptr_ty = switch (ptr.len) {
1224 .none => ty,
1225 else => ty.slicePtrFieldType(mod),
1226 };
1227 const ptr_val = switch (ptr.len) {
1228 .none => val,
1229 else => val.slicePtr(mod),
1230 };
1231 switch (ptr.addr) {
1232 .decl => |d| try dg.renderDeclValue(writer, ptr_ty, ptr_val, d, ptr_location),
1233 .mut_decl => |md| try dg.renderDeclValue(writer, ptr_ty, ptr_val, md.decl, ptr_location),
1234 .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ptr_ty, ptr_val, decl_val, ptr_location),
1235 .int => |int| {
1236 try writer.writeAll("((");
1237 try dg.renderType(writer, ptr_ty);
1238 try writer.print("){x})", .{
1239 try dg.fmtIntLiteral(Type.usize, Value.fromInterned(int), ptr_location),
1240 });
1241 },
1242 .eu_payload,
1243 .opt_payload,
1244 .elem,
1245 .field,
1246 => try dg.renderParentPtr(writer, ptr_val.ip_index, ptr_location),
1247 .comptime_field => unreachable,
1248 }
1249 if (ptr.len != .none) {
1250 try writer.writeAll(", ");
1251 try dg.renderValue(writer, Type.usize, Value.fromInterned(ptr.len), initializer_type);
1252 try writer.writeByte('}');
1210 .slice => |slice| {
1211 if (!location.isInitializer()) {
1212 try writer.writeByte('(');
1213 try dg.renderType(writer, ty);
1214 try writer.writeByte(')');
12531215 }
1216 try writer.writeByte('{');
1217 try dg.renderValue(writer, ty.slicePtrFieldType(mod), Value.fromInterned(slice.ptr), initializer_type);
1218 try writer.writeAll(", ");
1219 try dg.renderValue(writer, Type.usize, Value.fromInterned(slice.len), initializer_type);
1220 try writer.writeByte('}');
1221 },
1222 .ptr => |ptr| switch (ptr.addr) {
1223 .decl => |d| try dg.renderDeclValue(writer, ty, val, d, location),
1224 .mut_decl => |md| try dg.renderDeclValue(writer, ty, val, md.decl, location),
1225 .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ty, val, decl_val, location),
1226 .int => |int| {
1227 try writer.writeAll("((");
1228 try dg.renderType(writer, ty);
1229 try writer.print("){x})", .{
1230 try dg.fmtIntLiteral(Type.usize, Value.fromInterned(int), location),
1231 });
1232 },
1233 .eu_payload,
1234 .opt_payload,
1235 .elem,
1236 .field,
1237 => try dg.renderParentPtr(writer, val.ip_index, location),
1238 .comptime_field => unreachable,
12541239 },
12551240 .opt => |opt| {
12561241 const payload_ty = ty.optionalChild(mod);
src/codegen/llvm.zig+16-23
......@@ -3644,6 +3644,7 @@ pub const Object = struct {
36443644 .empty_enum_value,
36453645 .float,
36463646 .ptr,
3647 .slice,
36473648 .opt,
36483649 .aggregate,
36493650 .un,
......@@ -3872,30 +3873,22 @@ pub const Object = struct {
38723873 128 => try o.builder.fp128Const(val.toFloat(f128, mod)),
38733874 else => unreachable,
38743875 },
3875 .ptr => |ptr| {
3876 const ptr_ty = switch (ptr.len) {
3877 .none => ty,
3878 else => ty.slicePtrFieldType(mod),
3879 };
3880 const ptr_val = switch (ptr.addr) {
3881 .decl => |decl| try o.lowerDeclRefValue(ptr_ty, decl),
3882 .mut_decl => |mut_decl| try o.lowerDeclRefValue(ptr_ty, mut_decl.decl),
3883 .anon_decl => |anon_decl| try o.lowerAnonDeclRef(ptr_ty, anon_decl),
3884 .int => |int| try o.lowerIntAsPtr(int),
3885 .eu_payload,
3886 .opt_payload,
3887 .elem,
3888 .field,
3889 => try o.lowerParentPtr(val),
3890 .comptime_field => unreachable,
3891 };
3892 switch (ptr.len) {
3893 .none => return ptr_val,
3894 else => return o.builder.structConst(try o.lowerType(ty), &.{
3895 ptr_val, try o.lowerValue(ptr.len),
3896 }),
3897 }
3876 .ptr => |ptr| return switch (ptr.addr) {
3877 .decl => |decl| try o.lowerDeclRefValue(ty, decl),
3878 .mut_decl => |mut_decl| try o.lowerDeclRefValue(ty, mut_decl.decl),
3879 .anon_decl => |anon_decl| try o.lowerAnonDeclRef(ty, anon_decl),
3880 .int => |int| try o.lowerIntAsPtr(int),
3881 .eu_payload,
3882 .opt_payload,
3883 .elem,
3884 .field,
3885 => try o.lowerParentPtr(val),
3886 .comptime_field => unreachable,
38983887 },
3888 .slice => |slice| return o.builder.structConst(try o.lowerType(ty), &.{
3889 try o.lowerValue(slice.ptr),
3890 try o.lowerValue(slice.len),
3891 }),
38993892 .opt => |opt| {
39003893 comptime assert(optional_layout_version == 3);
39013894 const payload_ty = ty.optionalChild(mod);
src/codegen/spirv.zig+6-12
......@@ -855,18 +855,12 @@ const DeclGen = struct {
855855 const int_ty = ty.intTagType(mod);
856856 return try self.constant(int_ty, int_val, repr);
857857 },
858 .ptr => |ptr| {
859 const ptr_ty = switch (ptr.len) {
860 .none => ty,
861 else => ty.slicePtrFieldType(mod),
862 };
863 const ptr_id = try self.constantPtr(ptr_ty, val);
864 if (ptr.len == .none) {
865 return ptr_id;
866 }
867
868 const len_id = try self.constant(Type.usize, Value.fromInterned(ptr.len), .indirect);
869 return try self.constructStruct(
858 .ptr => return self.constantPtr(ty, val),
859 .slice => |slice| {
860 const ptr_ty = ty.slicePtrFieldType(mod);
861 const ptr_id = try self.constantPtr(ptr_ty, Value.fromInterned(slice.ptr));
862 const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect);
863 return self.constructStruct(
870864 ty,
871865 &.{ ptr_ty, Type.usize },
872866 &.{ ptr_id, len_id },
src/type.zig+9
......@@ -426,6 +426,7 @@ pub const Type = struct {
426426 .empty_enum_value,
427427 .float,
428428 .ptr,
429 .slice,
429430 .opt,
430431 .aggregate,
431432 .un,
......@@ -651,6 +652,7 @@ pub const Type = struct {
651652 .empty_enum_value,
652653 .float,
653654 .ptr,
655 .slice,
654656 .opt,
655657 .aggregate,
656658 .un,
......@@ -758,6 +760,7 @@ pub const Type = struct {
758760 .empty_enum_value,
759761 .float,
760762 .ptr,
763 .slice,
761764 .opt,
762765 .aggregate,
763766 .un,
......@@ -1073,6 +1076,7 @@ pub const Type = struct {
10731076 .empty_enum_value,
10741077 .float,
10751078 .ptr,
1079 .slice,
10761080 .opt,
10771081 .aggregate,
10781082 .un,
......@@ -1434,6 +1438,7 @@ pub const Type = struct {
14341438 .empty_enum_value,
14351439 .float,
14361440 .ptr,
1441 .slice,
14371442 .opt,
14381443 .aggregate,
14391444 .un,
......@@ -1660,6 +1665,7 @@ pub const Type = struct {
16601665 .empty_enum_value,
16611666 .float,
16621667 .ptr,
1668 .slice,
16631669 .opt,
16641670 .aggregate,
16651671 .un,
......@@ -2195,6 +2201,7 @@ pub const Type = struct {
21952201 .empty_enum_value,
21962202 .float,
21972203 .ptr,
2204 .slice,
21982205 .opt,
21992206 .aggregate,
22002207 .un,
......@@ -2538,6 +2545,7 @@ pub const Type = struct {
25382545 .empty_enum_value,
25392546 .float,
25402547 .ptr,
2548 .slice,
25412549 .opt,
25422550 .aggregate,
25432551 .un,
......@@ -2731,6 +2739,7 @@ pub const Type = struct {
27312739 .empty_enum_value,
27322740 .float,
27332741 .ptr,
2742 .slice,
27342743 .opt,
27352744 .aggregate,
27362745 .un,
src/value.zig+36-48
......@@ -194,10 +194,7 @@ pub const Value = struct {
194194 const ip = &mod.intern_pool;
195195 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
196196 .enum_literal => |enum_literal| enum_literal,
197 .ptr => |ptr| switch (ptr.len) {
198 .none => unreachable,
199 else => try arrayToIpString(val, Value.fromInterned(ptr.len).toUnsignedInt(mod), mod),
200 },
197 .slice => |slice| try arrayToIpString(val, Value.fromInterned(slice.len).toUnsignedInt(mod), mod),
201198 .aggregate => |aggregate| switch (aggregate.storage) {
202199 .bytes => |bytes| try ip.getOrPutString(mod.gpa, bytes),
203200 .elems => try arrayToIpString(val, ty.arrayLen(mod), mod),
......@@ -217,10 +214,7 @@ pub const Value = struct {
217214 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {
218215 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
219216 .enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)),
220 .ptr => |ptr| switch (ptr.len) {
221 .none => unreachable,
222 else => try arrayToAllocatedBytes(val, Value.fromInterned(ptr.len).toUnsignedInt(mod), allocator, mod),
223 },
217 .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(mod), allocator, mod),
224218 .aggregate => |aggregate| switch (aggregate.storage) {
225219 .bytes => |bytes| try allocator.dupe(u8, bytes),
226220 .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),
......@@ -286,12 +280,11 @@ pub const Value = struct {
286280 },
287281 .slice => {
288282 const pl = val.castTag(.slice).?.data;
289 const ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod);
290 var ptr_key = ip.indexToKey(ptr).ptr;
291 assert(ptr_key.len == .none);
292 ptr_key.ty = ty.toIntern();
293 ptr_key.len = try pl.len.intern(Type.usize, mod);
294 return mod.intern(.{ .ptr = ptr_key });
283 return mod.intern(.{ .slice = .{
284 .ty = ty.toIntern(),
285 .len = try pl.len.intern(Type.usize, mod),
286 .ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod),
287 } });
295288 },
296289 .bytes => {
297290 const pl = val.castTag(.bytes).?.data;
......@@ -374,6 +367,7 @@ pub const Value = struct {
374367 .enum_tag,
375368 .empty_enum_value,
376369 .float,
370 .ptr,
377371 => val,
378372
379373 .error_union => |error_union| switch (error_union.val) {
......@@ -381,13 +375,10 @@ pub const Value = struct {
381375 .payload => |payload| Tag.eu_payload.create(arena, Value.fromInterned(payload)),
382376 },
383377
384 .ptr => |ptr| switch (ptr.len) {
385 .none => val,
386 else => |len| Tag.slice.create(arena, .{
387 .ptr = val.slicePtr(mod),
388 .len = Value.fromInterned(len),
389 }),
390 },
378 .slice => |slice| Tag.slice.create(arena, .{
379 .ptr = Value.fromInterned(slice.ptr),
380 .len = Value.fromInterned(slice.len),
381 }),
391382
392383 .opt => |opt| switch (opt.val) {
393384 .none => val,
......@@ -1538,6 +1529,7 @@ pub const Value = struct {
15381529
15391530 pub fn isComptimeMutablePtr(val: Value, mod: *Module) bool {
15401531 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1532 .slice => |slice| return Value.fromInterned(slice.ptr).isComptimeMutablePtr(mod),
15411533 .ptr => |ptr| switch (ptr.addr) {
15421534 .mut_decl, .comptime_field => true,
15431535 .eu_payload, .opt_payload => |base_ptr| Value.fromInterned(base_ptr).isComptimeMutablePtr(mod),
......@@ -1600,9 +1592,8 @@ pub const Value = struct {
16001592
16011593 pub fn sliceLen(val: Value, mod: *Module) u64 {
16021594 const ip = &mod.intern_pool;
1603 const ptr = ip.indexToKey(val.toIntern()).ptr;
1604 return switch (ptr.len) {
1605 .none => switch (ip.indexToKey(switch (ptr.addr) {
1595 return switch (ip.indexToKey(val.toIntern())) {
1596 .ptr => |ptr| switch (ip.indexToKey(switch (ptr.addr) {
16061597 .decl => |decl| mod.declPtr(decl).ty.toIntern(),
16071598 .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(),
16081599 .anon_decl => |anon_decl| ip.typeOf(anon_decl.val),
......@@ -1612,7 +1603,8 @@ pub const Value = struct {
16121603 .array_type => |array_type| array_type.len,
16131604 else => 1,
16141605 },
1615 else => Value.fromInterned(ptr.len).toUnsignedInt(mod),
1606 .slice => |slice| Value.fromInterned(slice.len).toUnsignedInt(mod),
1607 else => unreachable,
16161608 };
16171609 }
16181610
......@@ -1636,6 +1628,7 @@ pub const Value = struct {
16361628 .undef => |ty| Value.fromInterned((try mod.intern(.{
16371629 .undef = Type.fromInterned(ty).elemType2(mod).toIntern(),
16381630 }))),
1631 .slice => |slice| return Value.fromInterned(slice.ptr).maybeElemValue(mod, index),
16391632 .ptr => |ptr| switch (ptr.addr) {
16401633 .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index),
16411634 .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValue(mod, index),
......@@ -1800,25 +1793,23 @@ pub const Value = struct {
18001793 ) Allocator.Error!Value {
18011794 const elem_ty = elem_ptr_ty.childType(mod);
18021795 const ptr_val = switch (mod.intern_pool.indexToKey(val.toIntern())) {
1803 .ptr => |ptr| ptr: {
1804 switch (ptr.addr) {
1805 .elem => |elem| if (Type.fromInterned(mod.intern_pool.typeOf(elem.base)).elemType2(mod).eql(elem_ty, mod))
1806 return Value.fromInterned((try mod.intern(.{ .ptr = .{
1807 .ty = elem_ptr_ty.toIntern(),
1808 .addr = .{ .elem = .{
1809 .base = elem.base,
1810 .index = elem.index + index,
1811 } },
1812 } }))),
1813 else => {},
1814 }
1815 break :ptr switch (ptr.len) {
1816 .none => val,
1817 else => val.slicePtr(mod),
1818 };
1819 },
1796 .slice => |slice| Value.fromInterned(slice.ptr),
18201797 else => val,
18211798 };
1799 switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
1800 .ptr => |ptr| switch (ptr.addr) {
1801 .elem => |elem| if (Type.fromInterned(mod.intern_pool.typeOf(elem.base)).elemType2(mod).eql(elem_ty, mod))
1802 return Value.fromInterned((try mod.intern(.{ .ptr = .{
1803 .ty = elem_ptr_ty.toIntern(),
1804 .addr = .{ .elem = .{
1805 .base = elem.base,
1806 .index = elem.index + index,
1807 } },
1808 } }))),
1809 else => {},
1810 },
1811 else => {},
1812 }
18221813 var ptr_ty_key = mod.intern_pool.indexToKey(elem_ptr_ty.toIntern()).ptr_type;
18231814 assert(ptr_ty_key.flags.size != .Slice);
18241815 ptr_ty_key.flags.size = .Many;
......@@ -1850,12 +1841,9 @@ pub const Value = struct {
18501841 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
18511842 .undef => true,
18521843 .simple_value => |v| v == .undefined,
1853 .ptr => |ptr| switch (ptr.len) {
1854 .none => false,
1855 else => for (0..@as(usize, @intCast(Value.fromInterned(ptr.len).toUnsignedInt(mod)))) |index| {
1856 if (try (try val.elemValue(mod, index)).anyUndef(mod)) break true;
1857 } else false,
1858 },
1844 .slice => |slice| for (0..@intCast(Value.fromInterned(slice.len).toUnsignedInt(mod))) |idx| {
1845 if (try (try val.elemValue(mod, idx)).anyUndef(mod)) break true;
1846 } else false,
18591847 .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| {
18601848 const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i];
18611849 if (try anyUndef(Value.fromInterned(elem), mod)) break true;