authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-18 22:02:55-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:53-07:00
log7bf91fc79ac9e4eae575baf3a2ca9549bc3bf6c2
treef07c76f10c294cdfa7cc302097278ac4ff720c65
parent607737d841bc2279cbe5fee68a0a546b9a5a802e

compiler: eliminate legacy Type.Tag.pointer

Now pointer types are stored only in InternPool.

15 files changed, 295 insertions(+), 673 deletions(-)

src/InternPool.zig+30-25
...@@ -186,17 +186,11 @@ pub const Key = union(enum) {...@@ -186,17 +186,11 @@ pub const Key = union(enum) {
186 pub const PtrType = struct {186 pub const PtrType = struct {
187 elem_type: Index,187 elem_type: Index,
188 sentinel: Index = .none,188 sentinel: Index = .none,
189 /// If zero use pointee_type.abiAlignment()189 /// `none` indicates the ABI alignment of the pointee_type. In this
190 /// When creating pointer types, if alignment is equal to pointee type190 /// case, this field *must* be set to `none`, otherwise the
191 /// abi alignment, this value should be set to 0 instead.191 /// `InternPool` equality and hashing functions will return incorrect
192 ///192 /// results.
193 /// Please don't change this to u32 or u29. If you want to save bits,193 alignment: Alignment = .none,
194 /// migrate the rest of the codebase to use the `Alignment` type rather
195 /// than using byte units. The LLVM backend can only handle `c_uint`
196 /// byte units; we can emit a semantic analysis error if alignment that
197 /// overflows that amount is attempted to be used, but it shouldn't
198 /// affect the other backends.
199 alignment: u64 = 0,
200 /// If this is non-zero it means the pointer points to a sub-byte194 /// If this is non-zero it means the pointer points to a sub-byte
201 /// range of data, which is backed by a "host integer" with this195 /// range of data, which is backed by a "host integer" with this
202 /// number of bytes.196 /// number of bytes.
...@@ -378,15 +372,11 @@ pub const Key = union(enum) {...@@ -378,15 +372,11 @@ pub const Key = union(enum) {
378 /// Tells whether a parameter is noalias. See `paramIsNoalias` helper372 /// Tells whether a parameter is noalias. See `paramIsNoalias` helper
379 /// method for accessing this.373 /// method for accessing this.
380 noalias_bits: u32,374 noalias_bits: u32,
381 /// If zero use default target function code alignment.375 /// `none` indicates the function has the default alignment for
382 ///376 /// function code on the target. In this case, this field *must* be set
383 /// Please don't change this to u32 or u29. If you want to save bits,377 /// to `none`, otherwise the `InternPool` equality and hashing
384 /// migrate the rest of the codebase to use the `Alignment` type rather378 /// functions will return incorrect results.
385 /// than using byte units. The LLVM backend can only handle `c_uint`379 alignment: Alignment,
386 /// byte units; we can emit a semantic analysis error if alignment that
387 /// overflows that amount is attempted to be used, but it shouldn't
388 /// affect the other backends.
389 alignment: u64,
390 cc: std.builtin.CallingConvention,380 cc: std.builtin.CallingConvention,
391 is_var_args: bool,381 is_var_args: bool,
392 is_generic: bool,382 is_generic: bool,
...@@ -1500,6 +1490,13 @@ pub const Alignment = enum(u6) {...@@ -1500,6 +1490,13 @@ pub const Alignment = enum(u6) {
1500 none = std.math.maxInt(u6),1490 none = std.math.maxInt(u6),
1501 _,1491 _,
15021492
1493 pub fn toByteUnitsOptional(a: Alignment) ?u64 {
1494 return switch (a) {
1495 .none => null,
1496 _ => @as(u64, 1) << @enumToInt(a),
1497 };
1498 }
1499
1503 pub fn toByteUnits(a: Alignment, default: u64) u64 {1500 pub fn toByteUnits(a: Alignment, default: u64) u64 {
1504 return switch (a) {1501 return switch (a) {
1505 .none => default,1502 .none => default,
...@@ -1509,8 +1506,14 @@ pub const Alignment = enum(u6) {...@@ -1509,8 +1506,14 @@ pub const Alignment = enum(u6) {
15091506
1510 pub fn fromByteUnits(n: u64) Alignment {1507 pub fn fromByteUnits(n: u64) Alignment {
1511 if (n == 0) return .none;1508 if (n == 0) return .none;
1509 assert(std.math.isPowerOfTwo(n));
1512 return @intToEnum(Alignment, @ctz(n));1510 return @intToEnum(Alignment, @ctz(n));
1513 }1511 }
1512
1513 pub fn fromNonzeroByteUnits(n: u64) Alignment {
1514 assert(n != 0);
1515 return fromByteUnits(n);
1516 }
1514};1517};
15151518
1516/// Used for non-sentineled arrays that have length fitting in u32, as well as1519/// Used for non-sentineled arrays that have length fitting in u32, as well as
...@@ -1773,7 +1776,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -1773,7 +1776,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
1773 return .{ .ptr_type = .{1776 return .{ .ptr_type = .{
1774 .elem_type = ptr_info.child,1777 .elem_type = ptr_info.child,
1775 .sentinel = ptr_info.sentinel,1778 .sentinel = ptr_info.sentinel,
1776 .alignment = ptr_info.flags.alignment.toByteUnits(0),1779 .alignment = ptr_info.flags.alignment,
1777 .size = ptr_info.flags.size,1780 .size = ptr_info.flags.size,
1778 .is_const = ptr_info.flags.is_const,1781 .is_const = ptr_info.flags.is_const,
1779 .is_volatile = ptr_info.flags.is_volatile,1782 .is_volatile = ptr_info.flags.is_volatile,
...@@ -2013,7 +2016,7 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType {...@@ -2013,7 +2016,7 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType {
2013 .return_type = type_function.data.return_type,2016 .return_type = type_function.data.return_type,
2014 .comptime_bits = type_function.data.comptime_bits,2017 .comptime_bits = type_function.data.comptime_bits,
2015 .noalias_bits = type_function.data.noalias_bits,2018 .noalias_bits = type_function.data.noalias_bits,
2016 .alignment = type_function.data.flags.alignment.toByteUnits(0),2019 .alignment = type_function.data.flags.alignment,
2017 .cc = type_function.data.flags.cc,2020 .cc = type_function.data.flags.cc,
2018 .is_var_args = type_function.data.flags.is_var_args,2021 .is_var_args = type_function.data.flags.is_var_args,
2019 .is_generic = type_function.data.flags.is_generic,2022 .is_generic = type_function.data.flags.is_generic,
...@@ -2100,16 +2103,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -2100,16 +2103,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
2100 return @intToEnum(Index, ip.items.len - 1);2103 return @intToEnum(Index, ip.items.len - 1);
2101 }2104 }
21022105
2106 const is_allowzero = ptr_type.is_allowzero or ptr_type.size == .C;
2107
2103 ip.items.appendAssumeCapacity(.{2108 ip.items.appendAssumeCapacity(.{
2104 .tag = .type_pointer,2109 .tag = .type_pointer,
2105 .data = try ip.addExtra(gpa, Pointer{2110 .data = try ip.addExtra(gpa, Pointer{
2106 .child = ptr_type.elem_type,2111 .child = ptr_type.elem_type,
2107 .sentinel = ptr_type.sentinel,2112 .sentinel = ptr_type.sentinel,
2108 .flags = .{2113 .flags = .{
2109 .alignment = Alignment.fromByteUnits(ptr_type.alignment),2114 .alignment = ptr_type.alignment,
2110 .is_const = ptr_type.is_const,2115 .is_const = ptr_type.is_const,
2111 .is_volatile = ptr_type.is_volatile,2116 .is_volatile = ptr_type.is_volatile,
2112 .is_allowzero = ptr_type.is_allowzero,2117 .is_allowzero = is_allowzero,
2113 .size = ptr_type.size,2118 .size = ptr_type.size,
2114 .address_space = ptr_type.address_space,2119 .address_space = ptr_type.address_space,
2115 .vector_index = ptr_type.vector_index,2120 .vector_index = ptr_type.vector_index,
...@@ -2316,7 +2321,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -2316,7 +2321,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
2316 .comptime_bits = func_type.comptime_bits,2321 .comptime_bits = func_type.comptime_bits,
2317 .noalias_bits = func_type.noalias_bits,2322 .noalias_bits = func_type.noalias_bits,
2318 .flags = .{2323 .flags = .{
2319 .alignment = Alignment.fromByteUnits(func_type.alignment),2324 .alignment = func_type.alignment,
2320 .cc = func_type.cc,2325 .cc = func_type.cc,
2321 .is_var_args = func_type.is_var_args,2326 .is_var_args = func_type.is_var_args,
2322 .is_generic = func_type.is_generic,2327 .is_generic = func_type.is_generic,
src/Module.zig+19-17
...@@ -6532,8 +6532,7 @@ pub fn populateTestFunctions(...@@ -6532,8 +6532,7 @@ pub fn populateTestFunctions(
6532 try mod.ensureDeclAnalyzed(decl_index);6532 try mod.ensureDeclAnalyzed(decl_index);
6533 }6533 }
6534 const decl = mod.declPtr(decl_index);6534 const decl = mod.declPtr(decl_index);
6535 var buf: Type.SlicePtrFieldTypeBuffer = undefined;6535 const tmp_test_fn_ty = decl.ty.slicePtrFieldType(mod).childType(mod);
6536 const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf, mod).childType(mod);
65376536
6538 const array_decl_index = d: {6537 const array_decl_index = d: {
6539 // Add mod.test_functions to an array decl then make the test_functions6538 // Add mod.test_functions to an array decl then make the test_functions
...@@ -6843,28 +6842,31 @@ pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type...@@ -6843,28 +6842,31 @@ pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type
6843}6842}
68446843
6845pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {6844pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
6846 if (child_type.ip_index == .none) {
6847 // TODO remove this after all types can be represented via the InternPool
6848 return Type.Tag.pointer.create(mod.tmp_hack_arena.allocator(), .{
6849 .pointee_type = child_type,
6850 .@"addrspace" = .generic,
6851 });
6852 }
6853 return ptrType(mod, .{ .elem_type = child_type.ip_index });6845 return ptrType(mod, .{ .elem_type = child_type.ip_index });
6854}6846}
68556847
6856pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {6848pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
6857 if (child_type.ip_index == .none) {
6858 // TODO remove this after all types can be represented via the InternPool
6859 return Type.Tag.pointer.create(mod.tmp_hack_arena.allocator(), .{
6860 .pointee_type = child_type,
6861 .mutable = false,
6862 .@"addrspace" = .generic,
6863 });
6864 }
6865 return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true });6849 return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true });
6866}6850}
68676851
6852pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
6853 const info = ptr_ty.ptrInfoIp(mod.intern_pool);
6854 return mod.ptrType(.{
6855 .elem_type = new_child.toIntern(),
6856
6857 .sentinel = info.sentinel,
6858 .alignment = info.alignment,
6859 .host_size = info.host_size,
6860 .bit_offset = info.bit_offset,
6861 .vector_index = info.vector_index,
6862 .size = info.size,
6863 .is_const = info.is_const,
6864 .is_volatile = info.is_volatile,
6865 .is_allowzero = info.is_allowzero,
6866 .address_space = info.address_space,
6867 });
6868}
6869
6868pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type {6870pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type {
6869 return (try intern(mod, .{ .func_type = info })).toType();6871 return (try intern(mod, .{ .func_type = info })).toType();
6870}6872}
src/Sema.zig+49-70
...@@ -9163,7 +9163,7 @@ fn funcCommon(...@@ -9163,7 +9163,7 @@ fn funcCommon(
9163 .return_type = return_type.toIntern(),9163 .return_type = return_type.toIntern(),
9164 .cc = cc_resolved,9164 .cc = cc_resolved,
9165 .cc_is_generic = cc == null,9165 .cc_is_generic = cc == null,
9166 .alignment = alignment orelse 0,9166 .alignment = if (alignment) |a| InternPool.Alignment.fromByteUnits(a) else .none,
9167 .align_is_generic = alignment == null,9167 .align_is_generic = alignment == null,
9168 .section_is_generic = section == .generic,9168 .section_is_generic = section == .generic,
9169 .addrspace_is_generic = address_space == null,9169 .addrspace_is_generic = address_space == null,
...@@ -17740,10 +17740,10 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17740,10 +17740,10 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17740 extra_i += 1;17740 extra_i += 1;
17741 const coerced = try sema.coerce(block, elem_ty, try sema.resolveInst(ref), sentinel_src);17741 const coerced = try sema.coerce(block, elem_ty, try sema.resolveInst(ref), sentinel_src);
17742 const val = try sema.resolveConstValue(block, sentinel_src, coerced, "pointer sentinel value must be comptime-known");17742 const val = try sema.resolveConstValue(block, sentinel_src, coerced, "pointer sentinel value must be comptime-known");
17743 break :blk val;17743 break :blk val.toIntern();
17744 } else null;17744 } else .none;
1774517745
17746 const abi_align: u32 = if (inst_data.flags.has_align) blk: {17746 const abi_align: InternPool.Alignment = if (inst_data.flags.has_align) blk: {
17747 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);17747 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
17748 extra_i += 1;17748 extra_i += 1;
17749 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);17749 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);
...@@ -17752,13 +17752,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17752,13 +17752,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17752 // which case we can make this 0 without resolving it.17752 // which case we can make this 0 without resolving it.
17753 if (val.castTag(.lazy_align)) |payload| {17753 if (val.castTag(.lazy_align)) |payload| {
17754 if (payload.data.eql(elem_ty, sema.mod)) {17754 if (payload.data.eql(elem_ty, sema.mod)) {
17755 break :blk 0;17755 break :blk .none;
17756 }17756 }
17757 }17757 }
17758 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);17758 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);
17759 try sema.validateAlign(block, align_src, abi_align);17759 try sema.validateAlign(block, align_src, abi_align);
17760 break :blk abi_align;17760 break :blk InternPool.Alignment.fromByteUnits(abi_align);
17761 } else 0;17761 } else .none;
1776217762
17763 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {17763 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {
17764 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);17764 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
...@@ -17789,7 +17789,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17789,7 +17789,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17789 return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{});17789 return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{});
17790 }17790 }
17791 const fn_align = mod.typeToFunc(elem_ty).?.alignment;17791 const fn_align = mod.typeToFunc(elem_ty).?.alignment;
17792 if (inst_data.flags.has_align and abi_align != 0 and fn_align != 0 and17792 if (inst_data.flags.has_align and abi_align != .none and fn_align != .none and
17793 abi_align != fn_align)17793 abi_align != fn_align)
17794 {17794 {
17795 return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{});17795 return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{});
...@@ -17815,16 +17815,16 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17815,16 +17815,16 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17815 }17815 }
17816 }17816 }
1781717817
17818 const ty = try Type.ptr(sema.arena, sema.mod, .{17818 const ty = try mod.ptrType(.{
17819 .pointee_type = elem_ty,17819 .elem_type = elem_ty.toIntern(),
17820 .sentinel = sentinel,17820 .sentinel = sentinel,
17821 .@"align" = abi_align,17821 .alignment = abi_align,
17822 .@"addrspace" = address_space,17822 .address_space = address_space,
17823 .bit_offset = bit_offset,17823 .bit_offset = bit_offset,
17824 .host_size = host_size,17824 .host_size = host_size,
17825 .mutable = inst_data.flags.is_mutable,17825 .is_const = !inst_data.flags.is_mutable,
17826 .@"allowzero" = inst_data.flags.is_allowzero,17826 .is_allowzero = inst_data.flags.is_allowzero,
17827 .@"volatile" = inst_data.flags.is_volatile,17827 .is_volatile = inst_data.flags.is_volatile,
17828 .size = inst_data.size,17828 .size = inst_data.size,
17829 });17829 });
17830 return sema.addType(ty);17830 return sema.addType(ty);
...@@ -18905,10 +18905,13 @@ fn zirReify(...@@ -18905,10 +18905,13 @@ fn zirReify(
18905 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {18905 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
18906 return sema.fail(block, src, "alignment must fit in 'u32'", .{});18906 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
18907 }18907 }
18908 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?);18908
18909 const abi_align = InternPool.Alignment.fromByteUnits(
18910 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,
18911 );
1890918912
18910 const unresolved_elem_ty = child_val.toType();18913 const unresolved_elem_ty = child_val.toType();
18911 const elem_ty = if (abi_align == 0)18914 const elem_ty = if (abi_align == .none)
18912 unresolved_elem_ty18915 unresolved_elem_ty
18913 else t: {18916 else t: {
18914 const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty);18917 const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty);
...@@ -18918,18 +18921,21 @@ fn zirReify(...@@ -18918,18 +18921,21 @@ fn zirReify(
1891818921
18919 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);18922 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);
1892018923
18921 var actual_sentinel: ?Value = null;18924 const actual_sentinel: InternPool.Index = s: {
18922 if (!sentinel_val.isNull(mod)) {18925 if (!sentinel_val.isNull(mod)) {
18923 if (ptr_size == .One or ptr_size == .C) {18926 if (ptr_size == .One or ptr_size == .C) {
18924 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});18927 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
18928 }
18929 const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;
18930 const ptr_ty = try Type.ptr(sema.arena, mod, .{
18931 .@"addrspace" = .generic,
18932 .pointee_type = try elem_ty.copy(sema.arena),
18933 });
18934 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
18935 break :s sent_val.toIntern();
18925 }18936 }
18926 const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;18937 break :s .none;
18927 const ptr_ty = try Type.ptr(sema.arena, mod, .{18938 };
18928 .@"addrspace" = .generic,
18929 .pointee_type = try elem_ty.copy(sema.arena),
18930 });
18931 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
18932 }
1893318939
18934 if (elem_ty.zigTypeTag(mod) == .NoReturn) {18940 if (elem_ty.zigTypeTag(mod) == .NoReturn) {
18935 return sema.fail(block, src, "pointer to noreturn not allowed", .{});18941 return sema.fail(block, src, "pointer to noreturn not allowed", .{});
...@@ -18938,7 +18944,7 @@ fn zirReify(...@@ -18938,7 +18944,7 @@ fn zirReify(
18938 return sema.fail(block, src, "function pointers must be single pointers", .{});18944 return sema.fail(block, src, "function pointers must be single pointers", .{});
18939 }18945 }
18940 const fn_align = mod.typeToFunc(elem_ty).?.alignment;18946 const fn_align = mod.typeToFunc(elem_ty).?.alignment;
18941 if (abi_align != 0 and fn_align != 0 and18947 if (abi_align != .none and fn_align != .none and
18942 abi_align != fn_align)18948 abi_align != fn_align)
18943 {18949 {
18944 return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{});18950 return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{});
...@@ -18964,14 +18970,14 @@ fn zirReify(...@@ -18964,14 +18970,14 @@ fn zirReify(
18964 }18970 }
18965 }18971 }
1896618972
18967 const ty = try Type.ptr(sema.arena, mod, .{18973 const ty = try mod.ptrType(.{
18968 .size = ptr_size,18974 .size = ptr_size,
18969 .mutable = !is_const_val.toBool(mod),18975 .is_const = is_const_val.toBool(mod),
18970 .@"volatile" = is_volatile_val.toBool(mod),18976 .is_volatile = is_volatile_val.toBool(mod),
18971 .@"align" = abi_align,18977 .alignment = abi_align,
18972 .@"addrspace" = mod.toEnum(std.builtin.AddressSpace, address_space_val),18978 .address_space = mod.toEnum(std.builtin.AddressSpace, address_space_val),
18973 .pointee_type = try elem_ty.copy(sema.arena),18979 .elem_type = elem_ty.toIntern(),
18974 .@"allowzero" = is_allowzero_val.toBool(mod),18980 .is_allowzero = is_allowzero_val.toBool(mod),
18975 .sentinel = actual_sentinel,18981 .sentinel = actual_sentinel,
18976 });18982 });
18977 return sema.addType(ty);18983 return sema.addType(ty);
...@@ -19470,9 +19476,9 @@ fn zirReify(...@@ -19470,9 +19476,9 @@ fn zirReify(
19470 }19476 }
19471 const alignment = @intCast(u29, alignment_val.toUnsignedInt(mod));19477 const alignment = @intCast(u29, alignment_val.toUnsignedInt(mod));
19472 if (alignment == target_util.defaultFunctionAlignment(target)) {19478 if (alignment == target_util.defaultFunctionAlignment(target)) {
19473 break :alignment 0;19479 break :alignment .none;
19474 } else {19480 } else {
19475 break :alignment alignment;19481 break :alignment InternPool.Alignment.fromByteUnits(alignment);
19476 }19482 }
19477 };19483 };
19478 const return_type = return_type_val.optionalValue(mod) orelse19484 const return_type = return_type_val.optionalValue(mod) orelse
...@@ -24291,8 +24297,7 @@ fn fieldPtr(...@@ -24291,8 +24297,7 @@ fn fieldPtr(
24291 const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty;24297 const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty;
2429224298
24293 if (mem.eql(u8, field_name, "ptr")) {24299 if (mem.eql(u8, field_name, "ptr")) {
24294 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);24300 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
24295 const slice_ptr_ty = inner_ty.slicePtrFieldType(buf, mod);
2429624301
24297 const result_ty = try Type.ptr(sema.arena, mod, .{24302 const result_ty = try Type.ptr(sema.arena, mod, .{
24298 .pointee_type = slice_ptr_ty,24303 .pointee_type = slice_ptr_ty,
...@@ -27914,7 +27919,7 @@ fn beginComptimePtrMutation(...@@ -27914,7 +27919,7 @@ fn beginComptimePtrMutation(
27914 sema,27919 sema,
27915 block,27920 block,
27916 src,27921 src,
27917 parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),27922 parent.ty.slicePtrFieldType(mod),
27918 &val_ptr.castTag(.slice).?.data.ptr,27923 &val_ptr.castTag(.slice).?.data.ptr,
27919 ptr_elem_ty,27924 ptr_elem_ty,
27920 parent.decl_ref_mut,27925 parent.decl_ref_mut,
...@@ -27981,7 +27986,7 @@ fn beginComptimePtrMutation(...@@ -27981,7 +27986,7 @@ fn beginComptimePtrMutation(
27981 sema,27986 sema,
27982 block,27987 block,
27983 src,27988 src,
27984 parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),27989 parent.ty.slicePtrFieldType(mod),
27985 &val_ptr.castTag(.slice).?.data.ptr,27990 &val_ptr.castTag(.slice).?.data.ptr,
27986 ptr_elem_ty,27991 ptr_elem_ty,
27987 parent.decl_ref_mut,27992 parent.decl_ref_mut,
...@@ -28363,7 +28368,7 @@ fn beginComptimePtrLoad(...@@ -28363,7 +28368,7 @@ fn beginComptimePtrLoad(
28363 const slice_val = tv.val.castTag(.slice).?.data;28368 const slice_val = tv.val.castTag(.slice).?.data;
28364 deref.pointee = switch (field_index) {28369 deref.pointee = switch (field_index) {
28365 Value.Payload.Slice.ptr_index => TypedValue{28370 Value.Payload.Slice.ptr_index => TypedValue{
28366 .ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),28371 .ty = field_ptr.container_ty.slicePtrFieldType(mod),
28367 .val = slice_val.ptr,28372 .val = slice_val.ptr,
28368 },28373 },
28369 Value.Payload.Slice.len_index => TypedValue{28374 Value.Payload.Slice.len_index => TypedValue{
...@@ -29454,8 +29459,7 @@ fn analyzeSlicePtr(...@@ -29454,8 +29459,7 @@ fn analyzeSlicePtr(
29454 slice_ty: Type,29459 slice_ty: Type,
29455) CompileError!Air.Inst.Ref {29460) CompileError!Air.Inst.Ref {
29456 const mod = sema.mod;29461 const mod = sema.mod;
29457 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);29462 const result_ty = slice_ty.slicePtrFieldType(mod);
29458 const result_ty = slice_ty.slicePtrFieldType(buf, mod);
29459 if (try sema.resolveMaybeUndefVal(slice)) |val| {29463 if (try sema.resolveMaybeUndefVal(slice)) |val| {
29460 if (val.isUndef(mod)) return sema.addConstUndef(result_ty);29464 if (val.isUndef(mod)) return sema.addConstUndef(result_ty);
29461 return sema.addConstant(result_ty, val.slicePtr());29465 return sema.addConstant(result_ty, val.slicePtr());
...@@ -31611,15 +31615,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31611,15 +31615,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31611 .inferred_alloc_mut => unreachable,31615 .inferred_alloc_mut => unreachable,
31612 .inferred_alloc_const => unreachable,31616 .inferred_alloc_const => unreachable,
3161331617
31614 .pointer => {
31615 const child_ty = ty.childType(mod);
31616 if (child_ty.zigTypeTag(mod) == .Fn) {
31617 return mod.typeToFunc(child_ty).?.is_generic;
31618 } else {
31619 return sema.resolveTypeRequiresComptime(child_ty);
31620 }
31621 },
31622
31623 .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),31618 .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),
31624 },31619 },
31625 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {31620 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
...@@ -33048,7 +33043,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33048,7 +33043,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33048 .error_set_merged,33043 .error_set_merged,
33049 .error_union,33044 .error_union,
33050 .error_set_inferred,33045 .error_set_inferred,
33051 .pointer,
33052 => return null,33046 => return null,
3305333047
33054 .inferred_alloc_const => unreachable,33048 .inferred_alloc_const => unreachable,
...@@ -33604,12 +33598,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {...@@ -33604,12 +33598,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
33604 };33598 };
3360533599
33606 switch (ty.tag()) {33600 switch (ty.tag()) {
33607 .pointer => switch (ty.ptrSize(mod)) {
33608 .Slice => return null,
33609 .C => return ty.optionalChild(mod),
33610 else => return ty,
33611 },
33612
33613 .inferred_alloc_const => unreachable,33601 .inferred_alloc_const => unreachable,
33614 .inferred_alloc_mut => unreachable,33602 .inferred_alloc_mut => unreachable,
3361533603
...@@ -33638,15 +33626,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33638,15 +33626,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33638 .inferred_alloc_mut => unreachable,33626 .inferred_alloc_mut => unreachable,
33639 .inferred_alloc_const => unreachable,33627 .inferred_alloc_const => unreachable,
3364033628
33641 .pointer => {
33642 const child_ty = ty.childType(mod);
33643 if (child_ty.zigTypeTag(mod) == .Fn) {
33644 return mod.typeToFunc(child_ty).?.is_generic;
33645 } else {
33646 return sema.typeRequiresComptime(child_ty);
33647 }
33648 },
33649
33650 .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()),33629 .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()),
33651 },33630 },
33652 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {33631 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
src/arch/aarch64/CodeGen.zig+1-2
...@@ -3434,8 +3434,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -3434,8 +3434,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
3434 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3434 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3435 const slice_ty = self.typeOf(bin_op.lhs);3435 const slice_ty = self.typeOf(bin_op.lhs);
3436 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {3436 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
3437 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3437 const ptr_ty = slice_ty.slicePtrFieldType(mod);
3438 const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod);
34393438
3440 const slice_mcv = try self.resolveInst(bin_op.lhs);3439 const slice_mcv = try self.resolveInst(bin_op.lhs);
3441 const base_mcv = slicePtr(slice_mcv);3440 const base_mcv = slicePtr(slice_mcv);
src/arch/arm/CodeGen.zig+1-2
...@@ -2432,8 +2432,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2432,8 +2432,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2432 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2432 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2433 const slice_ty = self.typeOf(bin_op.lhs);2433 const slice_ty = self.typeOf(bin_op.lhs);
2434 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {2434 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
2435 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2435 const ptr_ty = slice_ty.slicePtrFieldType(mod);
2436 const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod);
24372436
2438 const slice_mcv = try self.resolveInst(bin_op.lhs);2437 const slice_mcv = try self.resolveInst(bin_op.lhs);
2439 const base_mcv = slicePtr(slice_mcv);2438 const base_mcv = slicePtr(slice_mcv);
src/arch/sparc64/CodeGen.zig+1-2
...@@ -2462,8 +2462,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2462,8 +2462,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2462 const elem_ty = slice_ty.childType(mod);2462 const elem_ty = slice_ty.childType(mod);
2463 const elem_size = elem_ty.abiSize(mod);2463 const elem_size = elem_ty.abiSize(mod);
24642464
2465 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2465 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);
2466 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
24672466
2468 const index_lock: ?RegisterLock = if (index_mcv == .register)2467 const index_lock: ?RegisterLock = if (index_mcv == .register)
2469 self.register_manager.lockRegAssumeUnused(index_mcv.register)2468 self.register_manager.lockRegAssumeUnused(index_mcv.register)
src/arch/x86_64/CodeGen.zig+6-15
...@@ -4052,8 +4052,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -4052,8 +4052,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
40524052
4053 const elem_ty = slice_ty.childType(mod);4053 const elem_ty = slice_ty.childType(mod);
4054 const elem_size = elem_ty.abiSize(mod);4054 const elem_size = elem_ty.abiSize(mod);
4055 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4055 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);
4056 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
40574056
4058 const index_ty = self.typeOf(rhs);4057 const index_ty = self.typeOf(rhs);
4059 const index_mcv = try self.resolveInst(rhs);4058 const index_mcv = try self.resolveInst(rhs);
...@@ -4082,8 +4081,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4082,8 +4081,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
4082 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4081 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4083 const slice_ty = self.typeOf(bin_op.lhs);4082 const slice_ty = self.typeOf(bin_op.lhs);
40844083
4085 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4084 const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod);
4086 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
4087 const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs);4085 const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs);
4088 const dst_mcv = try self.allocRegOrMem(inst, false);4086 const dst_mcv = try self.allocRegOrMem(inst, false);
4089 try self.load(dst_mcv, slice_ptr_field_type, elem_ptr);4087 try self.load(dst_mcv, slice_ptr_field_type, elem_ptr);
...@@ -4281,11 +4279,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -4281,11 +4279,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4281 break :blk MCValue{ .register = reg };4279 break :blk MCValue{ .register = reg };
4282 } else ptr;4280 } else ptr;
42834281
4284 var ptr_tag_pl: Type.Payload.Pointer = .{4282 const ptr_tag_ty = try mod.adjustPtrTypeChild(ptr_union_ty, tag_ty);
4285 .data = ptr_union_ty.ptrInfo(mod),
4286 };
4287 ptr_tag_pl.data.pointee_type = tag_ty;
4288 const ptr_tag_ty = Type.initPayload(&ptr_tag_pl.base);
4289 try self.store(ptr_tag_ty, adjusted_ptr, tag);4283 try self.store(ptr_tag_ty, adjusted_ptr, tag);
42904284
4291 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });4285 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });
...@@ -8671,9 +8665,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -8671,9 +8665,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86718665
8672 const pl_ty = opt_ty.optionalChild(mod);8666 const pl_ty = opt_ty.optionalChild(mod);
86738667
8674 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
8675 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))8668 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
8676 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty }8669 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }
8677 else8670 else
8678 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };8671 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
86798672
...@@ -8763,9 +8756,8 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -8763,9 +8756,8 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
8763 const opt_ty = ptr_ty.childType(mod);8756 const opt_ty = ptr_ty.childType(mod);
8764 const pl_ty = opt_ty.optionalChild(mod);8757 const pl_ty = opt_ty.optionalChild(mod);
87658758
8766 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
8767 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))8759 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
8768 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty }8760 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }
8769 else8761 else
8770 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };8762 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
87718763
...@@ -10803,8 +10795,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -10803,8 +10795,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
10803 // here to elide it.10795 // here to elide it.
10804 switch (dst_ptr_ty.ptrSize(mod)) {10796 switch (dst_ptr_ty.ptrSize(mod)) {
10805 .Slice => {10797 .Slice => {
10806 var buf: Type.SlicePtrFieldTypeBuffer = undefined;10798 const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(mod);
10807 const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf, mod);
1080810799
10809 // TODO: this only handles slices stored in the stack10800 // TODO: this only handles slices stored in the stack
10810 const ptr = dst_ptr;10801 const ptr = dst_ptr;
src/codegen.zig+3-6
...@@ -347,8 +347,7 @@ pub fn generateSymbol(...@@ -347,8 +347,7 @@ pub fn generateSymbol(
347 const slice = typed_value.val.castTag(.slice).?.data;347 const slice = typed_value.val.castTag(.slice).?.data;
348348
349 // generate ptr349 // generate ptr
350 var buf: Type.SlicePtrFieldTypeBuffer = undefined;350 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(mod);
351 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod);
352 switch (try generateSymbol(bin_file, src_loc, .{351 switch (try generateSymbol(bin_file, src_loc, .{
353 .ty = slice_ptr_field_type,352 .ty = slice_ptr_field_type,
354 .val = slice.ptr,353 .val = slice.ptr,
...@@ -850,10 +849,9 @@ fn lowerParentPtr(...@@ -850,10 +849,9 @@ fn lowerParentPtr(
850 reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag(mod)) {849 reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag(mod)) {
851 .Pointer => offset: {850 .Pointer => offset: {
852 assert(field_ptr.container_ty.isSlice(mod));851 assert(field_ptr.container_ty.isSlice(mod));
853 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
854 break :offset switch (field_ptr.field_index) {852 break :offset switch (field_ptr.field_index) {
855 0 => 0,853 0 => 0,
856 1 => field_ptr.container_ty.slicePtrFieldType(&buf, mod).abiSize(mod),854 1 => field_ptr.container_ty.slicePtrFieldType(mod).abiSize(mod),
857 else => unreachable,855 else => unreachable,
858 };856 };
859 },857 },
...@@ -952,8 +950,7 @@ fn lowerDeclRef(...@@ -952,8 +950,7 @@ fn lowerDeclRef(
952 const mod = bin_file.options.module.?;950 const mod = bin_file.options.module.?;
953 if (typed_value.ty.isSlice(mod)) {951 if (typed_value.ty.isSlice(mod)) {
954 // generate ptr952 // generate ptr
955 var buf: Type.SlicePtrFieldTypeBuffer = undefined;953 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(mod);
956 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod);
957 switch (try generateSymbol(bin_file, src_loc, .{954 switch (try generateSymbol(bin_file, src_loc, .{
958 .ty = slice_ptr_field_type,955 .ty = slice_ptr_field_type,
959 .val = typed_value.val,956 .val = typed_value.val,
src/codegen/c.zig+15-41
...@@ -566,8 +566,7 @@ pub const DeclGen = struct {...@@ -566,8 +566,7 @@ pub const DeclGen = struct {
566 try writer.writeAll("){ .ptr = ");566 try writer.writeAll("){ .ptr = ");
567 }567 }
568568
569 var buf: Type.SlicePtrFieldTypeBuffer = undefined;569 try dg.renderValue(writer, ty.slicePtrFieldType(mod), val.slicePtr(), .Initializer);
570 try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), val.slicePtr(), .Initializer);
571570
572 const len_val = try mod.intValue(Type.usize, val.sliceLen(mod));571 const len_val = try mod.intValue(Type.usize, val.sliceLen(mod));
573572
...@@ -631,11 +630,7 @@ pub const DeclGen = struct {...@@ -631,11 +630,7 @@ pub const DeclGen = struct {
631 // Ensure complete type definition is visible before accessing fields.630 // Ensure complete type definition is visible before accessing fields.
632 _ = try dg.typeToIndex(field_ptr.container_ty, .complete);631 _ = try dg.typeToIndex(field_ptr.container_ty, .complete);
633632
634 var container_ptr_pl: Type.Payload.Pointer = .{633 const container_ptr_ty = try mod.adjustPtrTypeChild(ptr_ty, field_ptr.container_ty);
635 .data = ptr_ty.ptrInfo(mod),
636 };
637 container_ptr_pl.data.pointee_type = field_ptr.container_ty;
638 const container_ptr_ty = Type.initPayload(&container_ptr_pl.base);
639634
640 switch (fieldLocation(635 switch (fieldLocation(
641 field_ptr.container_ty,636 field_ptr.container_ty,
...@@ -661,11 +656,7 @@ pub const DeclGen = struct {...@@ -661,11 +656,7 @@ pub const DeclGen = struct {
661 try dg.writeCValue(writer, field);656 try dg.writeCValue(writer, field);
662 },657 },
663 .byte_offset => |byte_offset| {658 .byte_offset => |byte_offset| {
664 var u8_ptr_pl: Type.Payload.Pointer = .{659 const u8_ptr_ty = try mod.adjustPtrTypeChild(ptr_ty, Type.u8);
665 .data = ptr_ty.ptrInfo(mod),
666 };
667 u8_ptr_pl.data.pointee_type = Type.u8;
668 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
669660
670 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);661 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
671662
...@@ -788,8 +779,7 @@ pub const DeclGen = struct {...@@ -788,8 +779,7 @@ pub const DeclGen = struct {
788 }779 }
789780
790 try writer.writeAll("{(");781 try writer.writeAll("{(");
791 var buf: Type.SlicePtrFieldTypeBuffer = undefined;782 const ptr_ty = ty.slicePtrFieldType(mod);
792 const ptr_ty = ty.slicePtrFieldType(&buf, mod);
793 try dg.renderType(writer, ptr_ty);783 try dg.renderType(writer, ptr_ty);
794 return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});784 return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
795 } else {785 } else {
...@@ -1068,10 +1058,9 @@ pub const DeclGen = struct {...@@ -1068,10 +1058,9 @@ pub const DeclGen = struct {
1068 }1058 }
10691059
1070 const slice = val.castTag(.slice).?.data;1060 const slice = val.castTag(.slice).?.data;
1071 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
10721061
1073 try writer.writeByte('{');1062 try writer.writeByte('{');
1074 try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), slice.ptr, initializer_type);1063 try dg.renderValue(writer, ty.slicePtrFieldType(mod), slice.ptr, initializer_type);
1075 try writer.writeAll(", ");1064 try writer.writeAll(", ");
1076 try dg.renderValue(writer, Type.usize, slice.len, initializer_type);1065 try dg.renderValue(writer, Type.usize, slice.len, initializer_type);
1077 try writer.writeByte('}');1066 try writer.writeByte('}');
...@@ -1536,8 +1525,8 @@ pub const DeclGen = struct {...@@ -1536,8 +1525,8 @@ pub const DeclGen = struct {
15361525
1537 switch (kind) {1526 switch (kind) {
1538 .forward => {},1527 .forward => {},
1539 .complete => if (fn_info.alignment > 0)1528 .complete => if (fn_info.alignment.toByteUnitsOptional()) |a|
1540 try w.print(" zig_align_fn({})", .{fn_info.alignment}),1529 try w.print(" zig_align_fn({})", .{a}),
1541 else => unreachable,1530 else => unreachable,
1542 }1531 }
15431532
...@@ -1561,8 +1550,8 @@ pub const DeclGen = struct {...@@ -1561,8 +1550,8 @@ pub const DeclGen = struct {
1561 );1550 );
15621551
1563 switch (kind) {1552 switch (kind) {
1564 .forward => if (fn_info.alignment > 0)1553 .forward => if (fn_info.alignment.toByteUnitsOptional()) |a|
1565 try w.print(" zig_align_fn({})", .{fn_info.alignment}),1554 try w.print(" zig_align_fn({})", .{a}),
1566 .complete => {},1555 .complete => {},
1567 else => unreachable,1556 else => unreachable,
1568 }1557 }
...@@ -4062,8 +4051,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4062,8 +4051,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4062 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4051 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
40634052
4064 const inst_ty = f.typeOfIndex(inst);4053 const inst_ty = f.typeOfIndex(inst);
4065 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4054 const ptr_ty = inst_ty.slicePtrFieldType(mod);
4066 const ptr_ty = inst_ty.slicePtrFieldType(&buf, mod);
40674055
4068 const writer = f.object.writer();4056 const writer = f.object.writer();
4069 const local = try f.allocLocal(inst, inst_ty);4057 const local = try f.allocLocal(inst, inst_ty);
...@@ -5047,7 +5035,6 @@ fn airIsNull(...@@ -5047,7 +5035,6 @@ fn airIsNull(
5047 const operand_ty = f.typeOf(un_op);5035 const operand_ty = f.typeOf(un_op);
5048 const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;5036 const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
5049 const payload_ty = optional_ty.optionalChild(mod);5037 const payload_ty = optional_ty.optionalChild(mod);
5050 var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
50515038
5052 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))5039 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
5053 TypedValue{ .ty = Type.bool, .val = Value.true }5040 TypedValue{ .ty = Type.bool, .val = Value.true }
...@@ -5058,7 +5045,7 @@ fn airIsNull(...@@ -5058,7 +5045,7 @@ fn airIsNull(
5058 TypedValue{ .ty = payload_ty, .val = try mod.intValue(payload_ty, 0) }5045 TypedValue{ .ty = payload_ty, .val = try mod.intValue(payload_ty, 0) }
5059 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {5046 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
5060 try writer.writeAll(".ptr");5047 try writer.writeAll(".ptr");
5061 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod);5048 const slice_ptr_ty = payload_ty.slicePtrFieldType(mod);
5062 break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };5049 break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };
5063 } else rhs: {5050 } else rhs: {
5064 try writer.writeAll(".is_null");5051 try writer.writeAll(".is_null");
...@@ -5278,11 +5265,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5278,11 +5265,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5278 switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, mod)) {5265 switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, mod)) {
5279 .begin => try f.writeCValue(writer, field_ptr_val, .Initializer),5266 .begin => try f.writeCValue(writer, field_ptr_val, .Initializer),
5280 .field => |field| {5267 .field => |field| {
5281 var u8_ptr_pl: Type.Payload.Pointer = .{5268 const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8);
5282 .data = field_ptr_ty.ptrInfo(mod),
5283 };
5284 u8_ptr_pl.data.pointee_type = Type.u8;
5285 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
52865269
5287 try writer.writeAll("((");5270 try writer.writeAll("((");
5288 try f.renderType(writer, u8_ptr_ty);5271 try f.renderType(writer, u8_ptr_ty);
...@@ -5295,11 +5278,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5295,11 +5278,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5295 try writer.writeAll("))");5278 try writer.writeAll("))");
5296 },5279 },
5297 .byte_offset => |byte_offset| {5280 .byte_offset => |byte_offset| {
5298 var u8_ptr_pl: Type.Payload.Pointer = .{5281 const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8);
5299 .data = field_ptr_ty.ptrInfo(mod),
5300 };
5301 u8_ptr_pl.data.pointee_type = Type.u8;
5302 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
53035282
5304 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);5283 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
53055284
...@@ -5347,11 +5326,7 @@ fn fieldPtr(...@@ -5347,11 +5326,7 @@ fn fieldPtr(
5347 try f.writeCValueDerefMember(writer, container_ptr_val, field);5326 try f.writeCValueDerefMember(writer, container_ptr_val, field);
5348 },5327 },
5349 .byte_offset => |byte_offset| {5328 .byte_offset => |byte_offset| {
5350 var u8_ptr_pl: Type.Payload.Pointer = .{5329 const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8);
5351 .data = field_ptr_ty.ptrInfo(mod),
5352 };
5353 u8_ptr_pl.data.pointee_type = Type.u8;
5354 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
53555330
5356 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);5331 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
53575332
...@@ -5794,8 +5769,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5794,8 +5769,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
5794 // Unfortunately, C does not support any equivalent to5769 // Unfortunately, C does not support any equivalent to
5795 // &(*(void *)p)[0], although LLVM does via GetElementPtr5770 // &(*(void *)p)[0], although LLVM does via GetElementPtr
5796 if (operand == .undef) {5771 if (operand == .undef) {
5797 var buf: Type.SlicePtrFieldTypeBuffer = undefined;5772 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(mod) }, .Initializer);
5798 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf, mod) }, .Initializer);
5799 } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {5773 } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5800 try writer.writeAll("&(");5774 try writer.writeAll("&(");
5801 try f.writeCValueDeref(writer, operand);5775 try f.writeCValueDeref(writer, operand);
src/codegen/c/type.zig+1-2
...@@ -1431,8 +1431,7 @@ pub const CType = extern union {...@@ -1431,8 +1431,7 @@ pub const CType = extern union {
1431 .complete, .parameter, .global => try lookup.typeToIndex(ty, .forward),1431 .complete, .parameter, .global => try lookup.typeToIndex(ty, .forward),
1432 .payload => unreachable,1432 .payload => unreachable,
1433 }) |fwd_idx| {1433 }) |fwd_idx| {
1434 var buf: Type.SlicePtrFieldTypeBuffer = undefined;1434 const ptr_ty = ty.slicePtrFieldType(mod);
1435 const ptr_ty = ty.slicePtrFieldType(&buf, mod);
1436 if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| {1435 if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| {
1437 self.storage = .{ .anon = undefined };1436 self.storage = .{ .anon = undefined };
1438 self.storage.anon.fields[0] = .{1437 self.storage.anon.fields[0] = .{
src/codegen/llvm.zig+45-74
...@@ -1591,40 +1591,30 @@ pub const Object = struct {...@@ -1591,40 +1591,30 @@ pub const Object = struct {
1591 },1591 },
1592 .Pointer => {1592 .Pointer => {
1593 // Normalize everything that the debug info does not represent.1593 // Normalize everything that the debug info does not represent.
1594 const ptr_info = ty.ptrInfo(mod);1594 const ptr_info = ty.ptrInfoIp(mod.intern_pool);
15951595
1596 if (ptr_info.sentinel != null or1596 if (ptr_info.sentinel != .none or
1597 ptr_info.@"addrspace" != .generic or1597 ptr_info.address_space != .generic or
1598 ptr_info.bit_offset != 0 or1598 ptr_info.bit_offset != 0 or
1599 ptr_info.host_size != 0 or1599 ptr_info.host_size != 0 or
1600 ptr_info.vector_index != .none or1600 ptr_info.vector_index != .none or
1601 ptr_info.@"allowzero" or1601 ptr_info.is_allowzero or
1602 !ptr_info.mutable or1602 ptr_info.is_const or
1603 ptr_info.@"volatile" or1603 ptr_info.is_volatile or
1604 ptr_info.size == .Many or ptr_info.size == .C or1604 ptr_info.size == .Many or ptr_info.size == .C or
1605 !ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime(mod))1605 !ptr_info.elem_type.toType().hasRuntimeBitsIgnoreComptime(mod))
1606 {1606 {
1607 var payload: Type.Payload.Pointer = .{1607 const bland_ptr_ty = try mod.ptrType(.{
1608 .data = .{1608 .elem_type = if (!ptr_info.elem_type.toType().hasRuntimeBitsIgnoreComptime(mod))
1609 .pointee_type = ptr_info.pointee_type,1609 .anyopaque_type
1610 .sentinel = null,1610 else
1611 .@"align" = ptr_info.@"align",1611 ptr_info.elem_type,
1612 .@"addrspace" = .generic,1612 .alignment = ptr_info.alignment,
1613 .bit_offset = 0,1613 .size = switch (ptr_info.size) {
1614 .host_size = 0,1614 .Many, .C, .One => .One,
1615 .@"allowzero" = false,1615 .Slice => .Slice,
1616 .mutable = true,
1617 .@"volatile" = false,
1618 .size = switch (ptr_info.size) {
1619 .Many, .C, .One => .One,
1620 .Slice => .Slice,
1621 },
1622 },1616 },
1623 };1617 });
1624 if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) {
1625 payload.data.pointee_type = Type.anyopaque;
1626 }
1627 const bland_ptr_ty = Type.initPayload(&payload.base);
1628 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);1618 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);
1629 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1619 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1630 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module });1620 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module });
...@@ -1632,8 +1622,7 @@ pub const Object = struct {...@@ -1632,8 +1622,7 @@ pub const Object = struct {
1632 }1622 }
16331623
1634 if (ty.isSlice(mod)) {1624 if (ty.isSlice(mod)) {
1635 var buf: Type.SlicePtrFieldTypeBuffer = undefined;1625 const ptr_ty = ty.slicePtrFieldType(mod);
1636 const ptr_ty = ty.slicePtrFieldType(&buf, mod);
1637 const len_ty = Type.usize;1626 const len_ty = Type.usize;
16381627
1639 const name = try ty.nameAlloc(gpa, o.module);1628 const name = try ty.nameAlloc(gpa, o.module);
...@@ -1711,7 +1700,7 @@ pub const Object = struct {...@@ -1711,7 +1700,7 @@ pub const Object = struct {
1711 return full_di_ty;1700 return full_di_ty;
1712 }1701 }
17131702
1714 const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd);1703 const elem_di_ty = try o.lowerDebugType(ptr_info.elem_type.toType(), .fwd);
1715 const name = try ty.nameAlloc(gpa, o.module);1704 const name = try ty.nameAlloc(gpa, o.module);
1716 defer gpa.free(name);1705 defer gpa.free(name);
1717 const ptr_di_ty = dib.createPointerType(1706 const ptr_di_ty = dib.createPointerType(
...@@ -2625,8 +2614,8 @@ pub const DeclGen = struct {...@@ -2625,8 +2614,8 @@ pub const DeclGen = struct {
2625 },2614 },
2626 }2615 }
26272616
2628 if (fn_info.alignment != 0) {2617 if (fn_info.alignment.toByteUnitsOptional()) |a| {
2629 llvm_fn.setAlignment(@intCast(c_uint, fn_info.alignment));2618 llvm_fn.setAlignment(@intCast(c_uint, a));
2630 }2619 }
26312620
2632 // Function attributes that are independent of analysis results of the function body.2621 // Function attributes that are independent of analysis results of the function body.
...@@ -2819,8 +2808,7 @@ pub const DeclGen = struct {...@@ -2819,8 +2808,7 @@ pub const DeclGen = struct {
2819 .Bool => return dg.context.intType(1),2808 .Bool => return dg.context.intType(1),
2820 .Pointer => {2809 .Pointer => {
2821 if (t.isSlice(mod)) {2810 if (t.isSlice(mod)) {
2822 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2811 const ptr_type = t.slicePtrFieldType(mod);
2823 const ptr_type = t.slicePtrFieldType(&buf, mod);
28242812
2825 const fields: [2]*llvm.Type = .{2813 const fields: [2]*llvm.Type = .{
2826 try dg.lowerType(ptr_type),2814 try dg.lowerType(ptr_type),
...@@ -3176,11 +3164,10 @@ pub const DeclGen = struct {...@@ -3176,11 +3164,10 @@ pub const DeclGen = struct {
3176 },3164 },
3177 .slice => {3165 .slice => {
3178 const param_ty = fn_info.param_types[it.zig_index - 1].toType();3166 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
3179 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3180 const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional)3167 const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional)
3181 param_ty.optionalChild(mod).slicePtrFieldType(&buf, mod)3168 param_ty.optionalChild(mod).slicePtrFieldType(mod)
3182 else3169 else
3183 param_ty.slicePtrFieldType(&buf, mod);3170 param_ty.slicePtrFieldType(mod);
3184 const ptr_llvm_ty = try dg.lowerType(ptr_ty);3171 const ptr_llvm_ty = try dg.lowerType(ptr_ty);
3185 const len_llvm_ty = try dg.lowerType(Type.usize);3172 const len_llvm_ty = try dg.lowerType(Type.usize);
31863173
...@@ -3368,10 +3355,9 @@ pub const DeclGen = struct {...@@ -3368,10 +3355,9 @@ pub const DeclGen = struct {
3368 },3355 },
3369 .slice => {3356 .slice => {
3370 const slice = tv.val.castTag(.slice).?.data;3357 const slice = tv.val.castTag(.slice).?.data;
3371 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3372 const fields: [2]*llvm.Value = .{3358 const fields: [2]*llvm.Value = .{
3373 try dg.lowerValue(.{3359 try dg.lowerValue(.{
3374 .ty = tv.ty.slicePtrFieldType(&buf, mod),3360 .ty = tv.ty.slicePtrFieldType(mod),
3375 .val = slice.ptr,3361 .val = slice.ptr,
3376 }),3362 }),
3377 try dg.lowerValue(.{3363 try dg.lowerValue(.{
...@@ -4171,8 +4157,7 @@ pub const DeclGen = struct {...@@ -4171,8 +4157,7 @@ pub const DeclGen = struct {
4171 ) Error!*llvm.Value {4157 ) Error!*llvm.Value {
4172 const mod = self.module;4158 const mod = self.module;
4173 if (tv.ty.isSlice(mod)) {4159 if (tv.ty.isSlice(mod)) {
4174 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4160 const ptr_ty = tv.ty.slicePtrFieldType(mod);
4175 const ptr_ty = tv.ty.slicePtrFieldType(&buf, mod);
4176 const fields: [2]*llvm.Value = .{4161 const fields: [2]*llvm.Value = .{
4177 try self.lowerValue(.{4162 try self.lowerValue(.{
4178 .ty = ptr_ty,4163 .ty = ptr_ty,
...@@ -6043,17 +6028,14 @@ pub const FuncGen = struct {...@@ -6043,17 +6028,14 @@ pub const FuncGen = struct {
6043 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, "");6028 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, "");
6044 const field_ptr_ty = try mod.ptrType(.{6029 const field_ptr_ty = try mod.ptrType(.{
6045 .elem_type = llvm_field.ty.ip_index,6030 .elem_type = llvm_field.ty.ip_index,
6046 .alignment = llvm_field.alignment,6031 .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment),
6047 });6032 });
6048 if (isByRef(field_ty, mod)) {6033 if (isByRef(field_ty, mod)) {
6049 if (canElideLoad(self, body_tail))6034 if (canElideLoad(self, body_tail))
6050 return field_ptr;6035 return field_ptr;
60516036
6052 const field_alignment = if (llvm_field.alignment != 0)6037 assert(llvm_field.alignment != 0);
6053 llvm_field.alignment6038 return self.loadByRef(field_ptr, field_ty, llvm_field.alignment, false);
6054 else
6055 llvm_field.ty.abiAlignment(mod);
6056 return self.loadByRef(field_ptr, field_ty, field_alignment, false);
6057 } else {6039 } else {
6058 return self.load(field_ptr, field_ptr_ty);6040 return self.load(field_ptr, field_ptr_ty);
6059 }6041 }
...@@ -6151,7 +6133,7 @@ pub const FuncGen = struct {...@@ -6151,7 +6133,7 @@ pub const FuncGen = struct {
6151 const fn_ty = try mod.funcType(.{6133 const fn_ty = try mod.funcType(.{
6152 .param_types = &.{},6134 .param_types = &.{},
6153 .return_type = .void_type,6135 .return_type = .void_type,
6154 .alignment = 0,6136 .alignment = .none,
6155 .noalias_bits = 0,6137 .noalias_bits = 0,
6156 .comptime_bits = 0,6138 .comptime_bits = 0,
6157 .cc = .Unspecified,6139 .cc = .Unspecified,
...@@ -6655,8 +6637,7 @@ pub const FuncGen = struct {...@@ -6655,8 +6637,7 @@ pub const FuncGen = struct {
6655 operand;6637 operand;
6656 if (payload_ty.isSlice(mod)) {6638 if (payload_ty.isSlice(mod)) {
6657 const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");6639 const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");
6658 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;6640 const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(mod));
6659 const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf, mod));
6660 return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");6641 return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");
6661 }6642 }
6662 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");6643 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
...@@ -6923,7 +6904,7 @@ pub const FuncGen = struct {...@@ -6923,7 +6904,7 @@ pub const FuncGen = struct {
6923 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, "");6904 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, "");
6924 const field_ptr_ty = try mod.ptrType(.{6905 const field_ptr_ty = try mod.ptrType(.{
6925 .elem_type = llvm_field.ty.ip_index,6906 .elem_type = llvm_field.ty.ip_index,
6926 .alignment = llvm_field.alignment,6907 .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment),
6927 });6908 });
6928 return self.load(field_ptr, field_ptr_ty);6909 return self.load(field_ptr, field_ptr_ty);
6929 }6910 }
...@@ -9319,14 +9300,12 @@ pub const FuncGen = struct {...@@ -9319,14 +9300,12 @@ pub const FuncGen = struct {
9319 const llvm_i = llvmField(result_ty, i, mod).?.index;9300 const llvm_i = llvmField(result_ty, i, mod).?.index;
9320 indices[1] = llvm_u32.constInt(llvm_i, .False);9301 indices[1] = llvm_u32.constInt(llvm_i, .False);
9321 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");9302 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
9322 var field_ptr_payload: Type.Payload.Pointer = .{9303 const field_ptr_ty = try mod.ptrType(.{
9323 .data = .{9304 .elem_type = self.typeOf(elem).toIntern(),
9324 .pointee_type = self.typeOf(elem),9305 .alignment = InternPool.Alignment.fromNonzeroByteUnits(
9325 .@"align" = result_ty.structFieldAlign(i, mod),9306 result_ty.structFieldAlign(i, mod),
9326 .@"addrspace" = .generic,9307 ),
9327 },9308 });
9328 };
9329 const field_ptr_ty = Type.initPayload(&field_ptr_payload.base);
9330 try self.store(field_ptr, field_ptr_ty, llvm_elem, .NotAtomic);9309 try self.store(field_ptr, field_ptr_ty, llvm_elem, .NotAtomic);
9331 }9310 }
93329311
...@@ -9350,13 +9329,9 @@ pub const FuncGen = struct {...@@ -9350,13 +9329,9 @@ pub const FuncGen = struct {
9350 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));9329 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
93519330
9352 const array_info = result_ty.arrayInfo(mod);9331 const array_info = result_ty.arrayInfo(mod);
9353 var elem_ptr_payload: Type.Payload.Pointer = .{9332 const elem_ptr_ty = try mod.ptrType(.{
9354 .data = .{9333 .elem_type = array_info.elem_type.toIntern(),
9355 .pointee_type = array_info.elem_type,9334 });
9356 .@"addrspace" = .generic,
9357 },
9358 };
9359 const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base);
93609335
9361 for (elements, 0..) |elem, i| {9336 for (elements, 0..) |elem, i| {
9362 const indices: [2]*llvm.Value = .{9337 const indices: [2]*llvm.Value = .{
...@@ -9476,14 +9451,10 @@ pub const FuncGen = struct {...@@ -9476,14 +9451,10 @@ pub const FuncGen = struct {
9476 // tag and the payload.9451 // tag and the payload.
9477 const index_type = self.context.intType(32);9452 const index_type = self.context.intType(32);
94789453
9479 var field_ptr_payload: Type.Payload.Pointer = .{9454 const field_ptr_ty = try mod.ptrType(.{
9480 .data = .{9455 .elem_type = field.ty.toIntern(),
9481 .pointee_type = field.ty,9456 .alignment = InternPool.Alignment.fromNonzeroByteUnits(field_align),
9482 .@"align" = field_align,9457 });
9483 .@"addrspace" = .generic,
9484 },
9485 };
9486 const field_ptr_ty = Type.initPayload(&field_ptr_payload.base);
9487 if (layout.tag_size == 0) {9458 if (layout.tag_size == 0) {
9488 const indices: [3]*llvm.Value = .{9459 const indices: [3]*llvm.Value = .{
9489 index_type.constNull(),9460 index_type.constNull(),
src/codegen/spirv.zig+2-4
...@@ -669,8 +669,7 @@ pub const DeclGen = struct {...@@ -669,8 +669,7 @@ pub const DeclGen = struct {
669 .slice => {669 .slice => {
670 const slice = val.castTag(.slice).?.data;670 const slice = val.castTag(.slice).?.data;
671671
672 var buf: Type.SlicePtrFieldTypeBuffer = undefined;672 const ptr_ty = ty.slicePtrFieldType(mod);
673 const ptr_ty = ty.slicePtrFieldType(&buf, mod);
674673
675 try self.lower(ptr_ty, slice.ptr);674 try self.lower(ptr_ty, slice.ptr);
676 try self.addInt(Type.usize, slice.len);675 try self.addInt(Type.usize, slice.len);
...@@ -2991,9 +2990,8 @@ pub const DeclGen = struct {...@@ -2991,9 +2990,8 @@ pub const DeclGen = struct {
2991 if (optional_ty.optionalReprIsPayload(mod)) {2990 if (optional_ty.optionalReprIsPayload(mod)) {
2992 // Pointer payload represents nullability: pointer or slice.2991 // Pointer payload represents nullability: pointer or slice.
29932992
2994 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2995 const ptr_ty = if (payload_ty.isSlice(mod))2993 const ptr_ty = if (payload_ty.isSlice(mod))
2996 payload_ty.slicePtrFieldType(&ptr_buf, mod)2994 payload_ty.slicePtrFieldType(mod)
2997 else2995 else
2998 payload_ty;2996 payload_ty;
29992997
src/link/Dwarf.zig+1-2
...@@ -277,8 +277,7 @@ pub const DeclState = struct {...@@ -277,8 +277,7 @@ pub const DeclState = struct {
277 // DW.AT.type, DW.FORM.ref4277 // DW.AT.type, DW.FORM.ref4
278 var index = dbg_info_buffer.items.len;278 var index = dbg_info_buffer.items.len;
279 try dbg_info_buffer.resize(index + 4);279 try dbg_info_buffer.resize(index + 4);
280 var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);280 const ptr_ty = ty.slicePtrFieldType(mod);
281 const ptr_ty = ty.slicePtrFieldType(buf, mod);
282 try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index));281 try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index));
283 // DW.AT.data_member_location, DW.FORM.udata282 // DW.AT.data_member_location, DW.FORM.udata
284 try dbg_info_buffer.ensureUnusedCapacity(6);283 try dbg_info_buffer.ensureUnusedCapacity(6);
src/type.zig+117-403
...@@ -42,7 +42,6 @@ pub const Type = struct {...@@ -42,7 +42,6 @@ pub const Type = struct {
42 .error_set_merged,42 .error_set_merged,
43 => return .ErrorSet,43 => return .ErrorSet,
4444
45 .pointer,
46 .inferred_alloc_const,45 .inferred_alloc_const,
47 .inferred_alloc_mut,46 .inferred_alloc_mut,
48 => return .Pointer,47 => return .Pointer,
...@@ -250,17 +249,9 @@ pub const Type = struct {...@@ -250,17 +249,9 @@ pub const Type = struct {
250 return elem_ty;249 return elem_ty;
251 }250 }
252251
252 /// Asserts the type is a pointer.
253 pub fn ptrIsMutable(ty: Type, mod: *const Module) bool {253 pub fn ptrIsMutable(ty: Type, mod: *const Module) bool {
254 return switch (ty.ip_index) {254 return !mod.intern_pool.indexToKey(ty.ip_index).ptr_type.is_const;
255 .none => switch (ty.tag()) {
256 .pointer => ty.castTag(.pointer).?.data.mutable,
257 else => unreachable,
258 },
259 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
260 .ptr_type => |ptr_type| !ptr_type.is_const,
261 else => unreachable,
262 },
263 };
264 }255 }
265256
266 pub const ArrayInfo = struct {257 pub const ArrayInfo = struct {
...@@ -277,24 +268,21 @@ pub const Type = struct {...@@ -277,24 +268,21 @@ pub const Type = struct {
277 };268 };
278 }269 }
279270
280 pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data {271 pub fn ptrInfoIp(ty: Type, ip: InternPool) InternPool.Key.PtrType {
281 return switch (ty.ip_index) {272 return switch (ip.indexToKey(ty.ip_index)) {
282 .none => switch (ty.tag()) {273 .ptr_type => |p| p,
283 .pointer => ty.castTag(.pointer).?.data,274 .opt_type => |child| switch (ip.indexToKey(child)) {
284275 .ptr_type => |p| p,
285 else => unreachable,
286 },
287 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
288 .ptr_type => |p| Payload.Pointer.Data.fromKey(p),
289 .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) {
290 .ptr_type => |p| Payload.Pointer.Data.fromKey(p),
291 else => unreachable,
292 },
293 else => unreachable,276 else => unreachable,
294 },277 },
278 else => unreachable,
295 };279 };
296 }280 }
297281
282 pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data {
283 return Payload.Pointer.Data.fromKey(ptrInfoIp(ty, mod.intern_pool));
284 }
285
298 pub fn eql(a: Type, b: Type, mod: *Module) bool {286 pub fn eql(a: Type, b: Type, mod: *Module) bool {
299 if (a.ip_index != .none or b.ip_index != .none) {287 if (a.ip_index != .none or b.ip_index != .none) {
300 // The InternPool data structure hashes based on Key to make interned objects288 // The InternPool data structure hashes based on Key to make interned objects
...@@ -335,7 +323,6 @@ pub const Type = struct {...@@ -335,7 +323,6 @@ pub const Type = struct {
335 return true;323 return true;
336 },324 },
337325
338 .pointer,
339 .inferred_alloc_const,326 .inferred_alloc_const,
340 .inferred_alloc_mut,327 .inferred_alloc_mut,
341 => {328 => {
...@@ -434,7 +421,6 @@ pub const Type = struct {...@@ -434,7 +421,6 @@ pub const Type = struct {
434 std.hash.autoHash(hasher, ies);421 std.hash.autoHash(hasher, ies);
435 },422 },
436423
437 .pointer,
438 .inferred_alloc_const,424 .inferred_alloc_const,
439 .inferred_alloc_mut,425 .inferred_alloc_mut,
440 => {426 => {
...@@ -512,26 +498,6 @@ pub const Type = struct {...@@ -512,26 +498,6 @@ pub const Type = struct {
512 .inferred_alloc_mut,498 .inferred_alloc_mut,
513 => unreachable,499 => unreachable,
514500
515 .pointer => {
516 const payload = self.castTag(.pointer).?.data;
517 const sent: ?Value = if (payload.sentinel) |some|
518 try some.copy(allocator)
519 else
520 null;
521 return Tag.pointer.create(allocator, .{
522 .pointee_type = try payload.pointee_type.copy(allocator),
523 .sentinel = sent,
524 .@"align" = payload.@"align",
525 .@"addrspace" = payload.@"addrspace",
526 .bit_offset = payload.bit_offset,
527 .host_size = payload.host_size,
528 .vector_index = payload.vector_index,
529 .@"allowzero" = payload.@"allowzero",
530 .mutable = payload.mutable,
531 .@"volatile" = payload.@"volatile",
532 .size = payload.size,
533 });
534 },
535 .error_union => {501 .error_union => {
536 const payload = self.castTag(.error_union).?.data;502 const payload = self.castTag(.error_union).?.data;
537 return Tag.error_union.create(allocator, .{503 return Tag.error_union.create(allocator, .{
...@@ -623,41 +589,6 @@ pub const Type = struct {...@@ -623,41 +589,6 @@ pub const Type = struct {
623 while (true) {589 while (true) {
624 const t = ty.tag();590 const t = ty.tag();
625 switch (t) {591 switch (t) {
626 .pointer => {
627 const payload = ty.castTag(.pointer).?.data;
628 if (payload.sentinel) |some| switch (payload.size) {
629 .One, .C => unreachable,
630 .Many => try writer.print("[*:{}]", .{some.fmtDebug()}),
631 .Slice => try writer.print("[:{}]", .{some.fmtDebug()}),
632 } else switch (payload.size) {
633 .One => try writer.writeAll("*"),
634 .Many => try writer.writeAll("[*]"),
635 .C => try writer.writeAll("[*c]"),
636 .Slice => try writer.writeAll("[]"),
637 }
638 if (payload.@"align" != 0 or payload.host_size != 0 or payload.vector_index != .none) {
639 try writer.print("align({d}", .{payload.@"align"});
640
641 if (payload.bit_offset != 0 or payload.host_size != 0) {
642 try writer.print(":{d}:{d}", .{ payload.bit_offset, payload.host_size });
643 }
644 if (payload.vector_index == .runtime) {
645 try writer.writeAll(":?");
646 } else if (payload.vector_index != .none) {
647 try writer.print(":{d}", .{@enumToInt(payload.vector_index)});
648 }
649 try writer.writeAll(") ");
650 }
651 if (payload.@"addrspace" != .generic) {
652 try writer.print("addrspace(.{s}) ", .{@tagName(payload.@"addrspace")});
653 }
654 if (!payload.mutable) try writer.writeAll("const ");
655 if (payload.@"volatile") try writer.writeAll("volatile ");
656 if (payload.@"allowzero" and payload.size != .C) try writer.writeAll("allowzero ");
657
658 ty = payload.pointee_type;
659 continue;
660 },
661 .error_union => {592 .error_union => {
662 const payload = ty.castTag(.error_union).?.data;593 const payload = ty.castTag(.error_union).?.data;
663 try payload.error_set.dump("", .{}, writer);594 try payload.error_set.dump("", .{}, writer);
...@@ -734,47 +665,6 @@ pub const Type = struct {...@@ -734,47 +665,6 @@ pub const Type = struct {
734 try print(error_union.payload, writer, mod);665 try print(error_union.payload, writer, mod);
735 },666 },
736667
737 .pointer => {
738 const info = ty.ptrInfo(mod);
739
740 if (info.sentinel) |s| switch (info.size) {
741 .One, .C => unreachable,
742 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),
743 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),
744 } else switch (info.size) {
745 .One => try writer.writeAll("*"),
746 .Many => try writer.writeAll("[*]"),
747 .C => try writer.writeAll("[*c]"),
748 .Slice => try writer.writeAll("[]"),
749 }
750 if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) {
751 if (info.@"align" != 0) {
752 try writer.print("align({d}", .{info.@"align"});
753 } else {
754 const alignment = info.pointee_type.abiAlignment(mod);
755 try writer.print("align({d}", .{alignment});
756 }
757
758 if (info.bit_offset != 0 or info.host_size != 0) {
759 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
760 }
761 if (info.vector_index == .runtime) {
762 try writer.writeAll(":?");
763 } else if (info.vector_index != .none) {
764 try writer.print(":{d}", .{@enumToInt(info.vector_index)});
765 }
766 try writer.writeAll(") ");
767 }
768 if (info.@"addrspace" != .generic) {
769 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
770 }
771 if (!info.mutable) try writer.writeAll("const ");
772 if (info.@"volatile") try writer.writeAll("volatile ");
773 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
774
775 try print(info.pointee_type, writer, mod);
776 },
777
778 .error_set => {668 .error_set => {
779 const names = ty.castTag(.error_set).?.data.names.keys();669 const names = ty.castTag(.error_set).?.data.names.keys();
780 try writer.writeAll("error{");670 try writer.writeAll("error{");
...@@ -951,8 +841,8 @@ pub const Type = struct {...@@ -951,8 +841,8 @@ pub const Type = struct {
951 try writer.writeAll("...");841 try writer.writeAll("...");
952 }842 }
953 try writer.writeAll(") ");843 try writer.writeAll(") ");
954 if (fn_info.alignment != 0) {844 if (fn_info.alignment.toByteUnitsOptional()) |a| {
955 try writer.print("align({d}) ", .{fn_info.alignment});845 try writer.print("align({d}) ", .{a});
956 }846 }
957 if (fn_info.cc != .Unspecified) {847 if (fn_info.cc != .Unspecified) {
958 try writer.writeAll("callconv(.");848 try writer.writeAll("callconv(.");
...@@ -1032,20 +922,6 @@ pub const Type = struct {...@@ -1032,20 +922,6 @@ pub const Type = struct {
1032 .error_set_merged,922 .error_set_merged,
1033 => return true,923 => return true,
1034924
1035 // Pointers to zero-bit types still have a runtime address; however, pointers
1036 // to comptime-only types do not, with the exception of function pointers.
1037 .pointer => {
1038 if (ignore_comptime_only) {
1039 return true;
1040 } else if (ty.childType(mod).zigTypeTag(mod) == .Fn) {
1041 return !mod.typeToFunc(ty.childType(mod)).?.is_generic;
1042 } else if (strat == .sema) {
1043 return !(try strat.sema.typeRequiresComptime(ty));
1044 } else {
1045 return !comptimeOnly(ty, mod);
1046 }
1047 },
1048
1049 .inferred_alloc_const => unreachable,925 .inferred_alloc_const => unreachable,
1050 .inferred_alloc_mut => unreachable,926 .inferred_alloc_mut => unreachable,
1051 },927 },
...@@ -1231,8 +1107,6 @@ pub const Type = struct {...@@ -1231,8 +1107,6 @@ pub const Type = struct {
1231 .empty_struct_type => false,1107 .empty_struct_type => false,
12321108
1233 .none => switch (ty.tag()) {1109 .none => switch (ty.tag()) {
1234 .pointer => true,
1235
1236 .error_set,1110 .error_set,
1237 .error_set_single,1111 .error_set_single,
1238 .error_set_inferred,1112 .error_set_inferred,
...@@ -1410,51 +1284,27 @@ pub const Type = struct {...@@ -1410,51 +1284,27 @@ pub const Type = struct {
1410 }1284 }
14111285
1412 pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 {1286 pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 {
1413 switch (ty.ip_index) {1287 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1414 .none => switch (ty.tag()) {1288 .ptr_type => |ptr_type| {
1415 .pointer => {1289 if (ptr_type.alignment.toByteUnitsOptional()) |a| {
1416 const ptr_info = ty.castTag(.pointer).?.data;1290 return @intCast(u32, a);
1417 if (ptr_info.@"align" != 0) {1291 } else if (opt_sema) |sema| {
1418 return ptr_info.@"align";1292 const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema });
1419 } else if (opt_sema) |sema| {1293 return res.scalar;
1420 const res = try ptr_info.pointee_type.abiAlignmentAdvanced(mod, .{ .sema = sema });1294 } else {
1421 return res.scalar;1295 return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
1422 } else {1296 }
1423 return (ptr_info.pointee_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
1424 }
1425 },
1426
1427 else => unreachable,
1428 },
1429 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1430 .ptr_type => |ptr_type| {
1431 if (ptr_type.alignment != 0) {
1432 return @intCast(u32, ptr_type.alignment);
1433 } else if (opt_sema) |sema| {
1434 const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema });
1435 return res.scalar;
1436 } else {
1437 return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
1438 }
1439 },
1440 .opt_type => |child| return child.toType().ptrAlignmentAdvanced(mod, opt_sema),
1441 else => unreachable,
1442 },1297 },
1443 }1298 .opt_type => |child| child.toType().ptrAlignmentAdvanced(mod, opt_sema),
1299 else => unreachable,
1300 };
1444 }1301 }
14451302
1446 pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace {1303 pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace {
1447 return switch (ty.ip_index) {1304 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1448 .none => switch (ty.tag()) {1305 .ptr_type => |ptr_type| ptr_type.address_space,
1449 .pointer => ty.castTag(.pointer).?.data.@"addrspace",1306 .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space,
14501307 else => unreachable,
1451 else => unreachable,
1452 },
1453 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1454 .ptr_type => |ptr_type| ptr_type.address_space,
1455 .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space,
1456 else => unreachable,
1457 },
1458 };1308 };
1459 }1309 }
14601310
...@@ -1504,7 +1354,6 @@ pub const Type = struct {...@@ -1504,7 +1354,6 @@ pub const Type = struct {
1504 switch (ty.ip_index) {1354 switch (ty.ip_index) {
1505 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 },1355 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 },
1506 .none => switch (ty.tag()) {1356 .none => switch (ty.tag()) {
1507 .pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
15081357
1509 // TODO revisit this when we have the concept of the error tag type1358 // TODO revisit this when we have the concept of the error tag type
1510 .error_set_inferred,1359 .error_set_inferred,
...@@ -1541,10 +1390,11 @@ pub const Type = struct {...@@ -1541,10 +1390,11 @@ pub const Type = struct {
1541 .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat),1390 .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat),
1542 .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),1391 .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
1543 // represents machine code; not a pointer1392 // represents machine code; not a pointer
1544 .func_type => |func_type| {1393 .func_type => |func_type| return AbiAlignmentAdvanced{
1545 const alignment = @intCast(u32, func_type.alignment);1394 .scalar = if (func_type.alignment.toByteUnitsOptional()) |a|
1546 if (alignment != 0) return AbiAlignmentAdvanced{ .scalar = alignment };1395 @intCast(u32, a)
1547 return AbiAlignmentAdvanced{ .scalar = target_util.defaultFunctionAlignment(target) };1396 else
1397 target_util.defaultFunctionAlignment(target),
1548 },1398 },
15491399
1550 .simple_type => |t| switch (t) {1400 .simple_type => |t| switch (t) {
...@@ -1882,11 +1732,6 @@ pub const Type = struct {...@@ -1882,11 +1732,6 @@ pub const Type = struct {
1882 .inferred_alloc_const => unreachable,1732 .inferred_alloc_const => unreachable,
1883 .inferred_alloc_mut => unreachable,1733 .inferred_alloc_mut => unreachable,
18841734
1885 .pointer => switch (ty.castTag(.pointer).?.data.size) {
1886 .Slice => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },
1887 else => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
1888 },
1889
1890 // TODO revisit this when we have the concept of the error tag type1735 // TODO revisit this when we have the concept of the error tag type
1891 .error_set_inferred,1736 .error_set_inferred,
1892 .error_set,1737 .error_set,
...@@ -2201,11 +2046,6 @@ pub const Type = struct {...@@ -2201,11 +2046,6 @@ pub const Type = struct {
2201 .inferred_alloc_const => unreachable,2046 .inferred_alloc_const => unreachable,
2202 .inferred_alloc_mut => unreachable,2047 .inferred_alloc_mut => unreachable,
22032048
2204 .pointer => switch (ty.castTag(.pointer).?.data.size) {
2205 .Slice => return target.ptrBitWidth() * 2,
2206 else => return target.ptrBitWidth(),
2207 },
2208
2209 .error_set,2049 .error_set,
2210 .error_set_single,2050 .error_set_single,
2211 .error_set_inferred,2051 .error_set_inferred,
...@@ -2384,8 +2224,6 @@ pub const Type = struct {...@@ -2384,8 +2224,6 @@ pub const Type = struct {
2384 .inferred_alloc_mut,2224 .inferred_alloc_mut,
2385 => true,2225 => true,
23862226
2387 .pointer => ty.castTag(.pointer).?.data.size == .One,
2388
2389 else => false,2227 else => false,
2390 },2228 },
2391 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {2229 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
...@@ -2408,8 +2246,6 @@ pub const Type = struct {...@@ -2408,8 +2246,6 @@ pub const Type = struct {
2408 .inferred_alloc_mut,2246 .inferred_alloc_mut,
2409 => .One,2247 => .One,
24102248
2411 .pointer => ty.castTag(.pointer).?.data.size,
2412
2413 else => null,2249 else => null,
2414 },2250 },
2415 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {2251 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
...@@ -2421,10 +2257,7 @@ pub const Type = struct {...@@ -2421,10 +2257,7 @@ pub const Type = struct {
24212257
2422 pub fn isSlice(ty: Type, mod: *const Module) bool {2258 pub fn isSlice(ty: Type, mod: *const Module) bool {
2423 return switch (ty.ip_index) {2259 return switch (ty.ip_index) {
2424 .none => switch (ty.tag()) {2260 .none => false,
2425 .pointer => ty.castTag(.pointer).?.data.size == .Slice,
2426 else => false,
2427 },
2428 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {2261 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2429 .ptr_type => |ptr_type| ptr_type.size == .Slice,2262 .ptr_type => |ptr_type| ptr_type.size == .Slice,
2430 else => false,2263 else => false,
...@@ -2432,50 +2265,14 @@ pub const Type = struct {...@@ -2432,50 +2265,14 @@ pub const Type = struct {
2432 };2265 };
2433 }2266 }
24342267
2435 pub const SlicePtrFieldTypeBuffer = union {2268 pub fn slicePtrFieldType(ty: Type, mod: *const Module) Type {
2436 pointer: Payload.Pointer,2269 return mod.intern_pool.slicePtrType(ty.ip_index).toType();
2437 };
2438
2439 pub fn slicePtrFieldType(ty: Type, buffer: *SlicePtrFieldTypeBuffer, mod: *const Module) Type {
2440 switch (ty.ip_index) {
2441 .none => switch (ty.tag()) {
2442 .pointer => {
2443 const payload = ty.castTag(.pointer).?.data;
2444 assert(payload.size == .Slice);
2445
2446 buffer.* = .{
2447 .pointer = .{
2448 .data = .{
2449 .pointee_type = payload.pointee_type,
2450 .sentinel = payload.sentinel,
2451 .@"align" = payload.@"align",
2452 .@"addrspace" = payload.@"addrspace",
2453 .bit_offset = payload.bit_offset,
2454 .host_size = payload.host_size,
2455 .vector_index = payload.vector_index,
2456 .@"allowzero" = payload.@"allowzero",
2457 .mutable = payload.mutable,
2458 .@"volatile" = payload.@"volatile",
2459 .size = .Many,
2460 },
2461 },
2462 };
2463 return Type.initPayload(&buffer.pointer.base);
2464 },
2465
2466 else => unreachable,
2467 },
2468 else => return mod.intern_pool.slicePtrType(ty.ip_index).toType(),
2469 }
2470 }2270 }
24712271
2472 pub fn isConstPtr(ty: Type, mod: *const Module) bool {2272 pub fn isConstPtr(ty: Type, mod: *const Module) bool {
2473 return switch (ty.ip_index) {2273 return switch (ty.ip_index) {
2474 .none => switch (ty.tag()) {2274 .none => false,
2475 .pointer => !ty.castTag(.pointer).?.data.mutable,2275 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2476 else => false,
2477 },
2478 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2479 .ptr_type => |ptr_type| ptr_type.is_const,2276 .ptr_type => |ptr_type| ptr_type.is_const,
2480 else => false,2277 else => false,
2481 },2278 },
...@@ -2488,10 +2285,7 @@ pub const Type = struct {...@@ -2488,10 +2285,7 @@ pub const Type = struct {
24882285
2489 pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool {2286 pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool {
2490 return switch (ty.ip_index) {2287 return switch (ty.ip_index) {
2491 .none => switch (ty.tag()) {2288 .none => false,
2492 .pointer => ty.castTag(.pointer).?.data.@"volatile",
2493 else => false,
2494 },
2495 else => switch (ip.indexToKey(ty.ip_index)) {2289 else => switch (ip.indexToKey(ty.ip_index)) {
2496 .ptr_type => |ptr_type| ptr_type.is_volatile,2290 .ptr_type => |ptr_type| ptr_type.is_volatile,
2497 else => false,2291 else => false,
...@@ -2501,12 +2295,10 @@ pub const Type = struct {...@@ -2501,12 +2295,10 @@ pub const Type = struct {
25012295
2502 pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool {2296 pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool {
2503 return switch (ty.ip_index) {2297 return switch (ty.ip_index) {
2504 .none => switch (ty.tag()) {2298 .none => false,
2505 .pointer => ty.castTag(.pointer).?.data.@"allowzero",
2506 else => ty.zigTypeTag(mod) == .Optional,
2507 },
2508 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {2299 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2509 .ptr_type => |ptr_type| ptr_type.is_allowzero,2300 .ptr_type => |ptr_type| ptr_type.is_allowzero,
2301 .opt_type => true,
2510 else => false,2302 else => false,
2511 },2303 },
2512 };2304 };
...@@ -2514,10 +2306,7 @@ pub const Type = struct {...@@ -2514,10 +2306,7 @@ pub const Type = struct {
25142306
2515 pub fn isCPtr(ty: Type, mod: *const Module) bool {2307 pub fn isCPtr(ty: Type, mod: *const Module) bool {
2516 return switch (ty.ip_index) {2308 return switch (ty.ip_index) {
2517 .none => switch (ty.tag()) {2309 .none => false,
2518 .pointer => ty.castTag(.pointer).?.data.size == .C,
2519 else => false,
2520 },
2521 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {2310 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2522 .ptr_type => |ptr_type| ptr_type.size == .C,2311 .ptr_type => |ptr_type| ptr_type.size == .C,
2523 else => false,2312 else => false,
...@@ -2526,16 +2315,9 @@ pub const Type = struct {...@@ -2526,16 +2315,9 @@ pub const Type = struct {
2526 }2315 }
25272316
2528 pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool {2317 pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool {
2529 switch (ty.ip_index) {2318 return switch (ty.ip_index) {
2530 .none => switch (ty.tag()) {2319 .none => false,
2531 .pointer => switch (ty.castTag(.pointer).?.data.size) {2320 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2532 .Slice => return false,
2533 .One, .Many, .C => return true,
2534 },
2535
2536 else => return false,
2537 },
2538 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2539 .ptr_type => |ptr_type| switch (ptr_type.size) {2321 .ptr_type => |ptr_type| switch (ptr_type.size) {
2540 .Slice => false,2322 .Slice => false,
2541 .One, .Many, .C => true,2323 .One, .Many, .C => true,
...@@ -2549,7 +2331,7 @@ pub const Type = struct {...@@ -2549,7 +2331,7 @@ pub const Type = struct {
2549 },2331 },
2550 else => false,2332 else => false,
2551 },2333 },
2552 }2334 };
2553 }2335 }
25542336
2555 /// For pointer-like optionals, returns true, otherwise returns the allowzero property2337 /// For pointer-like optionals, returns true, otherwise returns the allowzero property
...@@ -2563,47 +2345,43 @@ pub const Type = struct {...@@ -2563,47 +2345,43 @@ pub const Type = struct {
25632345
2564 /// See also `isPtrLikeOptional`.2346 /// See also `isPtrLikeOptional`.
2565 pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool {2347 pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool {
2566 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {2348 return switch (ty.ip_index) {
2567 .opt_type => |child| switch (child.toType().zigTypeTag(mod)) {2349 .none => false,
2568 .Pointer => {2350 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2569 const info = child.toType().ptrInfo(mod);2351 .opt_type => |child| switch (child.toType().zigTypeTag(mod)) {
2570 switch (info.size) {2352 .Pointer => {
2571 .C => return false,2353 const info = child.toType().ptrInfo(mod);
2572 else => return !info.@"allowzero",2354 return switch (info.size) {
2573 }2355 .C => false,
2356 else => !info.@"allowzero",
2357 };
2358 },
2359 .ErrorSet => true,
2360 else => false,
2574 },2361 },
2575 .ErrorSet => true,
2576 else => false,2362 else => false,
2577 },2363 },
2578 else => false,
2579 };2364 };
2580 switch (ty.tag()) {
2581 .pointer => return ty.castTag(.pointer).?.data.size == .C,
2582
2583 else => return false,
2584 }
2585 }2365 }
25862366
2587 /// Returns true if the type is optional and would be lowered to a single pointer2367 /// Returns true if the type is optional and would be lowered to a single pointer
2588 /// address value, using 0 for null. Note that this returns true for C pointers.2368 /// address value, using 0 for null. Note that this returns true for C pointers.
2589 /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`.2369 /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`.
2590 pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool {2370 pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool {
2591 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {2371 return switch (ty.ip_index) {
2592 .ptr_type => |ptr_type| ptr_type.size == .C,2372 .none => false,
2593 .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) {2373 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2594 .ptr_type => |ptr_type| switch (ptr_type.size) {2374 .ptr_type => |ptr_type| ptr_type.size == .C,
2595 .Slice, .C => false,2375 .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) {
2596 .Many, .One => !ptr_type.is_allowzero,2376 .ptr_type => |ptr_type| switch (ptr_type.size) {
2377 .Slice, .C => false,
2378 .Many, .One => !ptr_type.is_allowzero,
2379 },
2380 else => false,
2597 },2381 },
2598 else => false,2382 else => false,
2599 },2383 },
2600 else => false,
2601 };2384 };
2602 switch (ty.tag()) {
2603 .pointer => return ty.castTag(.pointer).?.data.size == .C,
2604
2605 else => return false,
2606 }
2607 }2385 }
26082386
2609 /// For *[N]T, returns [N]T.2387 /// For *[N]T, returns [N]T.
...@@ -2614,14 +2392,7 @@ pub const Type = struct {...@@ -2614,14 +2392,7 @@ pub const Type = struct {
2614 }2392 }
26152393
2616 pub fn childTypeIp(ty: Type, ip: InternPool) Type {2394 pub fn childTypeIp(ty: Type, ip: InternPool) Type {
2617 return switch (ty.ip_index) {2395 return ip.childType(ty.ip_index).toType();
2618 .none => switch (ty.tag()) {
2619 .pointer => ty.castTag(.pointer).?.data.pointee_type,
2620
2621 else => unreachable,
2622 },
2623 else => ip.childType(ty.ip_index).toType(),
2624 };
2625 }2396 }
26262397
2627 /// For *[N]T, returns T.2398 /// For *[N]T, returns T.
...@@ -2634,34 +2405,19 @@ pub const Type = struct {...@@ -2634,34 +2405,19 @@ pub const Type = struct {
2634 /// For []T, returns T.2405 /// For []T, returns T.
2635 /// For anyframe->T, returns T.2406 /// For anyframe->T, returns T.
2636 pub fn elemType2(ty: Type, mod: *const Module) Type {2407 pub fn elemType2(ty: Type, mod: *const Module) Type {
2637 return switch (ty.ip_index) {2408 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2638 .none => switch (ty.tag()) {2409 .ptr_type => |ptr_type| switch (ptr_type.size) {
2639 .pointer => {2410 .One => ptr_type.elem_type.toType().shallowElemType(mod),
2640 const info = ty.castTag(.pointer).?.data;2411 .Many, .C, .Slice => ptr_type.elem_type.toType(),
2641 const child_ty = info.pointee_type;
2642 if (info.size == .One) {
2643 return child_ty.shallowElemType(mod);
2644 } else {
2645 return child_ty;
2646 }
2647 },
2648
2649 else => unreachable,
2650 },2412 },
2651 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {2413 .anyframe_type => |child| {
2652 .ptr_type => |ptr_type| switch (ptr_type.size) {2414 assert(child != .none);
2653 .One => ptr_type.elem_type.toType().shallowElemType(mod),2415 return child.toType();
2654 .Many, .C, .Slice => ptr_type.elem_type.toType(),
2655 },
2656 .anyframe_type => |child| {
2657 assert(child != .none);
2658 return child.toType();
2659 },
2660 .vector_type => |vector_type| vector_type.child.toType(),
2661 .array_type => |array_type| array_type.child.toType(),
2662 .opt_type => |child| mod.intern_pool.childType(child).toType(),
2663 else => unreachable,
2664 },2416 },
2417 .vector_type => |vector_type| vector_type.child.toType(),
2418 .array_type => |array_type| array_type.child.toType(),
2419 .opt_type => |child| mod.intern_pool.childType(child).toType(),
2420 else => unreachable,
2665 };2421 };
2666 }2422 }
26672423
...@@ -2683,21 +2439,13 @@ pub const Type = struct {...@@ -2683,21 +2439,13 @@ pub const Type = struct {
2683 /// Asserts that the type is an optional.2439 /// Asserts that the type is an optional.
2684 /// Note that for C pointers this returns the type unmodified.2440 /// Note that for C pointers this returns the type unmodified.
2685 pub fn optionalChild(ty: Type, mod: *const Module) Type {2441 pub fn optionalChild(ty: Type, mod: *const Module) Type {
2686 return switch (ty.ip_index) {2442 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2687 .none => switch (ty.tag()) {2443 .opt_type => |child| child.toType(),
2688 .pointer, // here we assume it is a C pointer2444 .ptr_type => |ptr_type| b: {
2689 => return ty,2445 assert(ptr_type.size == .C);
26902446 break :b ty;
2691 else => unreachable,
2692 },
2693 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2694 .opt_type => |child| child.toType(),
2695 .ptr_type => |ptr_type| b: {
2696 assert(ptr_type.size == .C);
2697 break :b ty;
2698 },
2699 else => unreachable,
2700 },2447 },
2448 else => unreachable,
2701 };2449 };
2702 }2450 }
27032451
...@@ -2921,23 +2669,16 @@ pub const Type = struct {...@@ -2921,23 +2669,16 @@ pub const Type = struct {
29212669
2922 /// Asserts the type is an array, pointer or vector.2670 /// Asserts the type is an array, pointer or vector.
2923 pub fn sentinel(ty: Type, mod: *const Module) ?Value {2671 pub fn sentinel(ty: Type, mod: *const Module) ?Value {
2924 return switch (ty.ip_index) {2672 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2925 .none => switch (ty.tag()) {2673 .vector_type,
2926 .pointer => ty.castTag(.pointer).?.data.sentinel,2674 .struct_type,
29272675 .anon_struct_type,
2928 else => unreachable,2676 => null,
2929 },
2930 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2931 .vector_type,
2932 .struct_type,
2933 .anon_struct_type,
2934 => null,
29352677
2936 .array_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null,2678 .array_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null,
2937 .ptr_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null,2679 .ptr_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null,
29382680
2939 else => unreachable,2681 else => unreachable,
2940 },
2941 };2682 };
2942 }2683 }
29432684
...@@ -3196,7 +2937,6 @@ pub const Type = struct {...@@ -3196,7 +2937,6 @@ pub const Type = struct {
3196 .error_set,2937 .error_set,
3197 .error_set_merged,2938 .error_set_merged,
3198 .error_set_inferred,2939 .error_set_inferred,
3199 .pointer,
3200 => return null,2940 => return null,
32012941
3202 .inferred_alloc_const => unreachable,2942 .inferred_alloc_const => unreachable,
...@@ -3400,15 +3140,6 @@ pub const Type = struct {...@@ -3400,15 +3140,6 @@ pub const Type = struct {
3400 .inferred_alloc_mut => unreachable,3140 .inferred_alloc_mut => unreachable,
3401 .inferred_alloc_const => unreachable,3141 .inferred_alloc_const => unreachable,
34023142
3403 .pointer => {
3404 const child_ty = ty.childType(mod);
3405 if (child_ty.zigTypeTag(mod) == .Fn) {
3406 return false;
3407 } else {
3408 return child_ty.comptimeOnly(mod);
3409 }
3410 },
3411
3412 .error_union => return ty.errorUnionPayload().comptimeOnly(mod),3143 .error_union => return ty.errorUnionPayload().comptimeOnly(mod),
3413 },3144 },
3414 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {3145 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
...@@ -4096,7 +3827,6 @@ pub const Type = struct {...@@ -4096,7 +3827,6 @@ pub const Type = struct {
4096 inferred_alloc_const, // See last_no_payload_tag below.3827 inferred_alloc_const, // See last_no_payload_tag below.
4097 // After this, the tag requires a payload.3828 // After this, the tag requires a payload.
40983829
4099 pointer,
4100 error_union,3830 error_union,
4101 error_set,3831 error_set,
4102 error_set_single,3832 error_set_single,
...@@ -4117,7 +3847,6 @@ pub const Type = struct {...@@ -4117,7 +3847,6 @@ pub const Type = struct {
4117 .error_set_inferred => Payload.ErrorSetInferred,3847 .error_set_inferred => Payload.ErrorSetInferred,
4118 .error_set_merged => Payload.ErrorSetMerged,3848 .error_set_merged => Payload.ErrorSetMerged,
41193849
4120 .pointer => Payload.Pointer,
4121 .error_union => Payload.ErrorUnion,3850 .error_union => Payload.ErrorUnion,
4122 .error_set_single => Payload.Name,3851 .error_set_single => Payload.Name,
4123 };3852 };
...@@ -4230,10 +3959,8 @@ pub const Type = struct {...@@ -4230,10 +3959,8 @@ pub const Type = struct {
4230 data: *Module.Fn.InferredErrorSet,3959 data: *Module.Fn.InferredErrorSet,
4231 };3960 };
42323961
3962 /// TODO: remove this data structure since we have `InternPool.Key.PtrType`.
4233 pub const Pointer = struct {3963 pub const Pointer = struct {
4234 pub const base_tag = Tag.pointer;
4235
4236 base: Payload = Payload{ .tag = base_tag },
4237 data: Data,3964 data: Data,
42383965
4239 pub const Data = struct {3966 pub const Data = struct {
...@@ -4270,7 +3997,7 @@ pub const Type = struct {...@@ -4270,7 +3997,7 @@ pub const Type = struct {
4270 return .{3997 return .{
4271 .pointee_type = p.elem_type.toType(),3998 .pointee_type = p.elem_type.toType(),
4272 .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null,3999 .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null,
4273 .@"align" = @intCast(u32, p.alignment),4000 .@"align" = @intCast(u32, p.alignment.toByteUnits(0)),
4274 .@"addrspace" = p.address_space,4001 .@"addrspace" = p.address_space,
4275 .bit_offset = p.bit_offset,4002 .bit_offset = p.bit_offset,
4276 .host_size = p.host_size,4003 .host_size = p.host_size,
...@@ -4368,11 +4095,11 @@ pub const Type = struct {...@@ -4368,11 +4095,11 @@ pub const Type = struct {
4368 pub const err_int = Type.u16;4095 pub const err_int = Type.u16;
43694096
4370 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {4097 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
4371 var d = data;4098 // TODO: update callsites of this function to directly call mod.ptrType
4099 // and then delete this function.
4100 _ = arena;
43724101
4373 if (d.size == .C) {4102 var d = data;
4374 d.@"allowzero" = true;
4375 }
43764103
4377 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee4104 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
4378 // type, we change it to 0 here. If this causes an assertion trip because the4105 // type, we change it to 0 here. If this causes an assertion trip because the
...@@ -4396,32 +4123,19 @@ pub const Type = struct {...@@ -4396,32 +4123,19 @@ pub const Type = struct {
4396 }4123 }
4397 }4124 }
43984125
4399 ip: {4126 return mod.ptrType(.{
4400 if (d.pointee_type.ip_index == .none) break :ip;4127 .elem_type = d.pointee_type.ip_index,
44014128 .sentinel = if (d.sentinel) |s| s.ip_index else .none,
4402 if (d.sentinel) |s| {4129 .alignment = InternPool.Alignment.fromByteUnits(d.@"align"),
4403 switch (s.ip_index) {4130 .host_size = d.host_size,
4404 .none, .null_value => break :ip,4131 .bit_offset = d.bit_offset,
4405 else => {},4132 .vector_index = d.vector_index,
4406 }4133 .size = d.size,
4407 }4134 .is_const = !d.mutable,
44084135 .is_volatile = d.@"volatile",
4409 return mod.ptrType(.{4136 .is_allowzero = d.@"allowzero",
4410 .elem_type = d.pointee_type.ip_index,4137 .address_space = d.@"addrspace",
4411 .sentinel = if (d.sentinel) |s| s.ip_index else .none,4138 });
4412 .alignment = d.@"align",
4413 .host_size = d.host_size,
4414 .bit_offset = d.bit_offset,
4415 .vector_index = d.vector_index,
4416 .size = d.size,
4417 .is_const = !d.mutable,
4418 .is_volatile = d.@"volatile",
4419 .is_allowzero = d.@"allowzero",
4420 .address_space = d.@"addrspace",
4421 });
4422 }
4423
4424 return Type.Tag.pointer.create(arena, d);
4425 }4139 }
44264140
4427 pub fn array(4141 pub fn array(
src/value.zig+4-8
...@@ -1844,8 +1844,7 @@ pub const Value = struct {...@@ -1844,8 +1844,7 @@ pub const Value = struct {
1844 return false;1844 return false;
1845 }1845 }
18461846
1847 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;1847 const ptr_ty = ty.slicePtrFieldType(mod);
1848 const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
18491848
1850 return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema);1849 return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema);
1851 },1850 },
...@@ -2001,8 +2000,7 @@ pub const Value = struct {...@@ -2001,8 +2000,7 @@ pub const Value = struct {
2001 return false;2000 return false;
2002 }2001 }
20032002
2004 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2003 const ptr_ty = ty.slicePtrFieldType(mod);
2005 const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
2006 const a_ptr = switch (a_ty.ptrSize(mod)) {2004 const a_ptr = switch (a_ty.ptrSize(mod)) {
2007 .Slice => a.slicePtr(),2005 .Slice => a.slicePtr(),
2008 .One => a,2006 .One => a,
...@@ -2121,8 +2119,7 @@ pub const Value = struct {...@@ -2121,8 +2119,7 @@ pub const Value = struct {
2121 .Bool, .Int, .ComptimeInt, .Pointer => switch (val.tag()) {2119 .Bool, .Int, .ComptimeInt, .Pointer => switch (val.tag()) {
2122 .slice => {2120 .slice => {
2123 const slice = val.castTag(.slice).?.data;2121 const slice = val.castTag(.slice).?.data;
2124 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2122 const ptr_ty = ty.slicePtrFieldType(mod);
2125 const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
2126 hash(slice.ptr, ptr_ty, hasher, mod);2123 hash(slice.ptr, ptr_ty, hasher, mod);
2127 hash(slice.len, Type.usize, hasher, mod);2124 hash(slice.len, Type.usize, hasher, mod);
2128 },2125 },
...@@ -2253,8 +2250,7 @@ pub const Value = struct {...@@ -2253,8 +2250,7 @@ pub const Value = struct {
2253 .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) {2250 .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) {
2254 .slice => {2251 .slice => {
2255 const slice = val.castTag(.slice).?.data;2252 const slice = val.castTag(.slice).?.data;
2256 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2253 const ptr_ty = ty.slicePtrFieldType(mod);
2257 const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
2258 slice.ptr.hashUncoerced(ptr_ty, hasher, mod);2254 slice.ptr.hashUncoerced(ptr_ty, hasher, mod);
2259 },2255 },
2260 else => val.hashPtr(hasher, mod),2256 else => val.hashPtr(hasher, mod),