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) {...@@ -326,6 +326,7 @@ pub const Key = union(enum) {
326 empty_enum_value: Index,326 empty_enum_value: Index,
327 float: Float,327 float: Float,
328 ptr: Ptr,328 ptr: Ptr,
329 slice: Slice,
329 opt: Opt,330 opt: Opt,
330 /// An instance of a struct, array, or vector.331 /// An instance of a struct, array, or vector.
331 /// Each element/field stored as an `Index`.332 /// Each element/field stored as an `Index`.
...@@ -493,7 +494,7 @@ pub const Key = union(enum) {...@@ -493,7 +494,7 @@ pub const Key = union(enum) {
493 start: u32,494 start: u32,
494 len: u32,495 len: u32,
495496
496 pub fn get(slice: Slice, ip: *const InternPool) []RuntimeOrder {497 pub fn get(slice: RuntimeOrder.Slice, ip: *const InternPool) []RuntimeOrder {
497 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);498 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);
498 }499 }
499 };500 };
...@@ -1197,8 +1198,6 @@ pub const Key = union(enum) {...@@ -1197,8 +1198,6 @@ pub const Key = union(enum) {
1197 ty: Index,1198 ty: Index,
1198 /// The value of the address that the pointer points to.1199 /// The value of the address that the pointer points to.
1199 addr: Addr,1200 addr: Addr,
1200 /// This could be `none` if size is not a slice.
1201 len: Index = .none,
12021201
1203 pub const Addr = union(enum) {1202 pub const Addr = union(enum) {
1204 const Tag = @typeInfo(Addr).Union.tag_type.?;1203 const Tag = @typeInfo(Addr).Union.tag_type.?;
...@@ -1232,6 +1231,15 @@ pub const Key = union(enum) {...@@ -1232,6 +1231,15 @@ pub const Key = union(enum) {
1232 };1231 };
1233 };1232 };
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
1235 /// `null` is represented by the `val` field being `none`.1243 /// `null` is represented by the `val` field being `none`.
1236 pub const Opt = extern struct {1244 pub const Opt = extern struct {
1237 /// This is the optional type; not the payload type.1245 /// This is the optional type; not the payload type.
...@@ -1354,12 +1362,14 @@ pub const Key = union(enum) {...@@ -1354,12 +1362,14 @@ pub const Key = union(enum) {
1354 return hasher.final();1362 return hasher.final();
1355 },1363 },
13561364
1365 .slice => |slice| Hash.hash(seed, asBytes(&slice.ty) ++ asBytes(&slice.ptr) ++ asBytes(&slice.len)),
1366
1357 .ptr => |ptr| {1367 .ptr => |ptr| {
1358 // Int-to-ptr pointers are hashed separately than decl-referencing pointers.1368 // Int-to-ptr pointers are hashed separately than decl-referencing pointers.
1359 // This is sound due to pointer provenance rules.1369 // This is sound due to pointer provenance rules.
1360 const addr: @typeInfo(Key.Ptr.Addr).Union.tag_type.? = ptr.addr;1370 const addr: @typeInfo(Key.Ptr.Addr).Union.tag_type.? = ptr.addr;
1361 const seed2 = seed + @intFromEnum(addr);1371 const seed2 = seed + @intFromEnum(addr);
1362 const common = asBytes(&ptr.ty) ++ asBytes(&ptr.len);1372 const common = asBytes(&ptr.ty);
1363 return switch (ptr.addr) {1373 return switch (ptr.addr) {
1364 .decl => |x| Hash.hash(seed2, common ++ asBytes(&x)),1374 .decl => |x| Hash.hash(seed2, common ++ asBytes(&x)),
13651375
...@@ -1624,9 +1634,17 @@ pub const Key = union(enum) {...@@ -1624,9 +1634,17 @@ pub const Key = union(enum) {
1624 return a_ty_info.eql(b_ty_info, ip);1634 return a_ty_info.eql(b_ty_info, ip);
1625 },1635 },
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
1627 .ptr => |a_info| {1645 .ptr => |a_info| {
1628 const b_info = b.ptr;1646 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
1631 const AddrTag = @typeInfo(Key.Ptr.Addr).Union.tag_type.?;1649 const AddrTag = @typeInfo(Key.Ptr.Addr).Union.tag_type.?;
1632 if (@as(AddrTag, a_info.addr) != @as(AddrTag, b_info.addr)) return false;1650 if (@as(AddrTag, a_info.addr) != @as(AddrTag, b_info.addr)) return false;
...@@ -1829,6 +1847,7 @@ pub const Key = union(enum) {...@@ -1829,6 +1847,7 @@ pub const Key = union(enum) {
1829 => .type_type,1847 => .type_type,
18301848
1831 inline .ptr,1849 inline .ptr,
1850 .slice,
1832 .int,1851 .int,
1833 .float,1852 .float,
1834 .opt,1853 .opt,
...@@ -3983,77 +4002,11 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -3983,77 +4002,11 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
3983 },4002 },
3984 .ptr_slice => {4003 .ptr_slice => {
3985 const info = ip.extraData(PtrSlice, data);4004 const info = ip.extraData(PtrSlice, data);
3986 const ptr_item = ip.items.get(@intFromEnum(info.ptr));4005 return .{ .slice = .{
3987 return .{4006 .ty = info.ty,
3988 .ptr = .{4007 .ptr = info.ptr,
3989 .ty = info.ty,4008 .len = info.len,
3990 .addr = switch (ptr_item.tag) {4009 } };
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 };
4057 },4010 },
4058 .int_u8 => .{ .int = .{4011 .int_u8 => .{ .int = .{
4059 .ty = .u8_type,4012 .ty = .u8_type,
...@@ -4735,153 +4688,139 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -4735,153 +4688,139 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
4735 });4688 });
4736 },4689 },
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
4738 .ptr => |ptr| {4704 .ptr => |ptr| {
4739 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;4705 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
4740 switch (ptr.len) {4706 assert(ptr_type.flags.size != .Slice);
4741 .none => {4707 switch (ptr.addr) {
4742 assert(ptr_type.flags.size != .Slice);4708 .decl => |decl| ip.items.appendAssumeCapacity(.{
4743 switch (ptr.addr) {4709 .tag = .ptr_decl,
4744 .decl => |decl| ip.items.appendAssumeCapacity(.{4710 .data = try ip.addExtra(gpa, PtrDecl{
4745 .tag = .ptr_decl,4711 .ty = ptr.ty,
4746 .data = try ip.addExtra(gpa, PtrDecl{4712 .decl = decl,
4747 .ty = ptr.ty,4713 }),
4748 .decl = decl,4714 }),
4749 }),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,
4750 }),4729 }),
4751 .mut_decl => |mut_decl| ip.items.appendAssumeCapacity(.{4730 } else .{
4752 .tag = .ptr_mut_decl,4731 .tag = .ptr_anon_decl_aligned,
4753 .data = try ip.addExtra(gpa, PtrMutDecl{4732 .data = try ip.addExtra(gpa, PtrAnonDeclAligned{
4754 .ty = ptr.ty,4733 .ty = ptr.ty,
4755 .decl = mut_decl.decl,4734 .val = anon_decl.val,
4756 .runtime_index = mut_decl.runtime_index,4735 .orig_ty = anon_decl.orig_ty,
4757 }),
4758 }),4736 }),
4759 .anon_decl => |anon_decl| ip.items.appendAssumeCapacity(4737 },
4760 if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) .{4738 ),
4761 .tag = .ptr_anon_decl,4739 .comptime_field => |field_val| {
4762 .data = try ip.addExtra(gpa, PtrAnonDecl{4740 assert(field_val != .none);
4763 .ty = ptr.ty,4741 ip.items.appendAssumeCapacity(.{
4764 .val = anon_decl.val,4742 .tag = .ptr_comptime_field,
4765 }),4743 .data = try ip.addExtra(gpa, PtrComptimeField{
4766 } else .{4744 .ty = ptr.ty,
4767 .tag = .ptr_anon_decl_aligned,4745 .field_val = field_val,
4768 .data = try ip.addExtra(gpa, PtrAnonDeclAligned{4746 }),
4769 .ty = ptr.ty,4747 });
4770 .val = anon_decl.val,4748 },
4771 .orig_ty = anon_decl.orig_ty,4749 .int, .eu_payload, .opt_payload => |base| {
4772 }),4750 switch (ptr.addr) {
4773 },4751 .int => assert(ip.typeOf(base) == .usize_type),
4774 ),4752 .eu_payload => assert(ip.indexToKey(
4775 .comptime_field => |field_val| {4753 ip.indexToKey(ip.typeOf(base)).ptr_type.child,
4776 assert(field_val != .none);4754 ) == .error_union_type),
4777 ip.items.appendAssumeCapacity(.{4755 .opt_payload => assert(ip.indexToKey(
4778 .tag = .ptr_comptime_field,4756 ip.indexToKey(ip.typeOf(base)).ptr_type.child,
4779 .data = try ip.addExtra(gpa, PtrComptimeField{4757 ) == .opt_type),
4780 .ty = ptr.ty,4758 else => unreachable,
4781 .field_val = field_val,4759 }
4782 }),4760 ip.items.appendAssumeCapacity(.{
4783 });4761 .tag = switch (ptr.addr) {
4762 .int => .ptr_int,
4763 .eu_payload => .ptr_eu_payload,
4764 .opt_payload => .ptr_opt_payload,
4765 else => unreachable,
4784 },4766 },
4785 .int, .eu_payload, .opt_payload => |base| {4767 .data = try ip.addExtra(gpa, PtrBase{
4786 switch (ptr.addr) {4768 .ty = ptr.ty,
4787 .int => assert(ip.typeOf(base) == .usize_type),4769 .base = base,
4788 .eu_payload => assert(ip.indexToKey(4770 }),
4789 ip.indexToKey(ip.typeOf(base)).ptr_type.child,4771 });
4790 ) == .error_union_type),4772 },
4791 .opt_payload => assert(ip.indexToKey(4773 .elem, .field => |base_index| {
4792 ip.indexToKey(ip.typeOf(base)).ptr_type.child,4774 const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type;
4793 ) == .opt_type),4775 switch (ptr.addr) {
4794 else => unreachable,4776 .elem => assert(base_ptr_type.flags.size == .Many),
4795 }4777 .field => {
4796 ip.items.appendAssumeCapacity(.{4778 assert(base_ptr_type.flags.size == .One);
4797 .tag = switch (ptr.addr) {4779 switch (ip.indexToKey(base_ptr_type.child)) {
4798 .int => .ptr_int,4780 .anon_struct_type => |anon_struct_type| {
4799 .eu_payload => .ptr_eu_payload,4781 assert(ptr.addr == .field);
4800 .opt_payload => .ptr_opt_payload,4782 assert(base_index.index < anon_struct_type.types.len);
4801 else => unreachable,
4802 },4783 },
4803 .data = try ip.addExtra(gpa, PtrBase{4784 .struct_type => |struct_type| {
4804 .ty = ptr.ty,4785 assert(ptr.addr == .field);
4805 .base = base,4786 assert(base_index.index < struct_type.field_types.len);
4806 }),4787 },
4807 });4788 .union_type => |union_key| {
4808 },4789 const union_type = ip.loadUnionType(union_key);
4809 .elem, .field => |base_index| {4790 assert(ptr.addr == .field);
4810 const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type;4791 assert(base_index.index < union_type.field_names.len);
4811 switch (ptr.addr) {4792 },
4812 .elem => assert(base_ptr_type.flags.size == .Many),4793 .ptr_type => |slice_type| {
4813 .field => {4794 assert(ptr.addr == .field);
4814 assert(base_ptr_type.flags.size == .One);4795 assert(slice_type.flags.size == .Slice);
4815 switch (ip.indexToKey(base_ptr_type.child)) {4796 assert(base_index.index < 2);
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 }
4836 },4797 },
4837 else => unreachable,4798 else => unreachable,
4838 }4799 }
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 });
4858 },4800 },
4801 else => unreachable,
4859 }4802 }
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);
4866 _ = ip.map.pop();4803 _ = ip.map.pop();
4867 var new_key = key;4804 const index_index = try ip.get(gpa, .{ .int = .{
4868 new_key.ptr.ty = ip.slicePtrType(ptr.ty);4805 .ty = .usize_type,
4869 new_key.ptr.len = .none;4806 .storage = .{ .u64 = base_index.index },
4870 assert(ip.indexToKey(new_key.ptr.ty).ptr_type.flags.size == .Many);4807 } });
4871 const ptr_index = try ip.get(gpa, new_key);
4872 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);4808 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);
4873 try ip.items.ensureUnusedCapacity(gpa, 1);4809 try ip.items.ensureUnusedCapacity(gpa, 1);
4874 ip.items.appendAssumeCapacity(.{4810 ip.items.appendAssumeCapacity(.{
4875 .tag = .ptr_slice,4811 .tag = switch (ptr.addr) {
4876 .data = try ip.addExtra(gpa, PtrSlice{4812 .elem => .ptr_elem,
4813 .field => .ptr_field,
4814 else => unreachable,
4815 },
4816 .data = try ip.addExtra(gpa, PtrBaseIndex{
4877 .ty = ptr.ty,4817 .ty = ptr.ty,
4878 .ptr = ptr_index,4818 .base = base_index.base,
4879 .len = ptr.len,4819 .index = index_index,
4880 }),4820 }),
4881 });4821 });
4882 },4822 },
4883 }4823 }
4884 assert(ptr.ty == ip.indexToKey(@as(Index, @enumFromInt(ip.items.len - 1))).ptr.ty);
4885 },4824 },
48864825
4887 .opt => |opt| {4826 .opt => |opt| {
...@@ -6844,14 +6783,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -6844,14 +6783,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
6844 .val = .none,6783 .val = .none,
6845 } });6784 } });
68466785
6847 if (ip.isPointerType(new_ty)) return ip.get(gpa, .{ .ptr = .{6786 if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) {
6848 .ty = new_ty,6787 .One, .Many, .C => return ip.get(gpa, .{ .ptr = .{
6849 .addr = .{ .int = .zero_usize },6788 .ty = new_ty,
6850 .len = switch (ip.indexToKey(new_ty).ptr_type.flags.size) {6789 .addr = .{ .int = .zero_usize },
6851 .One, .Many, .C => .none,6790 } }),
6852 .Slice => try ip.get(gpa, .{ .undef = .usize_type }),6791 .Slice => return ip.get(gpa, .{ .slice = .{
6853 },6792 .ty = new_ty,
6854 } });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 };
6855 },6800 },
6856 else => switch (tags[@intFromEnum(val)]) {6801 else => switch (tags[@intFromEnum(val)]) {
6857 .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty),6802 .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...@@ -6929,11 +6874,18 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
6929 },6874 },
6930 else => {},6875 else => {},
6931 },6876 },
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)
6933 return ip.get(gpa, .{ .ptr = .{6886 return ip.get(gpa, .{ .ptr = .{
6934 .ty = new_ty,6887 .ty = new_ty,
6935 .addr = ptr.addr,6888 .addr = ptr.addr,
6936 .len = ptr.len,
6937 } })6889 } })
6938 else if (ip.isIntegerType(new_ty))6890 else if (ip.isIntegerType(new_ty))
6939 switch (ptr.addr) {6891 switch (ptr.addr) {
...@@ -6942,14 +6894,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -6942,14 +6894,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
6942 },6894 },
6943 .opt => |opt| switch (ip.indexToKey(new_ty)) {6895 .opt => |opt| switch (ip.indexToKey(new_ty)) {
6944 .ptr_type => |ptr_type| return switch (opt.val) {6896 .ptr_type => |ptr_type| return switch (opt.val) {
6945 .none => try ip.get(gpa, .{ .ptr = .{6897 .none => switch (ptr_type.flags.size) {
6946 .ty = new_ty,6898 .One, .Many, .C => try ip.get(gpa, .{ .ptr = .{
6947 .addr = .{ .int = .zero_usize },6899 .ty = new_ty,
6948 .len = switch (ptr_type.flags.size) {6900 .addr = .{ .int = .zero_usize },
6949 .One, .Many, .C => .none,6901 } }),
6950 .Slice => try ip.get(gpa, .{ .undef = .usize_type }),6902 .Slice => try ip.get(gpa, .{ .slice = .{
6951 },6903 .ty = new_ty,
6952 } }),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 },
6953 else => |payload| try ip.getCoerced(gpa, payload, new_ty),6911 else => |payload| try ip.getCoerced(gpa, payload, new_ty),
6954 },6912 },
6955 .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{6913 .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{
src/Module.zig+21-14
...@@ -5278,9 +5278,12 @@ pub fn populateTestFunctions(...@@ -5278,9 +5278,12 @@ pub fn populateTestFunctions(
52785278
5279 const test_fn_fields = .{5279 const test_fn_fields = .{
5280 // name5280 // name
5281 try mod.intern(.{ .ptr = .{5281 try mod.intern(.{ .slice = .{
5282 .ty = .slice_const_u8_type,5282 .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 } }),
5284 .len = try mod.intern(.{ .int = .{5287 .len = try mod.intern(.{ .int = .{
5285 .ty = .usize_type,5288 .ty = .usize_type,
5286 .storage = .{ .u64 = test_decl_name.len },5289 .storage = .{ .u64 = test_decl_name.len },
...@@ -5331,9 +5334,12 @@ pub fn populateTestFunctions(...@@ -5331,9 +5334,12 @@ pub fn populateTestFunctions(
5331 },5334 },
5332 });5335 });
5333 const new_val = decl.val;5336 const new_val = decl.val;
5334 const new_init = try mod.intern(.{ .ptr = .{5337 const new_init = try mod.intern(.{ .slice = .{
5335 .ty = new_ty.toIntern(),5338 .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 } }),
5337 .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(),5343 .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(),
5338 } });5344 } });
5339 ip.mutateVarInit(decl.val.toIntern(), new_init);5345 ip.mutateVarInit(decl.val.toIntern(), new_init);
...@@ -5423,16 +5429,17 @@ pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void {...@@ -5423,16 +5429,17 @@ pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void {
5423 .err_name => {},5429 .err_name => {},
5424 .payload => |payload| try mod.markReferencedDeclsAlive(Value.fromInterned(payload)),5430 .payload => |payload| try mod.markReferencedDeclsAlive(Value.fromInterned(payload)),
5425 },5431 },
5426 .ptr => |ptr| {5432 .slice => |slice| {
5427 switch (ptr.addr) {5433 try mod.markReferencedDeclsAlive(Value.fromInterned(slice.ptr));
5428 .decl => |decl| try mod.markDeclIndexAlive(decl),5434 try mod.markReferencedDeclsAlive(Value.fromInterned(slice.len));
5429 .anon_decl => {},5435 },
5430 .mut_decl => |mut_decl| try mod.markDeclIndexAlive(mut_decl.decl),5436 .ptr => |ptr| switch (ptr.addr) {
5431 .int, .comptime_field => {},5437 .decl => |decl| try mod.markDeclIndexAlive(decl),
5432 .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(Value.fromInterned(parent)),5438 .anon_decl => {},
5433 .elem, .field => |base_index| try mod.markReferencedDeclsAlive(Value.fromInterned(base_index.base)),5439 .mut_decl => |mut_decl| try mod.markDeclIndexAlive(mut_decl.decl),
5434 }5440 .int, .comptime_field => {},
5435 if (ptr.len != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(ptr.len));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)),
5436 },5443 },
5437 .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(opt.val)),5444 .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(opt.val)),
5438 .aggregate => |aggregate| for (aggregate.storage.values()) |elem|5445 .aggregate => |aggregate| for (aggregate.storage.values()) |elem|
src/Sema.zig+165-124
...@@ -17375,16 +17375,19 @@ fn zirBuiltinSrc(...@@ -17375,16 +17375,19 @@ fn zirBuiltinSrc(
17375 .sentinel = .zero_u8,17375 .sentinel = .zero_u8,
17376 .child = .u8_type,17376 .child = .u8_type,
17377 } });17377 } });
17378 break :v try ip.get(gpa, .{ .ptr = .{17378 break :v try ip.get(gpa, .{ .slice = .{
17379 .ty = .slice_const_u8_sentinel_0_type,17379 .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 } }),
17380 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),17390 .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 } },
17388 } });17391 } });
17389 };17392 };
1739017393
...@@ -17396,16 +17399,19 @@ fn zirBuiltinSrc(...@@ -17396,16 +17399,19 @@ fn zirBuiltinSrc(
17396 .sentinel = .zero_u8,17399 .sentinel = .zero_u8,
17397 .child = .u8_type,17400 .child = .u8_type,
17398 } });17401 } });
17399 break :v try ip.get(gpa, .{ .ptr = .{17402 break :v try ip.get(gpa, .{ .slice = .{
17400 .ty = .slice_const_u8_sentinel_0_type,17403 .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 } }),
17401 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),17414 .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 } },
17409 } });17415 } });
17410 };17416 };
1741117417
...@@ -17517,12 +17523,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17517,12 +17523,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17517 .is_const = true,17523 .is_const = true,
17518 },17524 },
17519 })).toIntern();17525 })).toIntern();
17520 break :v try mod.intern(.{ .ptr = .{17526 break :v try mod.intern(.{ .slice = .{
17521 .ty = ptr_ty,17527 .ty = ptr_ty,
17522 .addr = .{ .anon_decl = .{17528 .ptr = try mod.intern(.{ .ptr = .{
17523 .orig_ty = ptr_ty,17529 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
17524 .val = new_decl_val,17530 .addr = .{ .anon_decl = .{
17525 } },17531 .orig_ty = ptr_ty,
17532 .val = new_decl_val,
17533 } },
17534 } }),
17526 .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),17535 .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),
17527 } });17536 } });
17528 };17537 };
...@@ -17796,12 +17805,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17796,12 +17805,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17796 .ty = new_decl_ty.toIntern(),17805 .ty = new_decl_ty.toIntern(),
17797 .storage = .{ .bytes = name },17806 .storage = .{ .bytes = name },
17798 } });17807 } });
17799 break :v try mod.intern(.{ .ptr = .{17808 break :v try mod.intern(.{ .slice = .{
17800 .ty = .slice_const_u8_sentinel_0_type,17809 .ty = .slice_const_u8_sentinel_0_type,
17801 .addr = .{ .anon_decl = .{17810 .ptr = try mod.intern(.{ .ptr = .{
17802 .val = new_decl_val,17811 .ty = .manyptr_const_u8_sentinel_0_type,
17803 .orig_ty = .slice_const_u8_sentinel_0_type,17812 .addr = .{ .anon_decl = .{
17804 } },17813 .val = new_decl_val,
17814 .orig_ty = .slice_const_u8_sentinel_0_type,
17815 } },
17816 } }),
17805 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),17817 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
17806 } });17818 } });
17807 };17819 };
...@@ -17838,12 +17850,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17838,12 +17850,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17838 .ty = array_errors_ty.toIntern(),17850 .ty = array_errors_ty.toIntern(),
17839 .storage = .{ .elems = vals },17851 .storage = .{ .elems = vals },
17840 } });17852 } });
17841 break :v try mod.intern(.{ .ptr = .{17853 break :v try mod.intern(.{ .slice = .{
17842 .ty = slice_errors_ty.toIntern(),17854 .ty = slice_errors_ty.toIntern(),
17843 .addr = .{ .anon_decl = .{17855 .ptr = try mod.intern(.{ .ptr = .{
17844 .orig_ty = slice_errors_ty.toIntern(),17856 .ty = slice_errors_ty.slicePtrFieldType(mod).toIntern(),
17845 .val = new_decl_val,17857 .addr = .{ .anon_decl = .{
17846 } },17858 .orig_ty = slice_errors_ty.toIntern(),
17859 .val = new_decl_val,
17860 } },
17861 } }),
17847 .len = (try mod.intValue(Type.usize, vals.len)).toIntern(),17862 .len = (try mod.intValue(Type.usize, vals.len)).toIntern(),
17848 } });17863 } });
17849 } else .none;17864 } else .none;
...@@ -17925,12 +17940,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17925,12 +17940,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17925 .ty = new_decl_ty.toIntern(),17940 .ty = new_decl_ty.toIntern(),
17926 .storage = .{ .bytes = name },17941 .storage = .{ .bytes = name },
17927 } });17942 } });
17928 break :v try mod.intern(.{ .ptr = .{17943 break :v try mod.intern(.{ .slice = .{
17929 .ty = .slice_const_u8_sentinel_0_type,17944 .ty = .slice_const_u8_sentinel_0_type,
17930 .addr = .{ .anon_decl = .{17945 .ptr = try mod.intern(.{ .ptr = .{
17931 .val = new_decl_val,17946 .ty = .manyptr_const_u8_sentinel_0_type,
17932 .orig_ty = .slice_const_u8_sentinel_0_type,17947 .addr = .{ .anon_decl = .{
17933 } },17948 .val = new_decl_val,
17949 .orig_ty = .slice_const_u8_sentinel_0_type,
17950 } },
17951 } }),
17934 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),17952 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
17935 } });17953 } });
17936 };17954 };
...@@ -17963,12 +17981,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17963,12 +17981,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17963 .is_const = true,17981 .is_const = true,
17964 },17982 },
17965 })).toIntern();17983 })).toIntern();
17966 break :v try mod.intern(.{ .ptr = .{17984 break :v try mod.intern(.{ .slice = .{
17967 .ty = ptr_ty,17985 .ty = ptr_ty,
17968 .addr = .{ .anon_decl = .{17986 .ptr = try mod.intern(.{ .ptr = .{
17969 .val = new_decl_val,17987 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
17970 .orig_ty = ptr_ty,17988 .addr = .{ .anon_decl = .{
17971 } },17989 .val = new_decl_val,
17990 .orig_ty = ptr_ty,
17991 } },
17992 } }),
17972 .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),17993 .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),
17973 } });17994 } });
17974 };17995 };
...@@ -18051,12 +18072,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18051,12 +18072,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18051 .ty = new_decl_ty.toIntern(),18072 .ty = new_decl_ty.toIntern(),
18052 .storage = .{ .bytes = name },18073 .storage = .{ .bytes = name },
18053 } });18074 } });
18054 break :v try mod.intern(.{ .ptr = .{18075 break :v try mod.intern(.{ .slice = .{
18055 .ty = .slice_const_u8_sentinel_0_type,18076 .ty = .slice_const_u8_sentinel_0_type,
18056 .addr = .{ .anon_decl = .{18077 .ptr = try mod.intern(.{ .ptr = .{
18057 .val = new_decl_val,18078 .ty = .manyptr_const_u8_sentinel_0_type,
18058 .orig_ty = .slice_const_u8_sentinel_0_type,18079 .addr = .{ .anon_decl = .{
18059 } },18080 .val = new_decl_val,
18081 .orig_ty = .slice_const_u8_sentinel_0_type,
18082 } },
18083 } }),
18060 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),18084 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
18061 } });18085 } });
18062 };18086 };
...@@ -18097,12 +18121,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18097,12 +18121,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18097 .is_const = true,18121 .is_const = true,
18098 },18122 },
18099 })).toIntern();18123 })).toIntern();
18100 break :v try mod.intern(.{ .ptr = .{18124 break :v try mod.intern(.{ .slice = .{
18101 .ty = ptr_ty,18125 .ty = ptr_ty,
18102 .addr = .{ .anon_decl = .{18126 .ptr = try mod.intern(.{ .ptr = .{
18103 .orig_ty = ptr_ty,18127 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
18104 .val = new_decl_val,18128 .addr = .{ .anon_decl = .{
18105 } },18129 .orig_ty = ptr_ty,
18130 .val = new_decl_val,
18131 } },
18132 } }),
18106 .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),18133 .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),
18107 } });18134 } });
18108 };18135 };
...@@ -18199,12 +18226,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18199,12 +18226,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18199 .ty = new_decl_ty.toIntern(),18226 .ty = new_decl_ty.toIntern(),
18200 .storage = .{ .bytes = bytes },18227 .storage = .{ .bytes = bytes },
18201 } });18228 } });
18202 break :v try mod.intern(.{ .ptr = .{18229 break :v try mod.intern(.{ .slice = .{
18203 .ty = .slice_const_u8_sentinel_0_type,18230 .ty = .slice_const_u8_sentinel_0_type,
18204 .addr = .{ .anon_decl = .{18231 .ptr = try mod.intern(.{ .ptr = .{
18205 .val = new_decl_val,18232 .ty = .manyptr_const_u8_sentinel_0_type,
18206 .orig_ty = .slice_const_u8_sentinel_0_type,18233 .addr = .{ .anon_decl = .{
18207 } },18234 .val = new_decl_val,
18235 .orig_ty = .slice_const_u8_sentinel_0_type,
18236 } },
18237 } }),
18208 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),18238 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
18209 } });18239 } });
18210 };18240 };
...@@ -18259,12 +18289,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18259,12 +18289,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18259 .ty = new_decl_ty.toIntern(),18289 .ty = new_decl_ty.toIntern(),
18260 .storage = .{ .bytes = name },18290 .storage = .{ .bytes = name },
18261 } });18291 } });
18262 break :v try mod.intern(.{ .ptr = .{18292 break :v try mod.intern(.{ .slice = .{
18263 .ty = .slice_const_u8_sentinel_0_type,18293 .ty = .slice_const_u8_sentinel_0_type,
18264 .addr = .{ .anon_decl = .{18294 .ptr = try mod.intern(.{ .ptr = .{
18265 .val = new_decl_val,18295 .ty = .manyptr_const_u8_sentinel_0_type,
18266 .orig_ty = .slice_const_u8_sentinel_0_type,18296 .addr = .{ .anon_decl = .{
18267 } },18297 .val = new_decl_val,
18298 .orig_ty = .slice_const_u8_sentinel_0_type,
18299 } },
18300 } }),
18268 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),18301 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
18269 } });18302 } });
18270 };18303 };
...@@ -18315,12 +18348,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18315,12 +18348,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18315 .is_const = true,18348 .is_const = true,
18316 },18349 },
18317 })).toIntern();18350 })).toIntern();
18318 break :v try mod.intern(.{ .ptr = .{18351 break :v try mod.intern(.{ .slice = .{
18319 .ty = ptr_ty,18352 .ty = ptr_ty,
18320 .addr = .{ .anon_decl = .{18353 .ptr = try mod.intern(.{ .ptr = .{
18321 .orig_ty = ptr_ty,18354 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
18322 .val = new_decl_val,18355 .addr = .{ .anon_decl = .{
18323 } },18356 .orig_ty = ptr_ty,
18357 .val = new_decl_val,
18358 } },
18359 } }),
18324 .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),18360 .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),
18325 } });18361 } });
18326 };18362 };
...@@ -18453,12 +18489,15 @@ fn typeInfoDecls(...@@ -18453,12 +18489,15 @@ fn typeInfoDecls(
18453 .is_const = true,18489 .is_const = true,
18454 },18490 },
18455 })).toIntern();18491 })).toIntern();
18456 return try mod.intern(.{ .ptr = .{18492 return try mod.intern(.{ .slice = .{
18457 .ty = ptr_ty,18493 .ty = ptr_ty,
18458 .addr = .{ .anon_decl = .{18494 .ptr = try mod.intern(.{ .ptr = .{
18459 .orig_ty = ptr_ty,18495 .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(),
18460 .val = new_decl_val,18496 .addr = .{ .anon_decl = .{
18461 } },18497 .orig_ty = ptr_ty,
18498 .val = new_decl_val,
18499 } },
18500 } }),
18462 .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),18501 .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),
18463 } });18502 } });
18464}18503}
...@@ -18498,12 +18537,15 @@ fn typeInfoNamespaceDecls(...@@ -18498,12 +18537,15 @@ fn typeInfoNamespaceDecls(
18498 .ty = new_decl_ty.toIntern(),18537 .ty = new_decl_ty.toIntern(),
18499 .storage = .{ .bytes = name },18538 .storage = .{ .bytes = name },
18500 } });18539 } });
18501 break :v try mod.intern(.{ .ptr = .{18540 break :v try mod.intern(.{ .slice = .{
18502 .ty = .slice_const_u8_sentinel_0_type,18541 .ty = .slice_const_u8_sentinel_0_type,
18503 .addr = .{ .anon_decl = .{18542 .ptr = try mod.intern(.{ .ptr = .{
18504 .orig_ty = .slice_const_u8_sentinel_0_type,18543 .ty = .manyptr_const_u8_sentinel_0_type,
18505 .val = new_decl_val,18544 .addr = .{ .anon_decl = .{
18506 } },18545 .orig_ty = .slice_const_u8_sentinel_0_type,
18546 .val = new_decl_val,
18547 } },
18548 } }),
18507 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),18549 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
18508 } });18550 } });
18509 };18551 };
...@@ -22738,9 +22780,12 @@ fn ptrCastFull(...@@ -22738,9 +22780,12 @@ fn ptrCastFull(
22738 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {22780 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {
22739 if (ptr_val.isUndef(mod)) return mod.undefRef(dest_ty);22781 if (ptr_val.isUndef(mod)) return mod.undefRef(dest_ty);
22740 const arr_len = try mod.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod));22782 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 = .{
22742 .ty = dest_ty.toIntern(),22784 .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 } }),
22744 .len = arr_len.toIntern(),22789 .len = arr_len.toIntern(),
22745 } })));22790 } })));
22746 } else {22791 } else {
...@@ -28765,21 +28810,24 @@ fn coerceExtra(...@@ -28765,21 +28810,24 @@ fn coerceExtra(
28765 if (inst_child_ty.structFieldCount(mod) == 0) {28810 if (inst_child_ty.structFieldCount(mod) == 0) {
28766 // Optional slice is represented with a null pointer so28811 // Optional slice is represented with a null pointer so
28767 // we use a dummy pointer value with the required alignment.28812 // 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 = .{
28769 .ty = dest_ty.toIntern(),28814 .ty = dest_ty.toIntern(),
28770 .addr = .{ .int = if (dest_info.flags.alignment != .none)28815 .ptr = try mod.intern(.{ .ptr = .{
28771 (try mod.intValue(28816 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),
28772 Type.usize,28817 .addr = .{ .int = if (dest_info.flags.alignment != .none)
28773 dest_info.flags.alignment.toByteUnitsOptional().?,28818 (try mod.intValue(
28774 )).toIntern()28819 Type.usize,
28775 else28820 dest_info.flags.alignment.toByteUnitsOptional().?,
28776 try mod.intern_pool.getCoercedInts(28821 )).toIntern()
28777 mod.gpa,28822 else
28778 mod.intern_pool.indexToKey(28823 try mod.intern_pool.getCoercedInts(
28779 (try Type.fromInterned(dest_info.child).lazyAbiAlignment(mod)).toIntern(),28824 mod.gpa,
28780 ).int,28825 mod.intern_pool.indexToKey(
28781 .usize_type,28826 (try Type.fromInterned(dest_info.child).lazyAbiAlignment(mod)).toIntern(),
28782 ) },28827 ).int,
28828 .usize_type,
28829 ) },
28830 } }),
28783 .len = (try mod.intValue(Type.usize, 0)).toIntern(),28831 .len = (try mod.intValue(Type.usize, 0)).toIntern(),
28784 } })));28832 } })));
28785 }28833 }
...@@ -31276,7 +31324,7 @@ fn beginComptimePtrLoad(...@@ -31276,7 +31324,7 @@ fn beginComptimePtrLoad(
31276 },31324 },
31277 Value.slice_len_index => TypedValue{31325 Value.slice_len_index => TypedValue{
31278 .ty = Type.usize,31326 .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),
31280 },31328 },
31281 else => unreachable,31329 else => unreachable,
31282 };31330 };
...@@ -31445,13 +31493,16 @@ fn coerceArrayPtrToSlice(...@@ -31445,13 +31493,16 @@ fn coerceArrayPtrToSlice(
31445 if (try sema.resolveValue(inst)) |val| {31493 if (try sema.resolveValue(inst)) |val| {
31446 const ptr_array_ty = sema.typeOf(inst);31494 const ptr_array_ty = sema.typeOf(inst);
31447 const array_ty = ptr_array_ty.childType(mod);31495 const array_ty = ptr_array_ty.childType(mod);
31448 const slice_val = try mod.intern(.{ .ptr = .{31496 const slice_val = try mod.intern(.{ .slice = .{
31449 .ty = dest_ty.toIntern(),31497 .ty = dest_ty.toIntern(),
31450 .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) {31498 .ptr = try mod.intern(.{ .ptr = .{
31451 .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) },31499 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),
31452 .ptr => |ptr| ptr.addr,31500 .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) {
31453 else => unreachable,31501 .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) },
31454 },31502 .ptr => |ptr| ptr.addr,
31503 else => unreachable,
31504 },
31505 } }),
31455 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),31506 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),
31456 } });31507 } });
31457 return Air.internedToRef(slice_val);31508 return Air.internedToRef(slice_val);
...@@ -35211,51 +35262,43 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {...@@ -35211,51 +35262,43 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
35211 (try val.getUnsignedIntAdvanced(mod, sema)).?,35262 (try val.getUnsignedIntAdvanced(mod, sema)).?,
35212 ),35263 ),
35213 },35264 },
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 },
35214 .ptr => |ptr| {35275 .ptr => |ptr| {
35215 const resolved_len = switch (ptr.len) {
35216 .none => .none,
35217 else => (try sema.resolveLazyValue(Value.fromInterned(ptr.len))).toIntern(),
35218 };
35219 switch (ptr.addr) {35276 switch (ptr.addr) {
35220 .decl, .mut_decl, .anon_decl => return if (resolved_len == ptr.len)35277 .decl, .mut_decl, .anon_decl => return val,
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 } }))),
35233 .comptime_field => |field_val| {35278 .comptime_field => |field_val| {
35234 const resolved_field_val =35279 const resolved_field_val =
35235 (try sema.resolveLazyValue(Value.fromInterned(field_val))).toIntern();35280 (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)
35237 val35282 val
35238 else35283 else
35239 Value.fromInterned((try mod.intern(.{ .ptr = .{35284 Value.fromInterned((try mod.intern(.{ .ptr = .{
35240 .ty = ptr.ty,35285 .ty = ptr.ty,
35241 .addr = .{ .comptime_field = resolved_field_val },35286 .addr = .{ .comptime_field = resolved_field_val },
35242 .len = resolved_len,
35243 } })));35287 } })));
35244 },35288 },
35245 .int => |int| {35289 .int => |int| {
35246 const resolved_int = (try sema.resolveLazyValue(Value.fromInterned(int))).toIntern();35290 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)
35248 val35292 val
35249 else35293 else
35250 Value.fromInterned((try mod.intern(.{ .ptr = .{35294 Value.fromInterned((try mod.intern(.{ .ptr = .{
35251 .ty = ptr.ty,35295 .ty = ptr.ty,
35252 .addr = .{ .int = resolved_int },35296 .addr = .{ .int = resolved_int },
35253 .len = resolved_len,
35254 } })));35297 } })));
35255 },35298 },
35256 .eu_payload, .opt_payload => |base| {35299 .eu_payload, .opt_payload => |base| {
35257 const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base))).toIntern();35300 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)
35259 val35302 val
35260 else35303 else
35261 Value.fromInterned((try mod.intern(.{ .ptr = .{35304 Value.fromInterned((try mod.intern(.{ .ptr = .{
...@@ -35265,12 +35308,11 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {...@@ -35265,12 +35308,11 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
35265 .opt_payload => .{ .opt_payload = resolved_base },35308 .opt_payload => .{ .opt_payload = resolved_base },
35266 else => unreachable,35309 else => unreachable,
35267 },35310 },
35268 .len = ptr.len,
35269 } })));35311 } })));
35270 },35312 },
35271 .elem, .field => |base_index| {35313 .elem, .field => |base_index| {
35272 const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base_index.base))).toIntern();35314 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)
35274 val35316 val
35275 else35317 else
35276 Value.fromInterned((try mod.intern(.{ .ptr = .{35318 Value.fromInterned((try mod.intern(.{ .ptr = .{
...@@ -35286,7 +35328,6 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {...@@ -35286,7 +35328,6 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
35286 } },35328 } },
35287 else => unreachable,35329 else => unreachable,
35288 },35330 },
35289 .len = ptr.len,
35290 } })));35331 } })));
35291 },35332 },
35292 }35333 }
src/TypedValue.zig+46-42
...@@ -264,52 +264,56 @@ pub fn print(...@@ -264,52 +264,56 @@ pub fn print(
264 .float => |float| switch (float.storage) {264 .float => |float| switch (float.storage) {
265 inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}),265 inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}),
266 },266 },
267 .ptr => |ptr| {267 .slice => |slice| {
268 if (ptr.addr == .int) {268 const ptr_ty = switch (ip.indexToKey(slice.ptr)) {
269 switch (ip.indexToKey(ptr.addr.int)) {269 .ptr => |ptr| ty: {
270 .int => |i| switch (i.storage) {270 if (ptr.addr == .int) return print(.{
271 inline else => |addr| return writer.print("{x:0>8}", .{addr}),271 .ty = Type.fromInterned(ptr.ty),
272 },272 .val = Value.fromInterned(slice.ptr),
273 .undef => return writer.writeAll("undefined"),273 }, writer, level - 1, mod);
274 else => unreachable,274 break :ty ip.indexToKey(ptr.ty).ptr_type;
275 }275 },
276 .undef => |ptr_ty| ip.indexToKey(ptr_ty).ptr_type,
277 else => unreachable,
278 };
279 if (level == 0) {
280 return writer.writeAll(".{ ... }");
276 }281 }
277282 const elem_ty = Type.fromInterned(ptr_ty.child);
278 const ptr_ty = ip.indexToKey(ty.toIntern()).ptr_type;283 const len = Value.fromInterned(slice.len).toUnsignedInt(mod);
279 if (ptr_ty.flags.size == .Slice) {284 if (elem_ty.eql(Type.u8, mod)) str: {
280 if (level == 0) {285 const max_len = @min(len, max_string_len);
281 return writer.writeAll(".{ ... }");286 var buf: [max_string_len]u8 = undefined;
282 }287 for (buf[0..max_len], 0..) |*c, i| {
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(", ");
301 const maybe_elem = try val.maybeElemValue(mod, i);288 const maybe_elem = try val.maybeElemValue(mod, i);
302 const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }");289 const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }");
303 try print(.{290 if (elem.isUndef(mod)) break :str;
304 .ty = elem_ty,291 c.* = @as(u8, @intCast(elem.toUnsignedInt(mod)));
305 .val = elem,
306 }, writer, level - 1, mod);
307 }
308 if (len > max_aggregate_items) {
309 try writer.writeAll(", ...");
310 }292 }
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);
312 }306 }
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
314 switch (ptr.addr) {318 switch (ptr.addr) {
315 .decl => |decl_index| {319 .decl => |decl_index| {
src/arch/wasm/CodeGen.zig+12-3
...@@ -3179,9 +3179,6 @@ fn lowerAnonDeclRef(...@@ -3179,9 +3179,6 @@ fn lowerAnonDeclRef(
31793179
3180fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {3180fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
3181 const mod = func.bin_file.base.comp.module.?;3181 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
3186 const decl = mod.declPtr(decl_index);3183 const decl = mod.declPtr(decl_index);
3187 // check if decl is an alias to a function, in which case we3184 // 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 {...@@ -3335,6 +3332,18 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3335 .f64 => |f64_val| return WValue{ .float64 = f64_val },3332 .f64 => |f64_val| return WValue{ .float64 = f64_val },
3336 else => unreachable,3333 else => unreachable,
3337 },3334 },
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 },
3338 .ptr => |ptr| switch (ptr.addr) {3347 .ptr => |ptr| switch (ptr.addr) {
3339 .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0),3348 .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0),
3340 .mut_decl => |mut_decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, mut_decl.decl, 0),3349 .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(...@@ -322,24 +322,24 @@ pub fn generateSymbol(
322 },322 },
323 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),323 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),
324 },324 },
325 .ptr => |ptr| {325 .ptr => switch (try lowerParentPtr(bin_file, src_loc, typed_value.val.toIntern(), code, debug_output, reloc_info)) {
326 // generate ptr326 .ok => {},
327 switch (try lowerParentPtr(bin_file, src_loc, switch (ptr.len) {327 .fail => |em| return .{ .fail = em },
328 .none => typed_value.val,328 },
329 else => typed_value.val.slicePtr(mod),329 .slice => |slice| {
330 }.toIntern(), code, debug_output, reloc_info)) {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)) {
331 .ok => {},334 .ok => {},
332 .fail => |em| return .{ .fail = em },335 .fail => |em| return .{ .fail = em },
333 }336 }
334 if (ptr.len != .none) {337 switch (try generateSymbol(bin_file, src_loc, .{
335 // generate len338 .ty = Type.usize,
336 switch (try generateSymbol(bin_file, src_loc, .{339 .val = Value.fromInterned(slice.len),
337 .ty = Type.usize,340 }, code, debug_output, reloc_info)) {
338 .val = Value.fromInterned(ptr.len),341 .ok => {},
339 }, code, debug_output, reloc_info)) {342 .fail => |em| return .{ .fail = em },
340 .ok => {},
341 .fail => |em| return Result{ .fail = em },
342 }
343 }343 }
344 },344 },
345 .opt => {345 .opt => {
...@@ -676,7 +676,6 @@ fn lowerParentPtr(...@@ -676,7 +676,6 @@ fn lowerParentPtr(
676) CodeGenError!Result {676) CodeGenError!Result {
677 const mod = bin_file.comp.module.?;677 const mod = bin_file.comp.module.?;
678 const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr;678 const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr;
679 assert(ptr.len == .none);
680 return switch (ptr.addr) {679 return switch (ptr.addr) {
681 .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info),680 .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info),
682 .mut_decl => |md| try lowerDeclRef(bin_file, src_loc, md.decl, code, debug_output, reloc_info),681 .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 {...@@ -1207,50 +1207,35 @@ pub const DeclGen = struct {
1207 try writer.print("{x}", .{try dg.fmtIntLiteral(repr_ty, repr_val, location)});1207 try writer.print("{x}", .{try dg.fmtIntLiteral(repr_ty, repr_val, location)});
1208 if (!empty) try writer.writeByte(')');1208 if (!empty) try writer.writeByte(')');
1209 },1209 },
1210 .ptr => |ptr| {1210 .slice => |slice| {
1211 if (ptr.len != .none) {1211 if (!location.isInitializer()) {
1212 if (!location.isInitializer()) {1212 try writer.writeByte('(');
1213 try writer.writeByte('(');1213 try dg.renderType(writer, ty);
1214 try dg.renderType(writer, ty);1214 try writer.writeByte(')');
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('}');
1253 }1215 }
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,
1254 },1239 },
1255 .opt => |opt| {1240 .opt => |opt| {
1256 const payload_ty = ty.optionalChild(mod);1241 const payload_ty = ty.optionalChild(mod);
src/codegen/llvm.zig+16-23
...@@ -3644,6 +3644,7 @@ pub const Object = struct {...@@ -3644,6 +3644,7 @@ pub const Object = struct {
3644 .empty_enum_value,3644 .empty_enum_value,
3645 .float,3645 .float,
3646 .ptr,3646 .ptr,
3647 .slice,
3647 .opt,3648 .opt,
3648 .aggregate,3649 .aggregate,
3649 .un,3650 .un,
...@@ -3872,30 +3873,22 @@ pub const Object = struct {...@@ -3872,30 +3873,22 @@ pub const Object = struct {
3872 128 => try o.builder.fp128Const(val.toFloat(f128, mod)),3873 128 => try o.builder.fp128Const(val.toFloat(f128, mod)),
3873 else => unreachable,3874 else => unreachable,
3874 },3875 },
3875 .ptr => |ptr| {3876 .ptr => |ptr| return switch (ptr.addr) {
3876 const ptr_ty = switch (ptr.len) {3877 .decl => |decl| try o.lowerDeclRefValue(ty, decl),
3877 .none => ty,3878 .mut_decl => |mut_decl| try o.lowerDeclRefValue(ty, mut_decl.decl),
3878 else => ty.slicePtrFieldType(mod),3879 .anon_decl => |anon_decl| try o.lowerAnonDeclRef(ty, anon_decl),
3879 };3880 .int => |int| try o.lowerIntAsPtr(int),
3880 const ptr_val = switch (ptr.addr) {3881 .eu_payload,
3881 .decl => |decl| try o.lowerDeclRefValue(ptr_ty, decl),3882 .opt_payload,
3882 .mut_decl => |mut_decl| try o.lowerDeclRefValue(ptr_ty, mut_decl.decl),3883 .elem,
3883 .anon_decl => |anon_decl| try o.lowerAnonDeclRef(ptr_ty, anon_decl),3884 .field,
3884 .int => |int| try o.lowerIntAsPtr(int),3885 => try o.lowerParentPtr(val),
3885 .eu_payload,3886 .comptime_field => unreachable,
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 }
3898 },3887 },
3888 .slice => |slice| return o.builder.structConst(try o.lowerType(ty), &.{
3889 try o.lowerValue(slice.ptr),
3890 try o.lowerValue(slice.len),
3891 }),
3899 .opt => |opt| {3892 .opt => |opt| {
3900 comptime assert(optional_layout_version == 3);3893 comptime assert(optional_layout_version == 3);
3901 const payload_ty = ty.optionalChild(mod);3894 const payload_ty = ty.optionalChild(mod);
src/codegen/spirv.zig+6-12
...@@ -855,18 +855,12 @@ const DeclGen = struct {...@@ -855,18 +855,12 @@ const DeclGen = struct {
855 const int_ty = ty.intTagType(mod);855 const int_ty = ty.intTagType(mod);
856 return try self.constant(int_ty, int_val, repr);856 return try self.constant(int_ty, int_val, repr);
857 },857 },
858 .ptr => |ptr| {858 .ptr => return self.constantPtr(ty, val),
859 const ptr_ty = switch (ptr.len) {859 .slice => |slice| {
860 .none => ty,860 const ptr_ty = ty.slicePtrFieldType(mod);
861 else => ty.slicePtrFieldType(mod),861 const ptr_id = try self.constantPtr(ptr_ty, Value.fromInterned(slice.ptr));
862 };862 const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect);
863 const ptr_id = try self.constantPtr(ptr_ty, val);863 return self.constructStruct(
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(
870 ty,864 ty,
871 &.{ ptr_ty, Type.usize },865 &.{ ptr_ty, Type.usize },
872 &.{ ptr_id, len_id },866 &.{ ptr_id, len_id },
src/type.zig+9
...@@ -426,6 +426,7 @@ pub const Type = struct {...@@ -426,6 +426,7 @@ pub const Type = struct {
426 .empty_enum_value,426 .empty_enum_value,
427 .float,427 .float,
428 .ptr,428 .ptr,
429 .slice,
429 .opt,430 .opt,
430 .aggregate,431 .aggregate,
431 .un,432 .un,
...@@ -651,6 +652,7 @@ pub const Type = struct {...@@ -651,6 +652,7 @@ pub const Type = struct {
651 .empty_enum_value,652 .empty_enum_value,
652 .float,653 .float,
653 .ptr,654 .ptr,
655 .slice,
654 .opt,656 .opt,
655 .aggregate,657 .aggregate,
656 .un,658 .un,
...@@ -758,6 +760,7 @@ pub const Type = struct {...@@ -758,6 +760,7 @@ pub const Type = struct {
758 .empty_enum_value,760 .empty_enum_value,
759 .float,761 .float,
760 .ptr,762 .ptr,
763 .slice,
761 .opt,764 .opt,
762 .aggregate,765 .aggregate,
763 .un,766 .un,
...@@ -1073,6 +1076,7 @@ pub const Type = struct {...@@ -1073,6 +1076,7 @@ pub const Type = struct {
1073 .empty_enum_value,1076 .empty_enum_value,
1074 .float,1077 .float,
1075 .ptr,1078 .ptr,
1079 .slice,
1076 .opt,1080 .opt,
1077 .aggregate,1081 .aggregate,
1078 .un,1082 .un,
...@@ -1434,6 +1438,7 @@ pub const Type = struct {...@@ -1434,6 +1438,7 @@ pub const Type = struct {
1434 .empty_enum_value,1438 .empty_enum_value,
1435 .float,1439 .float,
1436 .ptr,1440 .ptr,
1441 .slice,
1437 .opt,1442 .opt,
1438 .aggregate,1443 .aggregate,
1439 .un,1444 .un,
...@@ -1660,6 +1665,7 @@ pub const Type = struct {...@@ -1660,6 +1665,7 @@ pub const Type = struct {
1660 .empty_enum_value,1665 .empty_enum_value,
1661 .float,1666 .float,
1662 .ptr,1667 .ptr,
1668 .slice,
1663 .opt,1669 .opt,
1664 .aggregate,1670 .aggregate,
1665 .un,1671 .un,
...@@ -2195,6 +2201,7 @@ pub const Type = struct {...@@ -2195,6 +2201,7 @@ pub const Type = struct {
2195 .empty_enum_value,2201 .empty_enum_value,
2196 .float,2202 .float,
2197 .ptr,2203 .ptr,
2204 .slice,
2198 .opt,2205 .opt,
2199 .aggregate,2206 .aggregate,
2200 .un,2207 .un,
...@@ -2538,6 +2545,7 @@ pub const Type = struct {...@@ -2538,6 +2545,7 @@ pub const Type = struct {
2538 .empty_enum_value,2545 .empty_enum_value,
2539 .float,2546 .float,
2540 .ptr,2547 .ptr,
2548 .slice,
2541 .opt,2549 .opt,
2542 .aggregate,2550 .aggregate,
2543 .un,2551 .un,
...@@ -2731,6 +2739,7 @@ pub const Type = struct {...@@ -2731,6 +2739,7 @@ pub const Type = struct {
2731 .empty_enum_value,2739 .empty_enum_value,
2732 .float,2740 .float,
2733 .ptr,2741 .ptr,
2742 .slice,
2734 .opt,2743 .opt,
2735 .aggregate,2744 .aggregate,
2736 .un,2745 .un,
src/value.zig+36-48
...@@ -194,10 +194,7 @@ pub const Value = struct {...@@ -194,10 +194,7 @@ pub const Value = struct {
194 const ip = &mod.intern_pool;194 const ip = &mod.intern_pool;
195 return switch (mod.intern_pool.indexToKey(val.toIntern())) {195 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
196 .enum_literal => |enum_literal| enum_literal,196 .enum_literal => |enum_literal| enum_literal,
197 .ptr => |ptr| switch (ptr.len) {197 .slice => |slice| try arrayToIpString(val, Value.fromInterned(slice.len).toUnsignedInt(mod), mod),
198 .none => unreachable,
199 else => try arrayToIpString(val, Value.fromInterned(ptr.len).toUnsignedInt(mod), mod),
200 },
201 .aggregate => |aggregate| switch (aggregate.storage) {198 .aggregate => |aggregate| switch (aggregate.storage) {
202 .bytes => |bytes| try ip.getOrPutString(mod.gpa, bytes),199 .bytes => |bytes| try ip.getOrPutString(mod.gpa, bytes),
203 .elems => try arrayToIpString(val, ty.arrayLen(mod), mod),200 .elems => try arrayToIpString(val, ty.arrayLen(mod), mod),
...@@ -217,10 +214,7 @@ pub const Value = struct {...@@ -217,10 +214,7 @@ pub const Value = struct {
217 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {214 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {
218 return switch (mod.intern_pool.indexToKey(val.toIntern())) {215 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
219 .enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)),216 .enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)),
220 .ptr => |ptr| switch (ptr.len) {217 .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(mod), allocator, mod),
221 .none => unreachable,
222 else => try arrayToAllocatedBytes(val, Value.fromInterned(ptr.len).toUnsignedInt(mod), allocator, mod),
223 },
224 .aggregate => |aggregate| switch (aggregate.storage) {218 .aggregate => |aggregate| switch (aggregate.storage) {
225 .bytes => |bytes| try allocator.dupe(u8, bytes),219 .bytes => |bytes| try allocator.dupe(u8, bytes),
226 .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),220 .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),
...@@ -286,12 +280,11 @@ pub const Value = struct {...@@ -286,12 +280,11 @@ pub const Value = struct {
286 },280 },
287 .slice => {281 .slice => {
288 const pl = val.castTag(.slice).?.data;282 const pl = val.castTag(.slice).?.data;
289 const ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod);283 return mod.intern(.{ .slice = .{
290 var ptr_key = ip.indexToKey(ptr).ptr;284 .ty = ty.toIntern(),
291 assert(ptr_key.len == .none);285 .len = try pl.len.intern(Type.usize, mod),
292 ptr_key.ty = ty.toIntern();286 .ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod),
293 ptr_key.len = try pl.len.intern(Type.usize, mod);287 } });
294 return mod.intern(.{ .ptr = ptr_key });
295 },288 },
296 .bytes => {289 .bytes => {
297 const pl = val.castTag(.bytes).?.data;290 const pl = val.castTag(.bytes).?.data;
...@@ -374,6 +367,7 @@ pub const Value = struct {...@@ -374,6 +367,7 @@ pub const Value = struct {
374 .enum_tag,367 .enum_tag,
375 .empty_enum_value,368 .empty_enum_value,
376 .float,369 .float,
370 .ptr,
377 => val,371 => val,
378372
379 .error_union => |error_union| switch (error_union.val) {373 .error_union => |error_union| switch (error_union.val) {
...@@ -381,13 +375,10 @@ pub const Value = struct {...@@ -381,13 +375,10 @@ pub const Value = struct {
381 .payload => |payload| Tag.eu_payload.create(arena, Value.fromInterned(payload)),375 .payload => |payload| Tag.eu_payload.create(arena, Value.fromInterned(payload)),
382 },376 },
383377
384 .ptr => |ptr| switch (ptr.len) {378 .slice => |slice| Tag.slice.create(arena, .{
385 .none => val,379 .ptr = Value.fromInterned(slice.ptr),
386 else => |len| Tag.slice.create(arena, .{380 .len = Value.fromInterned(slice.len),
387 .ptr = val.slicePtr(mod),381 }),
388 .len = Value.fromInterned(len),
389 }),
390 },
391382
392 .opt => |opt| switch (opt.val) {383 .opt => |opt| switch (opt.val) {
393 .none => val,384 .none => val,
...@@ -1538,6 +1529,7 @@ pub const Value = struct {...@@ -1538,6 +1529,7 @@ pub const Value = struct {
15381529
1539 pub fn isComptimeMutablePtr(val: Value, mod: *Module) bool {1530 pub fn isComptimeMutablePtr(val: Value, mod: *Module) bool {
1540 return switch (mod.intern_pool.indexToKey(val.toIntern())) {1531 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1532 .slice => |slice| return Value.fromInterned(slice.ptr).isComptimeMutablePtr(mod),
1541 .ptr => |ptr| switch (ptr.addr) {1533 .ptr => |ptr| switch (ptr.addr) {
1542 .mut_decl, .comptime_field => true,1534 .mut_decl, .comptime_field => true,
1543 .eu_payload, .opt_payload => |base_ptr| Value.fromInterned(base_ptr).isComptimeMutablePtr(mod),1535 .eu_payload, .opt_payload => |base_ptr| Value.fromInterned(base_ptr).isComptimeMutablePtr(mod),
...@@ -1600,9 +1592,8 @@ pub const Value = struct {...@@ -1600,9 +1592,8 @@ pub const Value = struct {
16001592
1601 pub fn sliceLen(val: Value, mod: *Module) u64 {1593 pub fn sliceLen(val: Value, mod: *Module) u64 {
1602 const ip = &mod.intern_pool;1594 const ip = &mod.intern_pool;
1603 const ptr = ip.indexToKey(val.toIntern()).ptr;1595 return switch (ip.indexToKey(val.toIntern())) {
1604 return switch (ptr.len) {1596 .ptr => |ptr| switch (ip.indexToKey(switch (ptr.addr) {
1605 .none => switch (ip.indexToKey(switch (ptr.addr) {
1606 .decl => |decl| mod.declPtr(decl).ty.toIntern(),1597 .decl => |decl| mod.declPtr(decl).ty.toIntern(),
1607 .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(),1598 .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(),
1608 .anon_decl => |anon_decl| ip.typeOf(anon_decl.val),1599 .anon_decl => |anon_decl| ip.typeOf(anon_decl.val),
...@@ -1612,7 +1603,8 @@ pub const Value = struct {...@@ -1612,7 +1603,8 @@ pub const Value = struct {
1612 .array_type => |array_type| array_type.len,1603 .array_type => |array_type| array_type.len,
1613 else => 1,1604 else => 1,
1614 },1605 },
1615 else => Value.fromInterned(ptr.len).toUnsignedInt(mod),1606 .slice => |slice| Value.fromInterned(slice.len).toUnsignedInt(mod),
1607 else => unreachable,
1616 };1608 };
1617 }1609 }
16181610
...@@ -1636,6 +1628,7 @@ pub const Value = struct {...@@ -1636,6 +1628,7 @@ pub const Value = struct {
1636 .undef => |ty| Value.fromInterned((try mod.intern(.{1628 .undef => |ty| Value.fromInterned((try mod.intern(.{
1637 .undef = Type.fromInterned(ty).elemType2(mod).toIntern(),1629 .undef = Type.fromInterned(ty).elemType2(mod).toIntern(),
1638 }))),1630 }))),
1631 .slice => |slice| return Value.fromInterned(slice.ptr).maybeElemValue(mod, index),
1639 .ptr => |ptr| switch (ptr.addr) {1632 .ptr => |ptr| switch (ptr.addr) {
1640 .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index),1633 .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index),
1641 .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValue(mod, index),1634 .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValue(mod, index),
...@@ -1800,25 +1793,23 @@ pub const Value = struct {...@@ -1800,25 +1793,23 @@ pub const Value = struct {
1800 ) Allocator.Error!Value {1793 ) Allocator.Error!Value {
1801 const elem_ty = elem_ptr_ty.childType(mod);1794 const elem_ty = elem_ptr_ty.childType(mod);
1802 const ptr_val = switch (mod.intern_pool.indexToKey(val.toIntern())) {1795 const ptr_val = switch (mod.intern_pool.indexToKey(val.toIntern())) {
1803 .ptr => |ptr| ptr: {1796 .slice => |slice| Value.fromInterned(slice.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 },
1820 else => val,1797 else => val,
1821 };1798 };
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 }
1822 var ptr_ty_key = mod.intern_pool.indexToKey(elem_ptr_ty.toIntern()).ptr_type;1813 var ptr_ty_key = mod.intern_pool.indexToKey(elem_ptr_ty.toIntern()).ptr_type;
1823 assert(ptr_ty_key.flags.size != .Slice);1814 assert(ptr_ty_key.flags.size != .Slice);
1824 ptr_ty_key.flags.size = .Many;1815 ptr_ty_key.flags.size = .Many;
...@@ -1850,12 +1841,9 @@ pub const Value = struct {...@@ -1850,12 +1841,9 @@ pub const Value = struct {
1850 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {1841 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
1851 .undef => true,1842 .undef => true,
1852 .simple_value => |v| v == .undefined,1843 .simple_value => |v| v == .undefined,
1853 .ptr => |ptr| switch (ptr.len) {1844 .slice => |slice| for (0..@intCast(Value.fromInterned(slice.len).toUnsignedInt(mod))) |idx| {
1854 .none => false,1845 if (try (try val.elemValue(mod, idx)).anyUndef(mod)) break true;
1855 else => for (0..@as(usize, @intCast(Value.fromInterned(ptr.len).toUnsignedInt(mod)))) |index| {1846 } else false,
1856 if (try (try val.elemValue(mod, index)).anyUndef(mod)) break true;
1857 } else false,
1858 },
1859 .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| {1847 .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| {
1860 const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i];1848 const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i];
1861 if (try anyUndef(Value.fromInterned(elem), mod)) break true;1849 if (try anyUndef(Value.fromInterned(elem), mod)) break true;