authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-21 00:07:49-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-06-21 00:07:49-07:00
log12813d5912c55d6b290690d821a782d6c756f11c
treedd4b5f2a2ae81562ccb51fa1731309416860451e
parenta257e33fff8dd9efa7f43ea14e05eef65a7f3354
parent96cdd51c14337b012910a36ba93121a371509cfd
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #16105 from jacobly0/intern-pool-opt

InternPool: various optimizations

16 files changed, 1422 insertions(+), 1386 deletions(-)

src/Air.zig+6-3
...@@ -850,6 +850,8 @@ pub const Inst = struct {...@@ -850,6 +850,8 @@ pub const Inst = struct {
850 pub const Index = u32;850 pub const Index = u32;
851851
852 pub const Ref = enum(u32) {852 pub const Ref = enum(u32) {
853 u0_type = @intFromEnum(InternPool.Index.u0_type),
854 i0_type = @intFromEnum(InternPool.Index.i0_type),
853 u1_type = @intFromEnum(InternPool.Index.u1_type),855 u1_type = @intFromEnum(InternPool.Index.u1_type),
854 u8_type = @intFromEnum(InternPool.Index.u8_type),856 u8_type = @intFromEnum(InternPool.Index.u8_type),
855 i8_type = @intFromEnum(InternPool.Index.i8_type),857 i8_type = @intFromEnum(InternPool.Index.i8_type),
...@@ -909,6 +911,7 @@ pub const Inst = struct {...@@ -909,6 +911,7 @@ pub const Inst = struct {
909 single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),911 single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),
910 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),912 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
911 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),913 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
914 optional_noreturn_type = @intFromEnum(InternPool.Index.optional_noreturn_type),
912 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),915 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
913 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),916 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
914 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),917 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),
...@@ -1182,7 +1185,7 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {...@@ -1182,7 +1185,7 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {
1182 return air.extra[extra.end..][0..extra.data.body_len];1185 return air.extra[extra.end..][0..extra.data.body_len];
1183}1186}
11841187
1185pub fn typeOf(air: Air, inst: Air.Inst.Ref, ip: *const InternPool) Type {1188pub fn typeOf(air: *const Air, inst: Air.Inst.Ref, ip: *const InternPool) Type {
1186 const ref_int = @intFromEnum(inst);1189 const ref_int = @intFromEnum(inst);
1187 if (ref_int < InternPool.static_keys.len) {1190 if (ref_int < InternPool.static_keys.len) {
1188 return InternPool.static_keys[ref_int].typeOf().toType();1191 return InternPool.static_keys[ref_int].typeOf().toType();
...@@ -1190,7 +1193,7 @@ pub fn typeOf(air: Air, inst: Air.Inst.Ref, ip: *const InternPool) Type {...@@ -1190,7 +1193,7 @@ pub fn typeOf(air: Air, inst: Air.Inst.Ref, ip: *const InternPool) Type {
1190 return air.typeOfIndex(ref_int - ref_start_index, ip);1193 return air.typeOfIndex(ref_int - ref_start_index, ip);
1191}1194}
11921195
1193pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: *const InternPool) Type {1196pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) Type {
1194 const datas = air.instructions.items(.data);1197 const datas = air.instructions.items(.data);
1195 switch (air.instructions.items(.tag)[inst]) {1198 switch (air.instructions.items(.tag)[inst]) {
1196 .add,1199 .add,
...@@ -1403,7 +1406,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: *const InternPool) Type {...@@ -1403,7 +1406,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: *const InternPool) Type {
14031406
1404 .call, .call_always_tail, .call_never_tail, .call_never_inline => {1407 .call, .call_always_tail, .call_never_tail, .call_never_inline => {
1405 const callee_ty = air.typeOf(datas[inst].pl_op.operand, ip);1408 const callee_ty = air.typeOf(datas[inst].pl_op.operand, ip);
1406 return callee_ty.fnReturnTypeIp(ip);1409 return ip.funcReturnType(callee_ty.toIntern()).toType();
1407 },1410 },
14081411
1409 .slice_elem_val, .ptr_elem_val, .array_elem_val => {1412 .slice_elem_val, .ptr_elem_val, .array_elem_val => {
src/InternPool.zig+111-10
...@@ -620,6 +620,8 @@ pub const Key = union(enum) {...@@ -620,6 +620,8 @@ pub const Key = union(enum) {
620 len: Index = .none,620 len: Index = .none,
621621
622 pub const Addr = union(enum) {622 pub const Addr = union(enum) {
623 const Tag = @typeInfo(Addr).Union.tag_type.?;
624
623 decl: Module.Decl.Index,625 decl: Module.Decl.Index,
624 mut_decl: MutDecl,626 mut_decl: MutDecl,
625 comptime_field: Index,627 comptime_field: Index,
...@@ -1241,11 +1243,13 @@ pub const Item = struct {...@@ -1241,11 +1243,13 @@ pub const Item = struct {
1241/// When adding a tag to this enum, consider adding a corresponding entry to1243/// When adding a tag to this enum, consider adding a corresponding entry to
1242/// `primitives` in AstGen.zig.1244/// `primitives` in AstGen.zig.
1243pub const Index = enum(u32) {1245pub const Index = enum(u32) {
1244 pub const first_type: Index = .u1_type;1246 pub const first_type: Index = .u0_type;
1245 pub const last_type: Index = .empty_struct_type;1247 pub const last_type: Index = .empty_struct_type;
1246 pub const first_value: Index = .undef;1248 pub const first_value: Index = .undef;
1247 pub const last_value: Index = .empty_struct;1249 pub const last_value: Index = .empty_struct;
12481250
1251 u0_type,
1252 i0_type,
1249 u1_type,1253 u1_type,
1250 u8_type,1254 u8_type,
1251 i8_type,1255 i8_type,
...@@ -1305,6 +1309,7 @@ pub const Index = enum(u32) {...@@ -1305,6 +1309,7 @@ pub const Index = enum(u32) {
1305 single_const_pointer_to_comptime_int_type,1309 single_const_pointer_to_comptime_int_type,
1306 slice_const_u8_type,1310 slice_const_u8_type,
1307 slice_const_u8_sentinel_0_type,1311 slice_const_u8_sentinel_0_type,
1312 optional_noreturn_type,
1308 anyerror_void_error_union_type,1313 anyerror_void_error_union_type,
1309 generic_poison_type,1314 generic_poison_type,
1310 /// `@TypeOf(.{})`1315 /// `@TypeOf(.{})`
...@@ -1531,6 +1536,16 @@ pub const Index = enum(u32) {...@@ -1531,6 +1536,16 @@ pub const Index = enum(u32) {
1531};1536};
15321537
1533pub const static_keys = [_]Key{1538pub const static_keys = [_]Key{
1539 .{ .int_type = .{
1540 .signedness = .unsigned,
1541 .bits = 0,
1542 } },
1543
1544 .{ .int_type = .{
1545 .signedness = .signed,
1546 .bits = 0,
1547 } },
1548
1534 .{ .int_type = .{1549 .{ .int_type = .{
1535 .signedness = .unsigned,1550 .signedness = .unsigned,
1536 .bits = 1,1551 .bits = 1,
...@@ -1637,6 +1652,7 @@ pub const static_keys = [_]Key{...@@ -1637,6 +1652,7 @@ pub const static_keys = [_]Key{
1637 .{ .simple_type = .extern_options },1652 .{ .simple_type = .extern_options },
1638 .{ .simple_type = .type_info },1653 .{ .simple_type = .type_info },
16391654
1655 // [*]u8
1640 .{ .ptr_type = .{1656 .{ .ptr_type = .{
1641 .child = .u8_type,1657 .child = .u8_type,
1642 .flags = .{1658 .flags = .{
...@@ -1644,7 +1660,7 @@ pub const static_keys = [_]Key{...@@ -1644,7 +1660,7 @@ pub const static_keys = [_]Key{
1644 },1660 },
1645 } },1661 } },
16461662
1647 // manyptr_const_u8_type1663 // [*]const u8
1648 .{ .ptr_type = .{1664 .{ .ptr_type = .{
1649 .child = .u8_type,1665 .child = .u8_type,
1650 .flags = .{1666 .flags = .{
...@@ -1653,7 +1669,7 @@ pub const static_keys = [_]Key{...@@ -1653,7 +1669,7 @@ pub const static_keys = [_]Key{
1653 },1669 },
1654 } },1670 } },
16551671
1656 // manyptr_const_u8_sentinel_0_type1672 // [*:0]const u8
1657 .{ .ptr_type = .{1673 .{ .ptr_type = .{
1658 .child = .u8_type,1674 .child = .u8_type,
1659 .sentinel = .zero_u8,1675 .sentinel = .zero_u8,
...@@ -1663,6 +1679,7 @@ pub const static_keys = [_]Key{...@@ -1663,6 +1679,7 @@ pub const static_keys = [_]Key{
1663 },1679 },
1664 } },1680 } },
16651681
1682 // comptime_int
1666 .{ .ptr_type = .{1683 .{ .ptr_type = .{
1667 .child = .comptime_int_type,1684 .child = .comptime_int_type,
1668 .flags = .{1685 .flags = .{
...@@ -1671,7 +1688,7 @@ pub const static_keys = [_]Key{...@@ -1671,7 +1688,7 @@ pub const static_keys = [_]Key{
1671 },1688 },
1672 } },1689 } },
16731690
1674 // slice_const_u8_type1691 // []const u8
1675 .{ .ptr_type = .{1692 .{ .ptr_type = .{
1676 .child = .u8_type,1693 .child = .u8_type,
1677 .flags = .{1694 .flags = .{
...@@ -1680,7 +1697,7 @@ pub const static_keys = [_]Key{...@@ -1680,7 +1697,7 @@ pub const static_keys = [_]Key{
1680 },1697 },
1681 } },1698 } },
16821699
1683 // slice_const_u8_sentinel_0_type1700 // [:0]const u8
1684 .{ .ptr_type = .{1701 .{ .ptr_type = .{
1685 .child = .u8_type,1702 .child = .u8_type,
1686 .sentinel = .zero_u8,1703 .sentinel = .zero_u8,
...@@ -1690,7 +1707,10 @@ pub const static_keys = [_]Key{...@@ -1690,7 +1707,10 @@ pub const static_keys = [_]Key{
1690 },1707 },
1691 } },1708 } },
16921709
1693 // anyerror_void_error_union_type1710 // ?noreturn
1711 .{ .opt_type = .noreturn_type },
1712
1713 // anyerror!void
1694 .{ .error_union_type = .{1714 .{ .error_union_type = .{
1695 .error_set_type = .anyerror_type,1715 .error_set_type = .anyerror_type,
1696 .payload_type = .void_type,1716 .payload_type = .void_type,
...@@ -2279,8 +2299,9 @@ pub const Alignment = enum(u6) {...@@ -2279,8 +2299,9 @@ pub const Alignment = enum(u6) {
2279 return fromByteUnits(n);2299 return fromByteUnits(n);
2280 }2300 }
22812301
2282 pub fn min(a: Alignment, b: Alignment) Alignment {2302 pub fn order(lhs: Alignment, rhs: Alignment) std.math.Order {
2283 return @enumFromInt(Alignment, @min(@intFromEnum(a), @intFromEnum(b)));2303 assert(lhs != .none and rhs != .none);
2304 return std.math.order(@intFromEnum(lhs), @intFromEnum(rhs));
2284 }2305 }
2285};2306};
22862307
...@@ -5463,6 +5484,8 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -5463,6 +5484,8 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
5463 // An alternative would be to topological sort the static keys, but this would5484 // An alternative would be to topological sort the static keys, but this would
5464 // mean that the range of type indices would not be dense.5485 // mean that the range of type indices would not be dense.
5465 return switch (index) {5486 return switch (index) {
5487 .u0_type,
5488 .i0_type,
5466 .u1_type,5489 .u1_type,
5467 .u8_type,5490 .u8_type,
5468 .i8_type,5491 .i8_type,
...@@ -5522,6 +5545,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -5522,6 +5545,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
5522 .single_const_pointer_to_comptime_int_type,5545 .single_const_pointer_to_comptime_int_type,
5523 .slice_const_u8_type,5546 .slice_const_u8_type,
5524 .slice_const_u8_sentinel_0_type,5547 .slice_const_u8_sentinel_0_type,
5548 .optional_noreturn_type,
5525 .anyerror_void_error_union_type,5549 .anyerror_void_error_union_type,
5526 .generic_poison_type,5550 .generic_poison_type,
5527 .empty_struct_type,5551 .empty_struct_type,
...@@ -5669,20 +5693,96 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {...@@ -5669,20 +5693,96 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
5669 };5693 };
5670}5694}
56715695
5696pub fn funcReturnType(ip: *const InternPool, ty: Index) Index {
5697 const item = ip.items.get(@intFromEnum(ty));
5698 const child_item = switch (item.tag) {
5699 .type_pointer => ip.items.get(ip.extra.items[
5700 item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?
5701 ]),
5702 .type_function => item,
5703 else => unreachable,
5704 };
5705 assert(child_item.tag == .type_function);
5706 return @enumFromInt(Index, ip.extra.items[
5707 child_item.data + std.meta.fieldIndex(TypeFunction, "return_type").?
5708 ]);
5709}
5710
5672pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {5711pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
5673 return switch (ty) {5712 return switch (ty) {
5674 .noreturn_type => true,5713 .noreturn_type => true,
5675 else => switch (ip.indexToKey(ty)) {5714 else => switch (ip.items.items(.tag)[@intFromEnum(ty)]) {
5676 .error_set_type => |error_set_type| error_set_type.names.len == 0,5715 .type_error_set => ip.extra.items[ip.items.items(.data)[@intFromEnum(ty)] + std.meta.fieldIndex(ErrorSet, "names_len").?] == 0,
5677 else => false,5716 else => false,
5678 },5717 },
5679 };5718 };
5680}5719}
56815720
5721pub fn isUndef(ip: *const InternPool, val: Index) bool {
5722 return val == .undef or ip.items.items(.tag)[@intFromEnum(val)] == .undef;
5723}
5724
5725pub fn isRuntimeValue(ip: *const InternPool, val: Index) bool {
5726 return ip.items.items(.tag)[@intFromEnum(val)] == .runtime_value;
5727}
5728
5729pub fn isVariable(ip: *const InternPool, val: Index) bool {
5730 return ip.items.items(.tag)[@intFromEnum(val)] == .variable;
5731}
5732
5733pub fn getBackingDecl(ip: *const InternPool, val: Index) Module.Decl.OptionalIndex {
5734 var base = @intFromEnum(val);
5735 while (true) {
5736 switch (ip.items.items(.tag)[base]) {
5737 inline .ptr_decl,
5738 .ptr_mut_decl,
5739 => |tag| return @enumFromInt(Module.Decl.OptionalIndex, ip.extra.items[
5740 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "decl").?
5741 ]),
5742 inline .ptr_eu_payload,
5743 .ptr_opt_payload,
5744 .ptr_elem,
5745 .ptr_field,
5746 => |tag| base = ip.extra.items[
5747 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "base").?
5748 ],
5749 inline .ptr_slice => |tag| base = ip.extra.items[
5750 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "ptr").?
5751 ],
5752 else => return .none,
5753 }
5754 }
5755}
5756
5757pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.Addr.Tag {
5758 var base = @intFromEnum(val);
5759 while (true) {
5760 switch (ip.items.items(.tag)[base]) {
5761 .ptr_decl => return .decl,
5762 .ptr_mut_decl => return .mut_decl,
5763 .ptr_comptime_field => return .comptime_field,
5764 .ptr_int => return .int,
5765 inline .ptr_eu_payload,
5766 .ptr_opt_payload,
5767 .ptr_elem,
5768 .ptr_field,
5769 => |tag| base = ip.extra.items[
5770 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "base").?
5771 ],
5772 inline .ptr_slice => |tag| base = ip.extra.items[
5773 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "ptr").?
5774 ],
5775 else => return null,
5776 }
5777 }
5778}
5779
5682/// This is a particularly hot function, so we operate directly on encodings5780/// This is a particularly hot function, so we operate directly on encodings
5683/// rather than the more straightforward implementation of calling `indexToKey`.5781/// rather than the more straightforward implementation of calling `indexToKey`.
5684pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPoison}!std.builtin.TypeId {5782pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPoison}!std.builtin.TypeId {
5685 return switch (index) {5783 return switch (index) {
5784 .u0_type,
5785 .i0_type,
5686 .u1_type,5786 .u1_type,
5687 .u8_type,5787 .u8_type,
5688 .i8_type,5788 .i8_type,
...@@ -5754,6 +5854,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -5754,6 +5854,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
5754 .slice_const_u8_sentinel_0_type,5854 .slice_const_u8_sentinel_0_type,
5755 => .Pointer,5855 => .Pointer,
57565856
5857 .optional_noreturn_type => .Optional,
5757 .anyerror_void_error_union_type => .ErrorUnion,5858 .anyerror_void_error_union_type => .ErrorUnion,
5758 .empty_struct_type => .Struct,5859 .empty_struct_type => .Struct,
57595860
src/Module.zig+25-44
...@@ -33,6 +33,7 @@ const Liveness = @import("Liveness.zig");...@@ -33,6 +33,7 @@ const Liveness = @import("Liveness.zig");
33const isUpDir = @import("introspect.zig").isUpDir;33const isUpDir = @import("introspect.zig").isUpDir;
34const clang = @import("clang.zig");34const clang = @import("clang.zig");
35const InternPool = @import("InternPool.zig");35const InternPool = @import("InternPool.zig");
36const Alignment = InternPool.Alignment;
3637
37comptime {38comptime {
38 @setEvalBranchQuota(4000);39 @setEvalBranchQuota(4000);
...@@ -241,7 +242,7 @@ pub const MonomorphedFuncsAdaptedContext = struct {...@@ -241,7 +242,7 @@ pub const MonomorphedFuncsAdaptedContext = struct {
241};242};
242243
243pub const SetAlignStack = struct {244pub const SetAlignStack = struct {
244 alignment: u32,245 alignment: Alignment,
245 /// TODO: This needs to store a non-lazy source location for the case of an inline function246 /// TODO: This needs to store a non-lazy source location for the case of an inline function
246 /// which does `@setAlignStack` (applying it to the caller).247 /// which does `@setAlignStack` (applying it to the caller).
247 src: LazySrcLoc,248 src: LazySrcLoc,
...@@ -432,7 +433,7 @@ pub const Decl = struct {...@@ -432,7 +433,7 @@ pub const Decl = struct {
432 /// Populated when `has_tv`.433 /// Populated when `has_tv`.
433 @"linksection": InternPool.OptionalNullTerminatedString,434 @"linksection": InternPool.OptionalNullTerminatedString,
434 /// Populated when `has_tv`.435 /// Populated when `has_tv`.
435 @"align": u32,436 alignment: Alignment,
436 /// Populated when `has_tv`.437 /// Populated when `has_tv`.
437 @"addrspace": std.builtin.AddressSpace,438 @"addrspace": std.builtin.AddressSpace,
438 /// The direct parent namespace of the Decl.439 /// The direct parent namespace of the Decl.
...@@ -863,13 +864,7 @@ pub const Decl = struct {...@@ -863,13 +864,7 @@ pub const Decl = struct {
863864
864 pub fn getAlignment(decl: Decl, mod: *Module) u32 {865 pub fn getAlignment(decl: Decl, mod: *Module) u32 {
865 assert(decl.has_tv);866 assert(decl.has_tv);
866 if (decl.@"align" != 0) {867 return @intCast(u32, decl.alignment.toByteUnitsOptional() orelse decl.ty.abiAlignment(mod));
867 // Explicit alignment.
868 return decl.@"align";
869 } else {
870 // Natural alignment.
871 return decl.ty.abiAlignment(mod);
872 }
873 }868 }
874869
875 pub fn intern(decl: *Decl, mod: *Module) Allocator.Error!void {870 pub fn intern(decl: *Decl, mod: *Module) Allocator.Error!void {
...@@ -955,7 +950,7 @@ pub const Struct = struct {...@@ -955,7 +950,7 @@ pub const Struct = struct {
955 /// Uses `none` to indicate no default.950 /// Uses `none` to indicate no default.
956 default_val: InternPool.Index,951 default_val: InternPool.Index,
957 /// Zero means to use the ABI alignment of the type.952 /// Zero means to use the ABI alignment of the type.
958 abi_align: u32,953 abi_align: Alignment,
959 /// undefined until `status` is `have_layout`.954 /// undefined until `status` is `have_layout`.
960 offset: u32,955 offset: u32,
961 /// If true then `default_val` is the comptime field value.956 /// If true then `default_val` is the comptime field value.
...@@ -967,9 +962,9 @@ pub const Struct = struct {...@@ -967,9 +962,9 @@ pub const Struct = struct {
967 mod: *Module,962 mod: *Module,
968 layout: std.builtin.Type.ContainerLayout,963 layout: std.builtin.Type.ContainerLayout,
969 ) u32 {964 ) u32 {
970 if (field.abi_align != 0) {965 if (field.abi_align.toByteUnitsOptional()) |abi_align| {
971 assert(layout != .Packed);966 assert(layout != .Packed);
972 return field.abi_align;967 return @intCast(u32, abi_align);
973 }968 }
974969
975 const target = mod.getTarget();970 const target = mod.getTarget();
...@@ -1150,17 +1145,13 @@ pub const Union = struct {...@@ -1150,17 +1145,13 @@ pub const Union = struct {
1150 /// undefined until `status` is `have_field_types` or `have_layout`.1145 /// undefined until `status` is `have_field_types` or `have_layout`.
1151 ty: Type,1146 ty: Type,
1152 /// 0 means the ABI alignment of the type.1147 /// 0 means the ABI alignment of the type.
1153 abi_align: u32,1148 abi_align: Alignment,
11541149
1155 /// Returns the field alignment, assuming the union is not packed.1150 /// Returns the field alignment, assuming the union is not packed.
1156 /// Keep implementation in sync with `Sema.unionFieldAlignment`.1151 /// Keep implementation in sync with `Sema.unionFieldAlignment`.
1157 /// Prefer to call that function instead of this one during Sema.1152 /// Prefer to call that function instead of this one during Sema.
1158 pub fn normalAlignment(field: Field, mod: *Module) u32 {1153 pub fn normalAlignment(field: Field, mod: *Module) u32 {
1159 if (field.abi_align == 0) {1154 return @intCast(u32, field.abi_align.toByteUnitsOptional() orelse field.ty.abiAlignment(mod));
1160 return field.ty.abiAlignment(mod);
1161 } else {
1162 return field.abi_align;
1163 }
1164 }1155 }
1165 };1156 };
11661157
...@@ -1272,20 +1263,14 @@ pub const Union = struct {...@@ -1272,20 +1263,14 @@ pub const Union = struct {
1272 for (fields, 0..) |field, i| {1263 for (fields, 0..) |field, i| {
1273 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;1264 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
12741265
1275 const field_align = a: {1266 const field_align = field.abi_align.toByteUnitsOptional() orelse field.ty.abiAlignment(mod);
1276 if (field.abi_align == 0) {
1277 break :a field.ty.abiAlignment(mod);
1278 } else {
1279 break :a field.abi_align;
1280 }
1281 };
1282 const field_size = field.ty.abiSize(mod);1267 const field_size = field.ty.abiSize(mod);
1283 if (field_size > payload_size) {1268 if (field_size > payload_size) {
1284 payload_size = field_size;1269 payload_size = field_size;
1285 biggest_field = @intCast(u32, i);1270 biggest_field = @intCast(u32, i);
1286 }1271 }
1287 if (field_align > payload_align) {1272 if (field_align > payload_align) {
1288 payload_align = field_align;1273 payload_align = @intCast(u32, field_align);
1289 most_aligned_field = @intCast(u32, i);1274 most_aligned_field = @intCast(u32, i);
1290 most_aligned_field_size = field_size;1275 most_aligned_field_size = field_size;
1291 }1276 }
...@@ -4394,7 +4379,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -4394,7 +4379,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4394 new_decl.has_linksection_or_addrspace = false;4379 new_decl.has_linksection_or_addrspace = false;
4395 new_decl.ty = Type.type;4380 new_decl.ty = Type.type;
4396 new_decl.val = struct_ty.toValue();4381 new_decl.val = struct_ty.toValue();
4397 new_decl.@"align" = 0;4382 new_decl.alignment = .none;
4398 new_decl.@"linksection" = .none;4383 new_decl.@"linksection" = .none;
4399 new_decl.has_tv = true;4384 new_decl.has_tv = true;
4400 new_decl.owns_tv = true;4385 new_decl.owns_tv = true;
...@@ -4584,7 +4569,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4584,7 +4569,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45844569
4585 decl.ty = InternPool.Index.type_type.toType();4570 decl.ty = InternPool.Index.type_type.toType();
4586 decl.val = ty.toValue();4571 decl.val = ty.toValue();
4587 decl.@"align" = 0;4572 decl.alignment = .none;
4588 decl.@"linksection" = .none;4573 decl.@"linksection" = .none;
4589 decl.has_tv = true;4574 decl.has_tv = true;
4590 decl.owns_tv = false;4575 decl.owns_tv = false;
...@@ -4665,9 +4650,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4665,9 +4650,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
46654650
4666 decl.ty = decl_tv.ty;4651 decl.ty = decl_tv.ty;
4667 decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();4652 decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();
4668 decl.@"align" = blk: {4653 decl.alignment = blk: {
4669 const align_ref = decl.zirAlignRef(mod);4654 const align_ref = decl.zirAlignRef(mod);
4670 if (align_ref == .none) break :blk 0;4655 if (align_ref == .none) break :blk .none;
4671 break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);4656 break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);
4672 };4657 };
4673 decl.@"linksection" = blk: {4658 decl.@"linksection" = blk: {
...@@ -5758,7 +5743,7 @@ pub fn allocateNewDecl(...@@ -5758,7 +5743,7 @@ pub fn allocateNewDecl(
5758 .owns_tv = false,5743 .owns_tv = false,
5759 .ty = undefined,5744 .ty = undefined,
5760 .val = undefined,5745 .val = undefined,
5761 .@"align" = undefined,5746 .alignment = undefined,
5762 .@"linksection" = .none,5747 .@"linksection" = .none,
5763 .@"addrspace" = .generic,5748 .@"addrspace" = .generic,
5764 .analysis = .unreferenced,5749 .analysis = .unreferenced,
...@@ -5830,7 +5815,7 @@ pub fn initNewAnonDecl(...@@ -5830,7 +5815,7 @@ pub fn initNewAnonDecl(
5830 new_decl.src_line = src_line;5815 new_decl.src_line = src_line;
5831 new_decl.ty = typed_value.ty;5816 new_decl.ty = typed_value.ty;
5832 new_decl.val = typed_value.val;5817 new_decl.val = typed_value.val;
5833 new_decl.@"align" = 0;5818 new_decl.alignment = .none;
5834 new_decl.@"linksection" = .none;5819 new_decl.@"linksection" = .none;
5835 new_decl.has_tv = true;5820 new_decl.has_tv = true;
5836 new_decl.analysis = .complete;5821 new_decl.analysis = .complete;
...@@ -6773,13 +6758,9 @@ pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {...@@ -6773,13 +6758,9 @@ pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
6773}6758}
67746759
6775pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {6760pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
6776 const info = Type.ptrInfoIp(&mod.intern_pool, ptr_ty.toIntern());6761 var info = ptr_ty.ptrInfo(mod);
6777 return mod.ptrType(.{6762 info.child = new_child.toIntern();
6778 .child = new_child.toIntern(),6763 return mod.ptrType(info);
6779 .sentinel = info.sentinel,
6780 .flags = info.flags,
6781 .packed_offset = info.packed_offset,
6782 });
6783}6764}
67846765
6785pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type {6766pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type {
...@@ -7018,7 +6999,7 @@ pub fn atomicPtrAlignment(...@@ -7018,7 +6999,7 @@ pub fn atomicPtrAlignment(
7018 mod: *Module,6999 mod: *Module,
7019 ty: Type,7000 ty: Type,
7020 diags: *AtomicPtrAlignmentDiagnostics,7001 diags: *AtomicPtrAlignmentDiagnostics,
7021) AtomicPtrAlignmentError!u32 {7002) AtomicPtrAlignmentError!Alignment {
7022 const target = mod.getTarget();7003 const target = mod.getTarget();
7023 const max_atomic_bits: u16 = switch (target.cpu.arch) {7004 const max_atomic_bits: u16 = switch (target.cpu.arch) {
7024 .avr,7005 .avr,
...@@ -7104,11 +7085,11 @@ pub fn atomicPtrAlignment(...@@ -7104,11 +7085,11 @@ pub fn atomicPtrAlignment(
7104 };7085 };
7105 return error.FloatTooBig;7086 return error.FloatTooBig;
7106 }7087 }
7107 return 0;7088 return .none;
7108 },7089 },
7109 .Bool => return 0,7090 .Bool => return .none,
7110 else => {7091 else => {
7111 if (ty.isPtrAtRuntime(mod)) return 0;7092 if (ty.isPtrAtRuntime(mod)) return .none;
7112 return error.BadType;7093 return error.BadType;
7113 },7094 },
7114 };7095 };
...@@ -7122,7 +7103,7 @@ pub fn atomicPtrAlignment(...@@ -7122,7 +7103,7 @@ pub fn atomicPtrAlignment(
7122 return error.IntTooBig;7103 return error.IntTooBig;
7123 }7104 }
71247105
7125 return 0;7106 return .none;
7126}7107}
71277108
7128pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc {7109pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc {
src/Sema.zig+1048-915
...@@ -126,6 +126,7 @@ const crash_report = @import("crash_report.zig");...@@ -126,6 +126,7 @@ const crash_report = @import("crash_report.zig");
126const build_options = @import("build_options");126const build_options = @import("build_options");
127const Compilation = @import("Compilation.zig");127const Compilation = @import("Compilation.zig");
128const InternPool = @import("InternPool.zig");128const InternPool = @import("InternPool.zig");
129const Alignment = InternPool.Alignment;
129130
130pub const default_branch_quota = 1000;131pub const default_branch_quota = 1000;
131pub const default_reference_trace_len = 2;132pub const default_reference_trace_len = 2;
...@@ -708,7 +709,7 @@ pub const Block = struct {...@@ -708,7 +709,7 @@ pub const Block = struct {
708 }709 }
709710
710 /// `alignment` value of 0 means to use ABI alignment.711 /// `alignment` value of 0 means to use ABI alignment.
711 pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: u64) !Decl.Index {712 pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: Alignment) !Decl.Index {
712 const sema = wad.block.sema;713 const sema = wad.block.sema;
713 // Do this ahead of time because `createAnonymousDecl` depends on calling714 // Do this ahead of time because `createAnonymousDecl` depends on calling
714 // `type.hasRuntimeBits()`.715 // `type.hasRuntimeBits()`.
...@@ -718,8 +719,7 @@ pub const Block = struct {...@@ -718,8 +719,7 @@ pub const Block = struct {
718 .val = val,719 .val = val,
719 });720 });
720 const new_decl = sema.mod.declPtr(new_decl_index);721 const new_decl = sema.mod.declPtr(new_decl_index);
721 // TODO: migrate Decl alignment to use `InternPool.Alignment`722 new_decl.alignment = alignment;
722 new_decl.@"align" = @intCast(u32, alignment);
723 errdefer sema.mod.abortAnonDecl(new_decl_index);723 errdefer sema.mod.abortAnonDecl(new_decl_index);
724 wad.finished = true;724 wad.finished = true;
725 try sema.mod.finalizeAnonDecl(new_decl_index);725 try sema.mod.finalizeAnonDecl(new_decl_index);
...@@ -1847,7 +1847,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -1847,7 +1847,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
18471847
1848 // var addrs: [err_return_trace_addr_count]usize = undefined;1848 // var addrs: [err_return_trace_addr_count]usize = undefined;
1849 const err_return_trace_addr_count = 32;1849 const err_return_trace_addr_count = 32;
1850 const addr_arr_ty = try Type.array(sema.arena, err_return_trace_addr_count, null, Type.usize, mod);1850 const addr_arr_ty = try mod.arrayType(.{
1851 .len = err_return_trace_addr_count,
1852 .child = .usize_type,
1853 });
1851 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));1854 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));
18521855
1853 // var st: StackTrace = undefined;1856 // var st: StackTrace = undefined;
...@@ -1898,13 +1901,10 @@ fn resolveConstMaybeUndefVal(...@@ -1898,13 +1901,10 @@ fn resolveConstMaybeUndefVal(
1898 reason: []const u8,1901 reason: []const u8,
1899) CompileError!Value {1902) CompileError!Value {
1900 if (try sema.resolveMaybeUndefValAllowVariables(inst)) |val| {1903 if (try sema.resolveMaybeUndefValAllowVariables(inst)) |val| {
1901 switch (val.toIntern()) {1904 if (val.isGenericPoison()) return error.GenericPoison;
1902 .generic_poison => return error.GenericPoison,1905 if (sema.mod.intern_pool.isVariable(val.toIntern()))
1903 else => switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {1906 return sema.failWithNeededComptime(block, src, reason);
1904 .variable => return sema.failWithNeededComptime(block, src, reason),1907 return val;
1905 else => return val,
1906 },
1907 }
1908 }1908 }
1909 return sema.failWithNeededComptime(block, src, reason);1909 return sema.failWithNeededComptime(block, src, reason);
1910}1910}
...@@ -1919,15 +1919,11 @@ fn resolveConstValue(...@@ -1919,15 +1919,11 @@ fn resolveConstValue(
1919 reason: []const u8,1919 reason: []const u8,
1920) CompileError!Value {1920) CompileError!Value {
1921 if (try sema.resolveMaybeUndefValAllowVariables(air_ref)) |val| {1921 if (try sema.resolveMaybeUndefValAllowVariables(air_ref)) |val| {
1922 switch (val.toIntern()) {1922 if (val.isGenericPoison()) return error.GenericPoison;
1923 .generic_poison => return error.GenericPoison,1923 if (val.isUndef(sema.mod)) return sema.failWithUseOfUndef(block, src);
1924 .undef => return sema.failWithUseOfUndef(block, src),1924 if (sema.mod.intern_pool.isVariable(val.toIntern()))
1925 else => switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {1925 return sema.failWithNeededComptime(block, src, reason);
1926 .undef => return sema.failWithUseOfUndef(block, src),1926 return val;
1927 .variable => return sema.failWithNeededComptime(block, src, reason),
1928 else => return val,
1929 },
1930 }
1931 }1927 }
1932 return sema.failWithNeededComptime(block, src, reason);1928 return sema.failWithNeededComptime(block, src, reason);
1933}1929}
...@@ -1971,14 +1967,9 @@ fn resolveMaybeUndefVal(...@@ -1971,14 +1967,9 @@ fn resolveMaybeUndefVal(
1971 inst: Air.Inst.Ref,1967 inst: Air.Inst.Ref,
1972) CompileError!?Value {1968) CompileError!?Value {
1973 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;1969 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
1974 switch (val.ip_index) {1970 if (val.isGenericPoison()) return error.GenericPoison;
1975 .generic_poison => return error.GenericPoison,1971 if (val.ip_index != .none and sema.mod.intern_pool.isVariable(val.toIntern())) return null;
1976 .none => return val,1972 return val;
1977 else => switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {
1978 .variable => return null,
1979 else => return val,
1980 },
1981 }
1982}1973}
19831974
1984/// Value Tag `variable` causes this function to return `null`.1975/// Value Tag `variable` causes this function to return `null`.
...@@ -2002,20 +1993,13 @@ fn resolveMaybeUndefValIntable(...@@ -2002,20 +1993,13 @@ fn resolveMaybeUndefValIntable(
2002 inst: Air.Inst.Ref,1993 inst: Air.Inst.Ref,
2003) CompileError!?Value {1994) CompileError!?Value {
2004 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;1995 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
2005 var check = val;1996 if (val.isGenericPoison()) return error.GenericPoison;
2006 while (true) switch (check.ip_index) {1997 if (val.ip_index == .none) return val;
2007 .generic_poison => return error.GenericPoison,1998 if (sema.mod.intern_pool.isVariable(val.toIntern())) return null;
2008 .none => break,1999 if (sema.mod.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) {
2009 else => switch (sema.mod.intern_pool.indexToKey(check.toIntern())) {2000 .decl, .mut_decl, .comptime_field => return null,
2010 .variable => return null,2001 .int => {},
2011 .ptr => |ptr| switch (ptr.addr) {2002 .eu_payload, .opt_payload, .elem, .field => unreachable,
2012 .decl, .mut_decl, .comptime_field => return null,
2013 .int => break,
2014 .eu_payload, .opt_payload => |base| check = base.toValue(),
2015 .elem, .field => |base_index| check = base_index.base.toValue(),
2016 },
2017 else => break,
2018 },
2019 };2003 };
2020 return try sema.resolveLazyValue(val);2004 return try sema.resolveLazyValue(val);
2021}2005}
...@@ -2211,9 +2195,9 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool....@@ -2211,9 +2195,9 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.
2211 .Array => return ip.stringEqlSlice(field_name, "len"),2195 .Array => return ip.stringEqlSlice(field_name, "len"),
2212 .Pointer => {2196 .Pointer => {
2213 const ptr_info = ty.ptrInfo(mod);2197 const ptr_info = ty.ptrInfo(mod);
2214 if (ptr_info.size == .Slice) {2198 if (ptr_info.flags.size == .Slice) {
2215 return ip.stringEqlSlice(field_name, "ptr") or ip.stringEqlSlice(field_name, "len");2199 return ip.stringEqlSlice(field_name, "ptr") or ip.stringEqlSlice(field_name, "len");
2216 } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {2200 } else if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
2217 return ip.stringEqlSlice(field_name, "len");2201 return ip.stringEqlSlice(field_name, "len");
2218 } else return false;2202 } else return false;
2219 },2203 },
...@@ -2427,11 +2411,11 @@ fn analyzeAsAlign(...@@ -2427,11 +2411,11 @@ fn analyzeAsAlign(
2427 block: *Block,2411 block: *Block,
2428 src: LazySrcLoc,2412 src: LazySrcLoc,
2429 air_ref: Air.Inst.Ref,2413 air_ref: Air.Inst.Ref,
2430) !u32 {2414) !Alignment {
2431 const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, "alignment must be comptime-known");2415 const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, "alignment must be comptime-known");
2432 const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line.2416 const alignment = @intCast(u32, alignment_big); // We coerce to u29 in the prev line.
2433 try sema.validateAlign(block, src, alignment);2417 try sema.validateAlign(block, src, alignment);
2434 return alignment;2418 return Alignment.fromNonzeroByteUnits(alignment);
2435}2419}
24362420
2437fn validateAlign(2421fn validateAlign(
...@@ -2453,7 +2437,7 @@ pub fn resolveAlign(...@@ -2453,7 +2437,7 @@ pub fn resolveAlign(
2453 block: *Block,2437 block: *Block,
2454 src: LazySrcLoc,2438 src: LazySrcLoc,
2455 zir_ref: Zir.Inst.Ref,2439 zir_ref: Zir.Inst.Ref,
2456) !u32 {2440) !Alignment {
2457 const air_ref = try sema.resolveInst(zir_ref);2441 const air_ref = try sema.resolveInst(zir_ref);
2458 return sema.analyzeAsAlign(block, src, air_ref);2442 return sema.analyzeAsAlign(block, src, air_ref);
2459}2443}
...@@ -2569,7 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2569,7 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2569 const decl_index = try anon_decl.finish(2553 const decl_index = try anon_decl.finish(
2570 pointee_ty,2554 pointee_ty,
2571 (try mod.intern(.{ .undef = pointee_ty.toIntern() })).toValue(),2555 (try mod.intern(.{ .undef = pointee_ty.toIntern() })).toValue(),
2572 alignment.toByteUnits(0),2556 alignment,
2573 );2557 );
2574 sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index;2558 sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index;
2575 if (alignment != .none) {2559 if (alignment != .none) {
...@@ -2645,9 +2629,9 @@ fn coerceResultPtr(...@@ -2645,9 +2629,9 @@ fn coerceResultPtr(
2645 }2629 }
2646 }2630 }
26472631
2648 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{2632 const ptr_ty = try mod.ptrType(.{
2649 .pointee_type = pointee_ty,2633 .child = pointee_ty.toIntern(),
2650 .@"addrspace" = addr_space,2634 .flags = .{ .address_space = addr_space },
2651 });2635 });
26522636
2653 var new_ptr = ptr;2637 var new_ptr = ptr;
...@@ -2675,9 +2659,9 @@ fn coerceResultPtr(...@@ -2675,9 +2659,9 @@ fn coerceResultPtr(
2675 // Array coerced to Vector where element size is not equal but coercible.2659 // Array coerced to Vector where element size is not equal but coercible.
2676 .aggregate_init => {2660 .aggregate_init => {
2677 const ty_pl = air_datas[trash_inst].ty_pl;2661 const ty_pl = air_datas[trash_inst].ty_pl;
2678 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{2662 const ptr_operand_ty = try mod.ptrType(.{
2679 .pointee_type = try sema.analyzeAsType(block, src, ty_pl.ty),2663 .child = (try sema.analyzeAsType(block, src, ty_pl.ty)).toIntern(),
2680 .@"addrspace" = addr_space,2664 .flags = .{ .address_space = addr_space },
2681 });2665 });
26822666
2683 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {2667 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
...@@ -2689,9 +2673,9 @@ fn coerceResultPtr(...@@ -2689,9 +2673,9 @@ fn coerceResultPtr(
2689 .bitcast => {2673 .bitcast => {
2690 const ty_op = air_datas[trash_inst].ty_op;2674 const ty_op = air_datas[trash_inst].ty_op;
2691 const operand_ty = sema.typeOf(ty_op.operand);2675 const operand_ty = sema.typeOf(ty_op.operand);
2692 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{2676 const ptr_operand_ty = try mod.ptrType(.{
2693 .pointee_type = operand_ty,2677 .child = operand_ty.toIntern(),
2694 .@"addrspace" = addr_space,2678 .flags = .{ .address_space = addr_space },
2695 });2679 });
2696 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {2680 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
2697 new_ptr = try sema.addConstant(ptr_operand_ty, try mod.getCoerced(ptr_val, ptr_operand_ty));2681 new_ptr = try sema.addConstant(ptr_operand_ty, try mod.getCoerced(ptr_val, ptr_operand_ty));
...@@ -3401,13 +3385,13 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -3401,13 +3385,13 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
34013385
3402 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {3386 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
3403 const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty);3387 const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty);
3404 return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0);3388 return sema.analyzeComptimeAlloc(block, fn_ret_ty, .none);
3405 }3389 }
34063390
3407 const target = sema.mod.getTarget();3391 const target = sema.mod.getTarget();
3408 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{3392 const ptr_type = try sema.mod.ptrType(.{
3409 .pointee_type = sema.fn_ret_ty,3393 .child = sema.fn_ret_ty.toIntern(),
3410 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3394 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3411 });3395 });
34123396
3413 if (block.inlining != null) {3397 if (block.inlining != null) {
...@@ -3579,12 +3563,12 @@ fn zirAllocExtended(...@@ -3579,12 +3563,12 @@ fn zirAllocExtended(
3579 break :blk try sema.resolveType(block, ty_src, type_ref);3563 break :blk try sema.resolveType(block, ty_src, type_ref);
3580 } else undefined;3564 } else undefined;
35813565
3582 const alignment: u32 = if (small.has_align) blk: {3566 const alignment = if (small.has_align) blk: {
3583 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);3567 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);
3584 extra_index += 1;3568 extra_index += 1;
3585 const alignment = try sema.resolveAlign(block, align_src, align_ref);3569 const alignment = try sema.resolveAlign(block, align_src, align_ref);
3586 break :blk alignment;3570 break :blk alignment;
3587 } else 0;3571 } else .none;
35883572
3589 if (block.is_comptime or small.is_comptime) {3573 if (block.is_comptime or small.is_comptime) {
3590 if (small.has_type) {3574 if (small.has_type) {
...@@ -3594,7 +3578,7 @@ fn zirAllocExtended(...@@ -3594,7 +3578,7 @@ fn zirAllocExtended(
3594 .tag = .inferred_alloc_comptime,3578 .tag = .inferred_alloc_comptime,
3595 .data = .{ .inferred_alloc_comptime = .{3579 .data = .{ .inferred_alloc_comptime = .{
3596 .decl_index = undefined,3580 .decl_index = undefined,
3597 .alignment = InternPool.Alignment.fromByteUnits(alignment),3581 .alignment = alignment,
3598 .is_const = small.is_const,3582 .is_const = small.is_const,
3599 } },3583 } },
3600 });3584 });
...@@ -3608,10 +3592,12 @@ fn zirAllocExtended(...@@ -3608,10 +3592,12 @@ fn zirAllocExtended(
3608 }3592 }
3609 const target = sema.mod.getTarget();3593 const target = sema.mod.getTarget();
3610 try sema.resolveTypeLayout(var_ty);3594 try sema.resolveTypeLayout(var_ty);
3611 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{3595 const ptr_type = try sema.mod.ptrType(.{
3612 .pointee_type = var_ty,3596 .child = var_ty.toIntern(),
3613 .@"align" = alignment,3597 .flags = .{
3614 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3598 .alignment = alignment,
3599 .address_space = target_util.defaultAddressSpace(target, .local),
3600 },
3615 });3601 });
3616 return block.addTy(.alloc, ptr_type);3602 return block.addTy(.alloc, ptr_type);
3617 }3603 }
...@@ -3619,7 +3605,7 @@ fn zirAllocExtended(...@@ -3619,7 +3605,7 @@ fn zirAllocExtended(
3619 const result_index = try block.addInstAsIndex(.{3605 const result_index = try block.addInstAsIndex(.{
3620 .tag = .inferred_alloc,3606 .tag = .inferred_alloc,
3621 .data = .{ .inferred_alloc = .{3607 .data = .{ .inferred_alloc = .{
3622 .alignment = InternPool.Alignment.fromByteUnits(alignment),3608 .alignment = alignment,
3623 .is_const = small.is_const,3609 .is_const = small.is_const,
3624 } },3610 } },
3625 });3611 });
...@@ -3634,7 +3620,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -3634,7 +3620,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
3634 const inst_data = sema.code.instructions.items(.data)[inst].un_node;3620 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
3635 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };3621 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
3636 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3622 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3637 return sema.analyzeComptimeAlloc(block, var_ty, 0);3623 return sema.analyzeComptimeAlloc(block, var_ty, .none);
3638}3624}
36393625
3640fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {3626fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -3644,7 +3630,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3644,7 +3630,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3644 const alloc_ty = sema.typeOf(alloc);3630 const alloc_ty = sema.typeOf(alloc);
36453631
3646 var ptr_info = alloc_ty.ptrInfo(mod);3632 var ptr_info = alloc_ty.ptrInfo(mod);
3647 const elem_ty = ptr_info.pointee_type;3633 const elem_ty = ptr_info.child.toType();
36483634
3649 // Detect if all stores to an `.alloc` were comptime-known.3635 // Detect if all stores to an `.alloc` were comptime-known.
3650 ct: {3636 ct: {
...@@ -3688,11 +3674,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3688,11 +3674,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
36883674
3689 var anon_decl = try block.startAnonDecl();3675 var anon_decl = try block.startAnonDecl();
3690 defer anon_decl.deinit();3676 defer anon_decl.deinit();
3691 return sema.analyzeDeclRef(try anon_decl.finish(3677 return sema.analyzeDeclRef(try anon_decl.finish(elem_ty, store_val, ptr_info.flags.alignment));
3692 elem_ty,
3693 store_val,
3694 ptr_info.@"align",
3695 ));
3696 }3678 }
36973679
3698 return sema.makePtrConst(block, alloc);3680 return sema.makePtrConst(block, alloc);
...@@ -3703,8 +3685,8 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai...@@ -3703,8 +3685,8 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
3703 const alloc_ty = sema.typeOf(alloc);3685 const alloc_ty = sema.typeOf(alloc);
37043686
3705 var ptr_info = alloc_ty.ptrInfo(mod);3687 var ptr_info = alloc_ty.ptrInfo(mod);
3706 ptr_info.mutable = false;3688 ptr_info.flags.is_const = true;
3707 const const_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);3689 const const_ptr_ty = try mod.ptrType(ptr_info);
37083690
3709 // Detect if a comptime value simply needs to have its type changed.3691 // Detect if a comptime value simply needs to have its type changed.
3710 if (try sema.resolveMaybeUndefVal(alloc)) |val| {3692 if (try sema.resolveMaybeUndefVal(alloc)) |val| {
...@@ -3743,12 +3725,12 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -3743,12 +3725,12 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
3743 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };3725 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
3744 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3726 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3745 if (block.is_comptime) {3727 if (block.is_comptime) {
3746 return sema.analyzeComptimeAlloc(block, var_ty, 0);3728 return sema.analyzeComptimeAlloc(block, var_ty, .none);
3747 }3729 }
3748 const target = sema.mod.getTarget();3730 const target = sema.mod.getTarget();
3749 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{3731 const ptr_type = try sema.mod.ptrType(.{
3750 .pointee_type = var_ty,3732 .child = var_ty.toIntern(),
3751 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3733 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3752 });3734 });
3753 try sema.queueFullTypeResolution(var_ty);3735 try sema.queueFullTypeResolution(var_ty);
3754 return block.addTy(.alloc, ptr_type);3736 return block.addTy(.alloc, ptr_type);
...@@ -3762,13 +3744,13 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -3762,13 +3744,13 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
3762 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };3744 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
3763 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3745 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3764 if (block.is_comptime) {3746 if (block.is_comptime) {
3765 return sema.analyzeComptimeAlloc(block, var_ty, 0);3747 return sema.analyzeComptimeAlloc(block, var_ty, .none);
3766 }3748 }
3767 try sema.validateVarType(block, ty_src, var_ty, false);3749 try sema.validateVarType(block, ty_src, var_ty, false);
3768 const target = sema.mod.getTarget();3750 const target = sema.mod.getTarget();
3769 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{3751 const ptr_type = try sema.mod.ptrType(.{
3770 .pointee_type = var_ty,3752 .child = var_ty.toIntern(),
3771 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3753 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3772 });3754 });
3773 try sema.queueFullTypeResolution(var_ty);3755 try sema.queueFullTypeResolution(var_ty);
3774 return block.addTy(.alloc, ptr_type);3756 return block.addTy(.alloc, ptr_type);
...@@ -3934,11 +3916,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3934,11 +3916,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3934 const new_decl_index = d: {3916 const new_decl_index = d: {
3935 var anon_decl = try block.startAnonDecl();3917 var anon_decl = try block.startAnonDecl();
3936 defer anon_decl.deinit();3918 defer anon_decl.deinit();
3937 const new_decl_index = try anon_decl.finish(3919 const new_decl_index = try anon_decl.finish(final_elem_ty, store_val, ia1.alignment);
3938 final_elem_ty,
3939 store_val,
3940 ia1.alignment.toByteUnits(0),
3941 );
3942 break :d new_decl_index;3920 break :d new_decl_index;
3943 };3921 };
3944 try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index);3922 try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index);
...@@ -5162,11 +5140,7 @@ fn storeToInferredAllocComptime(...@@ -5162,11 +5140,7 @@ fn storeToInferredAllocComptime(
5162 if (operand_val.getVariable(sema.mod) != null) break :store;5140 if (operand_val.getVariable(sema.mod) != null) break :store;
5163 var anon_decl = try block.startAnonDecl();5141 var anon_decl = try block.startAnonDecl();
5164 defer anon_decl.deinit();5142 defer anon_decl.deinit();
5165 iac.decl_index = try anon_decl.finish(5143 iac.decl_index = try anon_decl.finish(operand_ty, operand_val, iac.alignment);
5166 operand_ty,
5167 operand_val,
5168 iac.alignment.toByteUnits(0),
5169 );
5170 try sema.comptime_mutable_decls.append(iac.decl_index);5144 try sema.comptime_mutable_decls.append(iac.decl_index);
5171 return;5145 return;
5172 }5146 }
...@@ -5247,8 +5221,8 @@ fn addStrLit(sema: *Sema, block: *Block, bytes: []const u8) CompileError!Air.Ins...@@ -5247,8 +5221,8 @@ fn addStrLit(sema: *Sema, block: *Block, bytes: []const u8) CompileError!Air.Ins
5247 const duped_bytes = try sema.arena.dupe(u8, bytes);5221 const duped_bytes = try sema.arena.dupe(u8, bytes);
5248 const ty = try mod.arrayType(.{5222 const ty = try mod.arrayType(.{
5249 .len = bytes.len,5223 .len = bytes.len,
5250 .child = .u8_type,
5251 .sentinel = .zero_u8,5224 .sentinel = .zero_u8,
5225 .child = .u8_type,
5252 });5226 });
5253 const val = try mod.intern(.{ .aggregate = .{5227 const val = try mod.intern(.{ .aggregate = .{
5254 .ty = ty.toIntern(),5228 .ty = ty.toIntern(),
...@@ -5859,11 +5833,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5859,11 +5833,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
5859 const decl_index = if (operand.val.getFunction(sema.mod)) |function| function.owner_decl else blk: {5833 const decl_index = if (operand.val.getFunction(sema.mod)) |function| function.owner_decl else blk: {
5860 var anon_decl = try block.startAnonDecl();5834 var anon_decl = try block.startAnonDecl();
5861 defer anon_decl.deinit();5835 defer anon_decl.deinit();
5862 break :blk try anon_decl.finish(5836 break :blk try anon_decl.finish(operand.ty, operand.val, .none);
5863 operand.ty,
5864 operand.val,
5865 0,
5866 );
5867 };5837 };
5868 try sema.analyzeExport(block, src, options, decl_index);5838 try sema.analyzeExport(block, src, options, decl_index);
5869}5839}
...@@ -5948,9 +5918,9 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -5948,9 +5918,9 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
5948 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };5918 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
5949 const src = LazySrcLoc.nodeOffset(extra.node);5919 const src = LazySrcLoc.nodeOffset(extra.node);
5950 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);5920 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
5951 if (alignment > 256) {5921 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
5952 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{5922 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
5953 alignment,5923 alignment.toByteUnitsOptional().?,
5954 });5924 });
5955 }5925 }
5956 const func_index = sema.func_index.unwrap() orelse5926 const func_index = sema.func_index.unwrap() orelse
...@@ -6585,8 +6555,8 @@ fn checkCallArgumentCount(...@@ -6585,8 +6555,8 @@ fn checkCallArgumentCount(
6585 .Fn => break :func_ty callee_ty,6555 .Fn => break :func_ty callee_ty,
6586 .Pointer => {6556 .Pointer => {
6587 const ptr_info = callee_ty.ptrInfo(mod);6557 const ptr_info = callee_ty.ptrInfo(mod);
6588 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {6558 if (ptr_info.flags.size == .One and ptr_info.child.toType().zigTypeTag(mod) == .Fn) {
6589 break :func_ty ptr_info.pointee_type;6559 break :func_ty ptr_info.child.toType();
6590 }6560 }
6591 },6561 },
6592 .Optional => {6562 .Optional => {
...@@ -6657,8 +6627,8 @@ fn callBuiltin(...@@ -6657,8 +6627,8 @@ fn callBuiltin(
6657 .Fn => break :func_ty callee_ty,6627 .Fn => break :func_ty callee_ty,
6658 .Pointer => {6628 .Pointer => {
6659 const ptr_info = callee_ty.ptrInfo(mod);6629 const ptr_info = callee_ty.ptrInfo(mod);
6660 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {6630 if (ptr_info.flags.size == .One and ptr_info.child.toType().zigTypeTag(mod) == .Fn) {
6661 break :func_ty ptr_info.pointee_type;6631 break :func_ty ptr_info.child.toType();
6662 }6632 }
6663 },6633 },
6664 else => {},6634 else => {},
...@@ -7896,7 +7866,7 @@ fn resolveGenericInstantiationType(...@@ -7896,7 +7866,7 @@ fn resolveGenericInstantiationType(
7896 .ty = new_decl.ty.toIntern(),7866 .ty = new_decl.ty.toIntern(),
7897 .index = new_func,7867 .index = new_func,
7898 } })).toValue();7868 } })).toValue();
7899 new_decl.@"align" = 0;7869 new_decl.alignment = .none;
7900 new_decl.has_tv = true;7870 new_decl.has_tv = true;
7901 new_decl.owns_tv = true;7871 new_decl.owns_tv = true;
7902 new_decl.analysis = .complete;7872 new_decl.analysis = .complete;
...@@ -7971,7 +7941,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -7971,7 +7941,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
7971 } else if (child_type.zigTypeTag(mod) == .Null) {7941 } else if (child_type.zigTypeTag(mod) == .Null) {
7972 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)});7942 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)});
7973 }7943 }
7974 const opt_type = try Type.optional(sema.arena, child_type, mod);7944 const opt_type = try mod.optionalType(child_type.toIntern());
79757945
7976 return sema.addType(opt_type);7946 return sema.addType(opt_type);
7977}7947}
...@@ -8017,7 +7987,10 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8017,7 +7987,10 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8017 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime-known");7987 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime-known");
8018 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);7988 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
8019 try sema.validateArrayElemType(block, elem_type, elem_src);7989 try sema.validateArrayElemType(block, elem_type, elem_src);
8020 const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod);7990 const array_ty = try sema.mod.arrayType(.{
7991 .len = len,
7992 .child = elem_type.toIntern(),
7993 });
80217994
8022 return sema.addType(array_ty);7995 return sema.addType(array_ty);
8023}7996}
...@@ -8037,7 +8010,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8037,7 +8010,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8037 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);8010 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);
8038 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);8011 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
8039 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime-known");8012 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime-known");
8040 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, sema.mod);8013 const array_ty = try sema.mod.arrayType(.{
8014 .len = len,
8015 .sentinel = sentinel_val.toIntern(),
8016 .child = elem_type.toIntern(),
8017 });
80418018
8042 return sema.addType(array_ty);8019 return sema.addType(array_ty);
8043}8020}
...@@ -8412,10 +8389,12 @@ fn analyzeOptionalPayloadPtr(...@@ -8412,10 +8389,12 @@ fn analyzeOptionalPayloadPtr(
8412 }8389 }
84138390
8414 const child_type = opt_type.optionalChild(mod);8391 const child_type = opt_type.optionalChild(mod);
8415 const child_pointer = try Type.ptr(sema.arena, mod, .{8392 const child_pointer = try mod.ptrType(.{
8416 .pointee_type = child_type,8393 .child = child_type.toIntern(),
8417 .mutable = !optional_ptr_ty.isConstPtr(mod),8394 .flags = .{
8418 .@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod),8395 .is_const = optional_ptr_ty.isConstPtr(mod),
8396 .address_space = optional_ptr_ty.ptrAddressSpace(mod),
8397 },
8419 });8398 });
84208399
8421 if (try sema.resolveDefinedValue(block, src, optional_ptr)) |ptr_val| {8400 if (try sema.resolveDefinedValue(block, src, optional_ptr)) |ptr_val| {
...@@ -8479,14 +8458,15 @@ fn zirOptionalPayload(...@@ -8479,14 +8458,15 @@ fn zirOptionalPayload(
8479 // TODO https://github.com/ziglang/zig/issues/65978458 // TODO https://github.com/ziglang/zig/issues/6597
8480 if (true) break :t operand_ty;8459 if (true) break :t operand_ty;
8481 const ptr_info = operand_ty.ptrInfo(mod);8460 const ptr_info = operand_ty.ptrInfo(mod);
8482 break :t try Type.ptr(sema.arena, mod, .{8461 break :t try mod.ptrType(.{
8483 .pointee_type = ptr_info.pointee_type,8462 .child = ptr_info.child,
8484 .@"align" = ptr_info.@"align",8463 .flags = .{
8485 .@"addrspace" = ptr_info.@"addrspace",8464 .alignment = ptr_info.flags.alignment,
8486 .mutable = ptr_info.mutable,8465 .is_const = ptr_info.flags.is_const,
8487 .@"allowzero" = ptr_info.@"allowzero",8466 .is_volatile = ptr_info.flags.is_volatile,
8488 .@"volatile" = ptr_info.@"volatile",8467 .is_allowzero = ptr_info.flags.is_allowzero,
8489 .size = .One,8468 .address_space = ptr_info.flags.address_space,
8469 },
8490 });8470 });
8491 },8471 },
8492 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),8472 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),
...@@ -8599,10 +8579,12 @@ fn analyzeErrUnionPayloadPtr(...@@ -8599,10 +8579,12 @@ fn analyzeErrUnionPayloadPtr(
85998579
8600 const err_union_ty = operand_ty.childType(mod);8580 const err_union_ty = operand_ty.childType(mod);
8601 const payload_ty = err_union_ty.errorUnionPayload(mod);8581 const payload_ty = err_union_ty.errorUnionPayload(mod);
8602 const operand_pointer_ty = try Type.ptr(sema.arena, mod, .{8582 const operand_pointer_ty = try mod.ptrType(.{
8603 .pointee_type = payload_ty,8583 .child = payload_ty.toIntern(),
8604 .mutable = !operand_ty.isConstPtr(mod),8584 .flags = .{
8605 .@"addrspace" = operand_ty.ptrAddressSpace(mod),8585 .is_const = operand_ty.isConstPtr(mod),
8586 .address_space = operand_ty.ptrAddressSpace(mod),
8587 },
8606 });8588 });
86078589
8608 if (try sema.resolveDefinedValue(block, src, operand)) |ptr_val| {8590 if (try sema.resolveDefinedValue(block, src, operand)) |ptr_val| {
...@@ -8769,7 +8751,7 @@ fn zirFunc(...@@ -8769,7 +8751,7 @@ fn zirFunc(
8769 block,8751 block,
8770 inst_data.src_node,8752 inst_data.src_node,
8771 inst,8753 inst,
8772 0,8754 .none,
8773 target_util.defaultAddressSpace(target, .function),8755 target_util.defaultAddressSpace(target, .function),
8774 FuncLinkSection.default,8756 FuncLinkSection.default,
8775 cc,8757 cc,
...@@ -8898,7 +8880,7 @@ fn funcCommon(...@@ -8898,7 +8880,7 @@ fn funcCommon(
8898 src_node_offset: i32,8880 src_node_offset: i32,
8899 func_inst: Zir.Inst.Index,8881 func_inst: Zir.Inst.Index,
8900 /// null means generic poison8882 /// null means generic poison
8901 alignment: ?u32,8883 alignment: ?Alignment,
8902 /// null means generic poison8884 /// null means generic poison
8903 address_space: ?std.builtin.AddressSpace,8885 address_space: ?std.builtin.AddressSpace,
8904 /// outer null means generic poison; inner null means default link section8886 /// outer null means generic poison; inner null means default link section
...@@ -9147,7 +9129,7 @@ fn funcCommon(...@@ -9147,7 +9129,7 @@ fn funcCommon(
9147 .return_type = return_type.toIntern(),9129 .return_type = return_type.toIntern(),
9148 .cc = cc_resolved,9130 .cc = cc_resolved,
9149 .cc_is_generic = cc == null,9131 .cc_is_generic = cc == null,
9150 .alignment = if (alignment) |a| InternPool.Alignment.fromByteUnits(a) else .none,9132 .alignment = alignment orelse .none,
9151 .align_is_generic = alignment == null,9133 .align_is_generic = alignment == null,
9152 .section_is_generic = section == .generic,9134 .section_is_generic = section == .generic,
9153 .addrspace_is_generic = address_space == null,9135 .addrspace_is_generic = address_space == null,
...@@ -9162,7 +9144,7 @@ fn funcCommon(...@@ -9162,7 +9144,7 @@ fn funcCommon(
9162 .default => .none,9144 .default => .none,
9163 .explicit => |section_name| section_name.toOptional(),9145 .explicit => |section_name| section_name.toOptional(),
9164 };9146 };
9165 sema.owner_decl.@"align" = alignment orelse 0;9147 sema.owner_decl.alignment = alignment orelse .none;
9166 sema.owner_decl.@"addrspace" = address_space orelse .generic;9148 sema.owner_decl.@"addrspace" = address_space orelse .generic;
91679149
9168 if (is_extern) {9150 if (is_extern) {
...@@ -10294,11 +10276,13 @@ const SwitchProngAnalysis = struct {...@@ -10294,11 +10276,13 @@ const SwitchProngAnalysis = struct {
10294 const union_obj = mod.typeToUnion(operand_ty).?;10276 const union_obj = mod.typeToUnion(operand_ty).?;
10295 const field_ty = union_obj.fields.values()[field_index].ty;10277 const field_ty = union_obj.fields.values()[field_index].ty;
10296 if (capture_byref) {10278 if (capture_byref) {
10297 const ptr_field_ty = try Type.ptr(sema.arena, mod, .{10279 const ptr_field_ty = try mod.ptrType(.{
10298 .pointee_type = field_ty,10280 .child = field_ty.toIntern(),
10299 .mutable = operand_ptr_ty.ptrIsMutable(mod),10281 .flags = .{
10300 .@"volatile" = operand_ptr_ty.isVolatilePtr(mod),10282 .is_const = !operand_ptr_ty.ptrIsMutable(mod),
10301 .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod),10283 .is_volatile = operand_ptr_ty.isVolatilePtr(mod),
10284 .address_space = operand_ptr_ty.ptrAddressSpace(mod),
10285 },
10302 });10286 });
10303 if (try sema.resolveDefinedValue(block, sema.src, spa.operand_ptr)) |union_ptr| {10287 if (try sema.resolveDefinedValue(block, sema.src, spa.operand_ptr)) |union_ptr| {
10304 return sema.addConstant(10288 return sema.addConstant(
...@@ -10401,24 +10385,28 @@ const SwitchProngAnalysis = struct {...@@ -10401,24 +10385,28 @@ const SwitchProngAnalysis = struct {
10401 // By-reference captures have some further restrictions which make them easier to emit10385 // By-reference captures have some further restrictions which make them easier to emit
10402 if (capture_byref) {10386 if (capture_byref) {
10403 const operand_ptr_info = operand_ptr_ty.ptrInfo(mod);10387 const operand_ptr_info = operand_ptr_ty.ptrInfo(mod);
10404 const capture_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{10388 const capture_ptr_ty = try mod.ptrType(.{
10405 .pointee_type = capture_ty,10389 .child = capture_ty.toIntern(),
10406 .@"addrspace" = operand_ptr_info.@"addrspace",10390 .flags = .{
10407 .mutable = operand_ptr_info.mutable,10391 // TODO: alignment!
10408 .@"volatile" = operand_ptr_info.@"volatile",10392 .is_const = operand_ptr_info.flags.is_const,
10409 // TODO: alignment!10393 .is_volatile = operand_ptr_info.flags.is_volatile,
10394 .address_space = operand_ptr_info.flags.address_space,
10395 },
10410 });10396 });
1041110397
10412 // By-ref captures of hetereogeneous types are only allowed if each field10398 // By-ref captures of hetereogeneous types are only allowed if each field
10413 // pointer type is in-memory coercible to the capture pointer type.10399 // pointer type is in-memory coercible to the capture pointer type.
10414 if (!same_types) {10400 if (!same_types) {
10415 for (field_tys, 0..) |field_ty, i| {10401 for (field_tys, 0..) |field_ty, i| {
10416 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{10402 const field_ptr_ty = try mod.ptrType(.{
10417 .pointee_type = field_ty,10403 .child = field_ty.toIntern(),
10418 .@"addrspace" = operand_ptr_info.@"addrspace",10404 .flags = .{
10419 .mutable = operand_ptr_info.mutable,10405 // TODO: alignment!
10420 .@"volatile" = operand_ptr_info.@"volatile",10406 .is_const = operand_ptr_info.flags.is_const,
10421 // TODO: alignment!10407 .is_volatile = operand_ptr_info.flags.is_volatile,
10408 .address_space = operand_ptr_info.flags.address_space,
10409 },
10422 });10410 });
10423 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ptr_ty, field_ptr_ty, false, sema.mod.getTarget(), .unneeded, .unneeded)) {10411 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ptr_ty, field_ptr_ty, false, sema.mod.getTarget(), .unneeded, .unneeded)) {
10424 const multi_idx = raw_capture_src.multi_capture;10412 const multi_idx = raw_capture_src.multi_capture;
...@@ -12675,8 +12663,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -12675,8 +12663,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
12675 // - When a Decl is destroyed, it can free the `*Module.EmbedFile`.12663 // - When a Decl is destroyed, it can free the `*Module.EmbedFile`.
12676 const ty = try mod.arrayType(.{12664 const ty = try mod.arrayType(.{
12677 .len = embed_file.bytes.len,12665 .len = embed_file.bytes.len,
12678 .child = .u8_type,
12679 .sentinel = .zero_u8,12666 .sentinel = .zero_u8,
12667 .child = .u8_type,
12680 });12668 });
12681 embed_file.owner_decl = try anon_decl.finish(12669 embed_file.owner_decl = try anon_decl.finish(
12682 ty,12670 ty,
...@@ -12684,7 +12672,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -12684,7 +12672,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
12684 .ty = ty.toIntern(),12672 .ty = ty.toIntern(),
12685 .storage = .{ .bytes = embed_file.bytes },12673 .storage = .{ .bytes = embed_file.bytes },
12686 } })).toValue(),12674 } })).toValue(),
12687 0, // default alignment12675 .none, // default alignment
12688 );12676 );
1268912677
12690 return sema.analyzeDeclRef(embed_file.owner_decl);12678 return sema.analyzeDeclRef(embed_file.owner_decl);
...@@ -13308,7 +13296,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13308,7 +13296,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13308 ),13296 ),
13309 };13297 };
1331013298
13311 const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, mod);13299 const result_ty = try mod.arrayType(.{
13300 .len = result_len,
13301 .sentinel = if (res_sent_val) |v| v.toIntern() else .none,
13302 .child = resolved_elem_ty.toIntern(),
13303 });
13312 const ptr_addrspace = p: {13304 const ptr_addrspace = p: {
13313 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod);13305 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod);
13314 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod);13306 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod);
...@@ -13367,14 +13359,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13367,14 +13359,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13367 try sema.requireRuntimeBlock(block, src, runtime_src);13359 try sema.requireRuntimeBlock(block, src, runtime_src);
1336813360
13369 if (ptr_addrspace) |ptr_as| {13361 if (ptr_addrspace) |ptr_as| {
13370 const alloc_ty = try Type.ptr(sema.arena, mod, .{13362 const alloc_ty = try mod.ptrType(.{
13371 .pointee_type = result_ty,13363 .child = result_ty.toIntern(),
13372 .@"addrspace" = ptr_as,13364 .flags = .{ .address_space = ptr_as },
13373 });13365 });
13374 const alloc = try block.addTy(.alloc, alloc_ty);13366 const alloc = try block.addTy(.alloc, alloc_ty);
13375 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{13367 const elem_ptr_ty = try mod.ptrType(.{
13376 .pointee_type = resolved_elem_ty,13368 .child = resolved_elem_ty.toIntern(),
13377 .@"addrspace" = ptr_as,13369 .flags = .{ .address_space = ptr_as },
13378 });13370 });
1337913371
13380 var elem_i: usize = 0;13372 var elem_i: usize = 0;
...@@ -13426,21 +13418,24 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -13426,21 +13418,24 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
13426 .Array => return operand_ty.arrayInfo(mod),13418 .Array => return operand_ty.arrayInfo(mod),
13427 .Pointer => {13419 .Pointer => {
13428 const ptr_info = operand_ty.ptrInfo(mod);13420 const ptr_info = operand_ty.ptrInfo(mod);
13429 switch (ptr_info.size) {13421 switch (ptr_info.flags.size) {
13430 // TODO: in the Many case here this should only work if the type13422 // TODO: in the Many case here this should only work if the type
13431 // has a sentinel, and this code should compute the length based13423 // has a sentinel, and this code should compute the length based
13432 // on the sentinel value.13424 // on the sentinel value.
13433 .Slice, .Many => {13425 .Slice, .Many => {
13434 const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime-known");13426 const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime-known");
13435 return Type.ArrayInfo{13427 return Type.ArrayInfo{
13436 .elem_type = ptr_info.pointee_type,13428 .elem_type = ptr_info.child.toType(),
13437 .sentinel = ptr_info.sentinel,13429 .sentinel = switch (ptr_info.sentinel) {
13430 .none => null,
13431 else => ptr_info.sentinel.toValue(),
13432 },
13438 .len = val.sliceLen(mod),13433 .len = val.sliceLen(mod),
13439 };13434 };
13440 },13435 },
13441 .One => {13436 .One => {
13442 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {13437 if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
13443 return ptr_info.pointee_type.arrayInfo(mod);13438 return ptr_info.child.toType().arrayInfo(mod);
13444 }13439 }
13445 },13440 },
13446 .C => {},13441 .C => {},
...@@ -13576,7 +13571,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13576,7 +13571,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13576 return sema.fail(block, rhs_src, "operation results in overflow", .{});13571 return sema.fail(block, rhs_src, "operation results in overflow", .{});
13577 const result_len = try sema.usizeCast(block, src, result_len_u64);13572 const result_len = try sema.usizeCast(block, src, result_len_u64);
1357813573
13579 const result_ty = try Type.array(sema.arena, result_len, lhs_info.sentinel, lhs_info.elem_type, mod);13574 const result_ty = try mod.arrayType(.{
13575 .len = result_len,
13576 .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none,
13577 .child = lhs_info.elem_type.toIntern(),
13578 });
1358013579
13581 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;13580 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;
13582 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);13581 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);
...@@ -13619,14 +13618,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13619,14 +13618,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13619 try sema.requireRuntimeBlock(block, src, lhs_src);13618 try sema.requireRuntimeBlock(block, src, lhs_src);
1362013619
13621 if (ptr_addrspace) |ptr_as| {13620 if (ptr_addrspace) |ptr_as| {
13622 const alloc_ty = try Type.ptr(sema.arena, mod, .{13621 const alloc_ty = try mod.ptrType(.{
13623 .pointee_type = result_ty,13622 .child = result_ty.toIntern(),
13624 .@"addrspace" = ptr_as,13623 .flags = .{ .address_space = ptr_as },
13625 });13624 });
13626 const alloc = try block.addTy(.alloc, alloc_ty);13625 const alloc = try block.addTy(.alloc, alloc_ty);
13627 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{13626 const elem_ptr_ty = try mod.ptrType(.{
13628 .pointee_type = lhs_info.elem_type,13627 .child = lhs_info.elem_type.toIntern(),
13629 .@"addrspace" = ptr_as,13628 .flags = .{ .address_space = ptr_as },
13630 });13629 });
1363113630
13632 var elem_i: usize = 0;13631 var elem_i: usize = 0;
...@@ -15582,18 +15581,18 @@ fn analyzePtrArithmetic(...@@ -15582,18 +15581,18 @@ fn analyzePtrArithmetic(
15582 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);15581 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
15583 const ptr_ty = sema.typeOf(ptr);15582 const ptr_ty = sema.typeOf(ptr);
15584 const ptr_info = ptr_ty.ptrInfo(mod);15583 const ptr_info = ptr_ty.ptrInfo(mod);
15585 assert(ptr_info.size == .Many or ptr_info.size == .C);15584 assert(ptr_info.flags.size == .Many or ptr_info.flags.size == .C);
1558615585
15587 const new_ptr_ty = t: {15586 const new_ptr_ty = t: {
15588 // Calculate the new pointer alignment.15587 // Calculate the new pointer alignment.
15589 // This code is duplicated in `elemPtrType`.15588 // This code is duplicated in `elemPtrType`.
15590 if (ptr_info.@"align" == 0) {15589 if (ptr_info.flags.alignment == .none) {
15591 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.15590 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
15592 break :t ptr_ty;15591 break :t ptr_ty;
15593 }15592 }
15594 // If the addend is not a comptime-known value we can still count on15593 // If the addend is not a comptime-known value we can still count on
15595 // it being a multiple of the type size.15594 // it being a multiple of the type size.
15596 const elem_size = ptr_info.pointee_type.abiSize(mod);15595 const elem_size = ptr_info.child.toType().abiSize(mod);
15597 const addend = if (opt_off_val) |off_val| a: {15596 const addend = if (opt_off_val) |off_val| a: {
15598 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod));15597 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod));
15599 break :a elem_size * off_int;15598 break :a elem_size * off_int;
...@@ -15602,17 +15601,23 @@ fn analyzePtrArithmetic(...@@ -15602,17 +15601,23 @@ fn analyzePtrArithmetic(
15602 // The resulting pointer is aligned to the lcd between the offset (an15601 // The resulting pointer is aligned to the lcd between the offset (an
15603 // arbitrary number) and the alignment factor (always a power of two,15602 // arbitrary number) and the alignment factor (always a power of two,
15604 // non zero).15603 // non zero).
15605 const new_align = @as(u32, 1) << @intCast(u5, @ctz(addend | ptr_info.@"align"));15604 const new_align = @enumFromInt(Alignment, @min(
15605 @ctz(addend),
15606 @intFromEnum(ptr_info.flags.alignment),
15607 ));
15608 assert(new_align != .none);
1560615609
15607 break :t try Type.ptr(sema.arena, mod, .{15610 break :t try mod.ptrType(.{
15608 .pointee_type = ptr_info.pointee_type,15611 .child = ptr_info.child,
15609 .sentinel = ptr_info.sentinel,15612 .sentinel = ptr_info.sentinel,
15610 .@"align" = new_align,15613 .flags = .{
15611 .@"addrspace" = ptr_info.@"addrspace",15614 .size = ptr_info.flags.size,
15612 .mutable = ptr_info.mutable,15615 .alignment = new_align,
15613 .@"allowzero" = ptr_info.@"allowzero",15616 .is_const = ptr_info.flags.is_const,
15614 .@"volatile" = ptr_info.@"volatile",15617 .is_volatile = ptr_info.flags.is_volatile,
15615 .size = ptr_info.size,15618 .is_allowzero = ptr_info.flags.is_allowzero,
15619 .address_space = ptr_info.flags.address_space,
15620 },
15616 });15621 });
15617 };15622 };
1561815623
...@@ -15624,7 +15629,7 @@ fn analyzePtrArithmetic(...@@ -15624,7 +15629,7 @@ fn analyzePtrArithmetic(
15624 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));15629 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));
15625 if (offset_int == 0) return ptr;15630 if (offset_int == 0) return ptr;
15626 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {15631 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {
15627 const elem_size = ptr_info.pointee_type.abiSize(mod);15632 const elem_size = ptr_info.child.toType().abiSize(mod);
15628 const new_addr = switch (air_tag) {15633 const new_addr = switch (air_tag) {
15629 .ptr_add => addr + elem_size * offset_int,15634 .ptr_add => addr + elem_size * offset_int,
15630 .ptr_sub => addr - elem_size * offset_int,15635 .ptr_sub => addr - elem_size * offset_int,
...@@ -16363,8 +16368,8 @@ fn zirBuiltinSrc(...@@ -16363,8 +16368,8 @@ fn zirBuiltinSrc(
16363 const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));16368 const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));
16364 const new_decl_ty = try mod.arrayType(.{16369 const new_decl_ty = try mod.arrayType(.{
16365 .len = name.len,16370 .len = name.len,
16366 .child = .u8_type,
16367 .sentinel = .zero_u8,16371 .sentinel = .zero_u8,
16372 .child = .u8_type,
16368 });16373 });
16369 const new_decl = try anon_decl.finish(16374 const new_decl = try anon_decl.finish(
16370 new_decl_ty,16375 new_decl_ty,
...@@ -16372,7 +16377,7 @@ fn zirBuiltinSrc(...@@ -16372,7 +16377,7 @@ fn zirBuiltinSrc(
16372 .ty = new_decl_ty.toIntern(),16377 .ty = new_decl_ty.toIntern(),
16373 .storage = .{ .bytes = name },16378 .storage = .{ .bytes = name },
16374 } })).toValue(),16379 } })).toValue(),
16375 0, // default alignment16380 .none, // default alignment
16376 );16381 );
16377 break :blk try mod.intern(.{ .ptr = .{16382 break :blk try mod.intern(.{ .ptr = .{
16378 .ty = .slice_const_u8_sentinel_0_type,16383 .ty = .slice_const_u8_sentinel_0_type,
...@@ -16388,8 +16393,8 @@ fn zirBuiltinSrc(...@@ -16388,8 +16393,8 @@ fn zirBuiltinSrc(
16388 const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);16393 const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
16389 const new_decl_ty = try mod.arrayType(.{16394 const new_decl_ty = try mod.arrayType(.{
16390 .len = name.len,16395 .len = name.len,
16391 .child = .u8_type,
16392 .sentinel = .zero_u8,16396 .sentinel = .zero_u8,
16397 .child = .u8_type,
16393 });16398 });
16394 const new_decl = try anon_decl.finish(16399 const new_decl = try anon_decl.finish(
16395 new_decl_ty,16400 new_decl_ty,
...@@ -16397,7 +16402,7 @@ fn zirBuiltinSrc(...@@ -16397,7 +16402,7 @@ fn zirBuiltinSrc(
16397 .ty = new_decl_ty.toIntern(),16402 .ty = new_decl_ty.toIntern(),
16398 .storage = .{ .bytes = name },16403 .storage = .{ .bytes = name },
16399 } })).toValue(),16404 } })).toValue(),
16400 0, // default alignment16405 .none, // default alignment
16401 );16406 );
16402 break :blk try mod.intern(.{ .ptr = .{16407 break :blk try mod.intern(.{ .ptr = .{
16403 .ty = .slice_const_u8_sentinel_0_type,16408 .ty = .slice_const_u8_sentinel_0_type,
...@@ -16518,7 +16523,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16518,7 +16523,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16518 .ty = new_decl_ty.toIntern(),16523 .ty = new_decl_ty.toIntern(),
16519 .storage = .{ .elems = param_vals },16524 .storage = .{ .elems = param_vals },
16520 } })).toValue(),16525 } })).toValue(),
16521 0, // default alignment16526 .none, // default alignment
16522 );16527 );
16523 break :v try mod.intern(.{ .ptr = .{16528 break :v try mod.intern(.{ .ptr = .{
16524 .ty = (try mod.ptrType(.{16529 .ty = (try mod.ptrType(.{
...@@ -16620,10 +16625,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16620,10 +16625,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16620 },16625 },
16621 .Pointer => {16626 .Pointer => {
16622 const info = ty.ptrInfo(mod);16627 const info = ty.ptrInfo(mod);
16623 const alignment = if (info.@"align" != 0)16628 const alignment = if (info.flags.alignment.toByteUnitsOptional()) |alignment|
16624 try mod.intValue(Type.comptime_int, info.@"align")16629 try mod.intValue(Type.comptime_int, alignment)
16625 else16630 else
16626 try info.pointee_type.lazyAbiAlignment(mod);16631 try info.child.toType().lazyAbiAlignment(mod);
1662716632
16628 const addrspace_ty = try sema.getBuiltinType("AddressSpace");16633 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
16629 const pointer_ty = t: {16634 const pointer_ty = t: {
...@@ -16653,21 +16658,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16653,21 +16658,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1665316658
16654 const field_values = .{16659 const field_values = .{
16655 // size: Size,16660 // size: Size,
16656 try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.size))).intern(ptr_size_ty, mod),16661 try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).intern(ptr_size_ty, mod),
16657 // is_const: bool,16662 // is_const: bool,
16658 Value.makeBool(!info.mutable).toIntern(),16663 Value.makeBool(info.flags.is_const).toIntern(),
16659 // is_volatile: bool,16664 // is_volatile: bool,
16660 Value.makeBool(info.@"volatile").toIntern(),16665 Value.makeBool(info.flags.is_volatile).toIntern(),
16661 // alignment: comptime_int,16666 // alignment: comptime_int,
16662 alignment.toIntern(),16667 alignment.toIntern(),
16663 // address_space: AddressSpace16668 // address_space: AddressSpace
16664 try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.@"addrspace"))).intern(addrspace_ty, mod),16669 try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).intern(addrspace_ty, mod),
16665 // child: type,16670 // child: type,
16666 info.pointee_type.toIntern(),16671 info.child,
16667 // is_allowzero: bool,16672 // is_allowzero: bool,
16668 Value.makeBool(info.@"allowzero").toIntern(),16673 Value.makeBool(info.flags.is_allowzero).toIntern(),
16669 // sentinel: ?*const anyopaque,16674 // sentinel: ?*const anyopaque,
16670 (try sema.optRefValue(block, info.pointee_type, info.sentinel)).toIntern(),16675 (try sema.optRefValue(block, info.child.toType(), switch (info.sentinel) {
16676 .none => null,
16677 else => info.sentinel.toValue(),
16678 })).toIntern(),
16671 };16679 };
16672 return sema.addConstant(type_info_ty, (try mod.intern(.{ .un = .{16680 return sema.addConstant(type_info_ty, (try mod.intern(.{ .un = .{
16673 .ty = type_info_ty.toIntern(),16681 .ty = type_info_ty.toIntern(),
...@@ -16811,7 +16819,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16811,7 +16819,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16811 .ty = new_decl_ty.toIntern(),16819 .ty = new_decl_ty.toIntern(),
16812 .storage = .{ .bytes = name },16820 .storage = .{ .bytes = name },
16813 } })).toValue(),16821 } })).toValue(),
16814 0, // default alignment16822 .none, // default alignment
16815 );16823 );
16816 break :v try mod.intern(.{ .ptr = .{16824 break :v try mod.intern(.{ .ptr = .{
16817 .ty = .slice_const_u8_type,16825 .ty = .slice_const_u8_type,
...@@ -16846,7 +16854,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16846,7 +16854,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16846 const array_errors_ty = try mod.arrayType(.{16854 const array_errors_ty = try mod.arrayType(.{
16847 .len = vals.len,16855 .len = vals.len,
16848 .child = error_field_ty.toIntern(),16856 .child = error_field_ty.toIntern(),
16849 .sentinel = .none,
16850 });16857 });
16851 const new_decl = try fields_anon_decl.finish(16858 const new_decl = try fields_anon_decl.finish(
16852 array_errors_ty,16859 array_errors_ty,
...@@ -16854,7 +16861,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16854,7 +16861,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16854 .ty = array_errors_ty.toIntern(),16861 .ty = array_errors_ty.toIntern(),
16855 .storage = .{ .elems = vals },16862 .storage = .{ .elems = vals },
16856 } })).toValue(),16863 } })).toValue(),
16857 0, // default alignment16864 .none, // default alignment
16858 );16865 );
16859 break :v try mod.intern(.{ .ptr = .{16866 break :v try mod.intern(.{ .ptr = .{
16860 .ty = slice_errors_ty.toIntern(),16867 .ty = slice_errors_ty.toIntern(),
...@@ -16948,7 +16955,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16948,7 +16955,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16948 .ty = new_decl_ty.toIntern(),16955 .ty = new_decl_ty.toIntern(),
16949 .storage = .{ .bytes = name },16956 .storage = .{ .bytes = name },
16950 } })).toValue(),16957 } })).toValue(),
16951 0, // default alignment16958 .none, // default alignment
16952 );16959 );
16953 break :v try mod.intern(.{ .ptr = .{16960 break :v try mod.intern(.{ .ptr = .{
16954 .ty = .slice_const_u8_type,16961 .ty = .slice_const_u8_type,
...@@ -16973,7 +16980,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16973,7 +16980,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16973 const fields_array_ty = try mod.arrayType(.{16980 const fields_array_ty = try mod.arrayType(.{
16974 .len = enum_field_vals.len,16981 .len = enum_field_vals.len,
16975 .child = enum_field_ty.toIntern(),16982 .child = enum_field_ty.toIntern(),
16976 .sentinel = .none,
16977 });16983 });
16978 const new_decl = try fields_anon_decl.finish(16984 const new_decl = try fields_anon_decl.finish(
16979 fields_array_ty,16985 fields_array_ty,
...@@ -16981,7 +16987,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16981,7 +16987,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16981 .ty = fields_array_ty.toIntern(),16987 .ty = fields_array_ty.toIntern(),
16982 .storage = .{ .elems = enum_field_vals },16988 .storage = .{ .elems = enum_field_vals },
16983 } })).toValue(),16989 } })).toValue(),
16984 0, // default alignment16990 .none, // default alignment
16985 );16991 );
16986 break :v try mod.intern(.{ .ptr = .{16992 break :v try mod.intern(.{ .ptr = .{
16987 .ty = (try mod.ptrType(.{16993 .ty = (try mod.ptrType(.{
...@@ -17087,7 +17093,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17087,7 +17093,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17087 .ty = new_decl_ty.toIntern(),17093 .ty = new_decl_ty.toIntern(),
17088 .storage = .{ .bytes = name },17094 .storage = .{ .bytes = name },
17089 } })).toValue(),17095 } })).toValue(),
17090 0, // default alignment17096 .none, // default alignment
17091 );17097 );
17092 break :v try mod.intern(.{ .ptr = .{17098 break :v try mod.intern(.{ .ptr = .{
17093 .ty = .slice_const_u8_type,17099 .ty = .slice_const_u8_type,
...@@ -17119,7 +17125,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17119,7 +17125,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17119 const array_fields_ty = try mod.arrayType(.{17125 const array_fields_ty = try mod.arrayType(.{
17120 .len = union_field_vals.len,17126 .len = union_field_vals.len,
17121 .child = union_field_ty.toIntern(),17127 .child = union_field_ty.toIntern(),
17122 .sentinel = .none,
17123 });17128 });
17124 const new_decl = try fields_anon_decl.finish(17129 const new_decl = try fields_anon_decl.finish(
17125 array_fields_ty,17130 array_fields_ty,
...@@ -17127,7 +17132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17127,7 +17132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17127 .ty = array_fields_ty.toIntern(),17132 .ty = array_fields_ty.toIntern(),
17128 .storage = .{ .elems = union_field_vals },17133 .storage = .{ .elems = union_field_vals },
17129 } })).toValue(),17134 } })).toValue(),
17130 0, // default alignment17135 .none, // default alignment
17131 );17136 );
17132 break :v try mod.intern(.{ .ptr = .{17137 break :v try mod.intern(.{ .ptr = .{
17133 .ty = (try mod.ptrType(.{17138 .ty = (try mod.ptrType(.{
...@@ -17247,7 +17252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17247,7 +17252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17247 .ty = new_decl_ty.toIntern(),17252 .ty = new_decl_ty.toIntern(),
17248 .storage = .{ .bytes = bytes },17253 .storage = .{ .bytes = bytes },
17249 } })).toValue(),17254 } })).toValue(),
17250 0, // default alignment17255 .none, // default alignment
17251 );17256 );
17252 break :v try mod.intern(.{ .ptr = .{17257 break :v try mod.intern(.{ .ptr = .{
17253 .ty = .slice_const_u8_type,17258 .ty = .slice_const_u8_type,
...@@ -17304,7 +17309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17304,7 +17309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17304 .ty = new_decl_ty.toIntern(),17309 .ty = new_decl_ty.toIntern(),
17305 .storage = .{ .bytes = name },17310 .storage = .{ .bytes = name },
17306 } })).toValue(),17311 } })).toValue(),
17307 0, // default alignment17312 .none, // default alignment
17308 );17313 );
17309 break :v try mod.intern(.{ .ptr = .{17314 break :v try mod.intern(.{ .ptr = .{
17310 .ty = .slice_const_u8_type,17315 .ty = .slice_const_u8_type,
...@@ -17343,7 +17348,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17343,7 +17348,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17343 const array_fields_ty = try mod.arrayType(.{17348 const array_fields_ty = try mod.arrayType(.{
17344 .len = struct_field_vals.len,17349 .len = struct_field_vals.len,
17345 .child = struct_field_ty.toIntern(),17350 .child = struct_field_ty.toIntern(),
17346 .sentinel = .none,
17347 });17351 });
17348 const new_decl = try fields_anon_decl.finish(17352 const new_decl = try fields_anon_decl.finish(
17349 array_fields_ty,17353 array_fields_ty,
...@@ -17351,7 +17355,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17351,7 +17355,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17351 .ty = array_fields_ty.toIntern(),17355 .ty = array_fields_ty.toIntern(),
17352 .storage = .{ .elems = struct_field_vals },17356 .storage = .{ .elems = struct_field_vals },
17353 } })).toValue(),17357 } })).toValue(),
17354 0, // default alignment17358 .none, // default alignment
17355 );17359 );
17356 break :v try mod.intern(.{ .ptr = .{17360 break :v try mod.intern(.{ .ptr = .{
17357 .ty = (try mod.ptrType(.{17361 .ty = (try mod.ptrType(.{
...@@ -17490,7 +17494,6 @@ fn typeInfoDecls(...@@ -17490,7 +17494,6 @@ fn typeInfoDecls(
17490 const array_decl_ty = try mod.arrayType(.{17494 const array_decl_ty = try mod.arrayType(.{
17491 .len = decl_vals.items.len,17495 .len = decl_vals.items.len,
17492 .child = declaration_ty.toIntern(),17496 .child = declaration_ty.toIntern(),
17493 .sentinel = .none,
17494 });17497 });
17495 const new_decl = try decls_anon_decl.finish(17498 const new_decl = try decls_anon_decl.finish(
17496 array_decl_ty,17499 array_decl_ty,
...@@ -17498,7 +17501,7 @@ fn typeInfoDecls(...@@ -17498,7 +17501,7 @@ fn typeInfoDecls(
17498 .ty = array_decl_ty.toIntern(),17501 .ty = array_decl_ty.toIntern(),
17499 .storage = .{ .elems = decl_vals.items },17502 .storage = .{ .elems = decl_vals.items },
17500 } })).toValue(),17503 } })).toValue(),
17501 0, // default alignment17504 .none, // default alignment
17502 );17505 );
17503 return try mod.intern(.{ .ptr = .{17506 return try mod.intern(.{ .ptr = .{
17504 .ty = (try mod.ptrType(.{17507 .ty = (try mod.ptrType(.{
...@@ -17551,7 +17554,7 @@ fn typeInfoNamespaceDecls(...@@ -17551,7 +17554,7 @@ fn typeInfoNamespaceDecls(
17551 .ty = new_decl_ty.toIntern(),17554 .ty = new_decl_ty.toIntern(),
17552 .storage = .{ .bytes = name },17555 .storage = .{ .bytes = name },
17553 } })).toValue(),17556 } })).toValue(),
17554 0, // default alignment17557 .none, // default alignment
17555 );17558 );
17556 break :v try mod.intern(.{ .ptr = .{17559 break :v try mod.intern(.{ .ptr = .{
17557 .ty = .slice_const_u8_type,17560 .ty = .slice_const_u8_type,
...@@ -18076,12 +18079,14 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -18076,12 +18079,14 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1807618079
18077 const operand_ty = sema.typeOf(operand);18080 const operand_ty = sema.typeOf(operand);
18078 const ptr_info = operand_ty.ptrInfo(mod);18081 const ptr_info = operand_ty.ptrInfo(mod);
18079 const res_ty = try Type.ptr(sema.arena, mod, .{18082 const res_ty = try mod.ptrType(.{
18080 .pointee_type = err_union_ty.errorUnionPayload(mod),18083 .child = err_union_ty.errorUnionPayload(mod).toIntern(),
18081 .@"addrspace" = ptr_info.@"addrspace",18084 .flags = .{
18082 .mutable = ptr_info.mutable,18085 .is_const = ptr_info.flags.is_const,
18083 .@"allowzero" = ptr_info.@"allowzero",18086 .is_volatile = ptr_info.flags.is_volatile,
18084 .@"volatile" = ptr_info.@"volatile",18087 .is_allowzero = ptr_info.flags.is_allowzero,
18088 .address_space = ptr_info.flags.address_space,
18089 },
18085 });18090 });
18086 const res_ty_ref = try sema.addType(res_ty);18091 const res_ty_ref = try sema.addType(res_ty);
18087 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).Struct.fields.len +18092 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).Struct.fields.len +
...@@ -18501,7 +18506,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18501,7 +18506,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18501 break :blk val.toIntern();18506 break :blk val.toIntern();
18502 } else .none;18507 } else .none;
1850318508
18504 const abi_align: InternPool.Alignment = if (inst_data.flags.has_align) blk: {18509 const abi_align: Alignment = if (inst_data.flags.has_align) blk: {
18505 const ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_i]);18510 const ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_i]);
18506 extra_i += 1;18511 extra_i += 1;
18507 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);18512 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);
...@@ -18517,7 +18522,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18517,7 +18522,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18517 }18522 }
18518 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);18523 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);
18519 try sema.validateAlign(block, align_src, abi_align);18524 try sema.validateAlign(block, align_src, abi_align);
18520 break :blk InternPool.Alignment.fromByteUnits(abi_align);18525 break :blk Alignment.fromByteUnits(abi_align);
18521 } else .none;18526 } else .none;
1852218527
18523 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {18528 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {
...@@ -18794,9 +18799,9 @@ fn zirStructInit(...@@ -18794,9 +18799,9 @@ fn zirStructInit(
1879418799
18795 if (is_ref) {18800 if (is_ref) {
18796 const target = mod.getTarget();18801 const target = mod.getTarget();
18797 const alloc_ty = try Type.ptr(sema.arena, mod, .{18802 const alloc_ty = try mod.ptrType(.{
18798 .pointee_type = resolved_ty,18803 .child = resolved_ty.toIntern(),
18799 .@"addrspace" = target_util.defaultAddressSpace(target, .local),18804 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
18800 });18805 });
18801 const alloc = try block.addTy(.alloc, alloc_ty);18806 const alloc = try block.addTy(.alloc, alloc_ty);
18802 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty, true);18807 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty, true);
...@@ -18917,9 +18922,9 @@ fn finishStructInit(...@@ -18917,9 +18922,9 @@ fn finishStructInit(
18917 if (is_ref) {18922 if (is_ref) {
18918 try sema.resolveStructLayout(struct_ty);18923 try sema.resolveStructLayout(struct_ty);
18919 const target = sema.mod.getTarget();18924 const target = sema.mod.getTarget();
18920 const alloc_ty = try Type.ptr(sema.arena, mod, .{18925 const alloc_ty = try mod.ptrType(.{
18921 .pointee_type = struct_ty,18926 .child = struct_ty.toIntern(),
18922 .@"addrspace" = target_util.defaultAddressSpace(target, .local),18927 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
18923 });18928 });
18924 const alloc = try block.addTy(.alloc, alloc_ty);18929 const alloc = try block.addTy(.alloc, alloc_ty);
18925 for (field_inits, 0..) |field_init, i_usize| {18930 for (field_inits, 0..) |field_init, i_usize| {
...@@ -19038,9 +19043,9 @@ fn zirStructInitAnon(...@@ -19038,9 +19043,9 @@ fn zirStructInitAnon(
1903819043
19039 if (is_ref) {19044 if (is_ref) {
19040 const target = mod.getTarget();19045 const target = mod.getTarget();
19041 const alloc_ty = try Type.ptr(sema.arena, mod, .{19046 const alloc_ty = try mod.ptrType(.{
19042 .pointee_type = tuple_ty.toType(),19047 .child = tuple_ty,
19043 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19048 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19044 });19049 });
19045 const alloc = try block.addTy(.alloc, alloc_ty);19050 const alloc = try block.addTy(.alloc, alloc_ty);
19046 var extra_index = extra.end;19051 var extra_index = extra.end;
...@@ -19049,10 +19054,9 @@ fn zirStructInitAnon(...@@ -19049,10 +19054,9 @@ fn zirStructInitAnon(
19049 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);19054 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);
19050 extra_index = item.end;19055 extra_index = item.end;
1905119056
19052 const field_ptr_ty = try Type.ptr(sema.arena, mod, .{19057 const field_ptr_ty = try mod.ptrType(.{
19053 .mutable = true,19058 .child = field_ty,
19054 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19059 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19055 .pointee_type = field_ty.toType(),
19056 });19060 });
19057 if (values[i] == .none) {19061 if (values[i] == .none) {
19058 const init = try sema.resolveInst(item.data.init);19062 const init = try sema.resolveInst(item.data.init);
...@@ -19150,18 +19154,17 @@ fn zirArrayInit(...@@ -19150,18 +19154,17 @@ fn zirArrayInit(
1915019154
19151 if (is_ref) {19155 if (is_ref) {
19152 const target = mod.getTarget();19156 const target = mod.getTarget();
19153 const alloc_ty = try Type.ptr(sema.arena, mod, .{19157 const alloc_ty = try mod.ptrType(.{
19154 .pointee_type = array_ty,19158 .child = array_ty.toIntern(),
19155 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19159 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19156 });19160 });
19157 const alloc = try block.addTy(.alloc, alloc_ty);19161 const alloc = try block.addTy(.alloc, alloc_ty);
1915819162
19159 if (array_ty.isTuple(mod)) {19163 if (array_ty.isTuple(mod)) {
19160 for (resolved_args, 0..) |arg, i| {19164 for (resolved_args, 0..) |arg, i| {
19161 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{19165 const elem_ptr_ty = try mod.ptrType(.{
19162 .mutable = true,19166 .child = array_ty.structFieldType(i, mod).toIntern(),
19163 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19167 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19164 .pointee_type = array_ty.structFieldType(i, mod),
19165 });19168 });
19166 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);19169 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1916719170
...@@ -19172,10 +19175,9 @@ fn zirArrayInit(...@@ -19172,10 +19175,9 @@ fn zirArrayInit(
19172 return sema.makePtrConst(block, alloc);19175 return sema.makePtrConst(block, alloc);
19173 }19176 }
1917419177
19175 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{19178 const elem_ptr_ty = try mod.ptrType(.{
19176 .mutable = true,19179 .child = array_ty.elemType2(mod).toIntern(),
19177 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19180 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19178 .pointee_type = array_ty.elemType2(mod),
19179 });19181 });
19180 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);19182 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1918119183
...@@ -19249,17 +19251,16 @@ fn zirArrayInitAnon(...@@ -19249,17 +19251,16 @@ fn zirArrayInitAnon(
1924919251
19250 if (is_ref) {19252 if (is_ref) {
19251 const target = sema.mod.getTarget();19253 const target = sema.mod.getTarget();
19252 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{19254 const alloc_ty = try mod.ptrType(.{
19253 .pointee_type = tuple_ty.toType(),19255 .child = tuple_ty,
19254 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19256 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19255 });19257 });
19256 const alloc = try block.addTy(.alloc, alloc_ty);19258 const alloc = try block.addTy(.alloc, alloc_ty);
19257 for (operands, 0..) |operand, i_usize| {19259 for (operands, 0..) |operand, i_usize| {
19258 const i = @intCast(u32, i_usize);19260 const i = @intCast(u32, i_usize);
19259 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{19261 const field_ptr_ty = try mod.ptrType(.{
19260 .mutable = true,19262 .child = types[i],
19261 .@"addrspace" = target_util.defaultAddressSpace(target, .local),19263 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
19262 .pointee_type = types[i].toType(),
19263 });19264 });
19264 if (values[i] == .none) {19265 if (values[i] == .none) {
19265 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);19266 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);
...@@ -19292,7 +19293,7 @@ fn addConstantMaybeRef(...@@ -19292,7 +19293,7 @@ fn addConstantMaybeRef(
19292 const decl = try anon_decl.finish(19293 const decl = try anon_decl.finish(
19293 ty,19294 ty,
19294 val,19295 val,
19295 0, // default alignment19296 .none, // default alignment
19296 );19297 );
19297 return sema.analyzeDeclRef(decl);19298 return sema.analyzeDeclRef(decl);
19298}19299}
...@@ -19387,7 +19388,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -19387,7 +19388,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
19387 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");19388 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
19388 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);19389 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
19389 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);19390 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
19390 const opt_ptr_stack_trace_ty = try Type.optional(sema.arena, ptr_stack_trace_ty, mod);19391 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());
1939119392
19392 if (sema.owner_func != null and19393 if (sema.owner_func != null and
19393 sema.owner_func.?.calls_or_awaits_errorable_fn and19394 sema.owner_func.?.calls_or_awaits_errorable_fn and
...@@ -19707,7 +19708,7 @@ fn zirReify(...@@ -19707,7 +19708,7 @@ fn zirReify(
19707 return sema.fail(block, src, "alignment must fit in 'u32'", .{});19708 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
19708 }19709 }
1970919710
19710 const abi_align = InternPool.Alignment.fromByteUnits(19711 const abi_align = Alignment.fromByteUnits(
19711 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,19712 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,
19712 );19713 );
1971319714
...@@ -19728,10 +19729,7 @@ fn zirReify(...@@ -19728,10 +19729,7 @@ fn zirReify(
19728 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});19729 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
19729 }19730 }
19730 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;19731 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;
19731 const ptr_ty = try Type.ptr(sema.arena, mod, .{19732 const ptr_ty = try mod.singleMutPtrType(elem_ty);
19732 .@"addrspace" = .generic,
19733 .pointee_type = elem_ty,
19734 });
19735 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;19733 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
19736 break :s sent_val.toIntern();19734 break :s sent_val.toIntern();
19737 }19735 }
...@@ -19800,14 +19798,15 @@ fn zirReify(...@@ -19800,14 +19798,15 @@ fn zirReify(
19800 const len = len_val.toUnsignedInt(mod);19798 const len = len_val.toUnsignedInt(mod);
19801 const child_ty = child_val.toType();19799 const child_ty = child_val.toType();
19802 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {19800 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
19803 const ptr_ty = try Type.ptr(sema.arena, mod, .{19801 const ptr_ty = try mod.singleMutPtrType(child_ty);
19804 .@"addrspace" = .generic,
19805 .pointee_type = child_ty,
19806 });
19807 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;19802 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;
19808 } else null;19803 } else null;
1980919804
19810 const ty = try Type.array(sema.arena, len, sentinel, child_ty, mod);19805 const ty = try mod.arrayType(.{
19806 .len = len,
19807 .sentinel = if (sentinel) |s| s.toIntern() else .none,
19808 .child = child_ty.toIntern(),
19809 });
19811 return sema.addType(ty);19810 return sema.addType(ty);
19812 },19811 },
19813 .Optional => {19812 .Optional => {
...@@ -19818,7 +19817,7 @@ fn zirReify(...@@ -19818,7 +19817,7 @@ fn zirReify(
1981819817
19819 const child_ty = child_val.toType();19818 const child_ty = child_val.toType();
1982019819
19821 const ty = try Type.optional(sema.arena, child_ty, mod);19820 const ty = try mod.optionalType(child_ty.toIntern());
19822 return sema.addType(ty);19821 return sema.addType(ty);
19823 },19822 },
19824 .ErrorUnion => {19823 .ErrorUnion => {
...@@ -20199,7 +20198,7 @@ fn zirReify(...@@ -20199,7 +20198,7 @@ fn zirReify(
20199 const field_ty = type_val.toType();20198 const field_ty = type_val.toType();
20200 gop.value_ptr.* = .{20199 gop.value_ptr.* = .{
20201 .ty = field_ty,20200 .ty = field_ty,
20202 .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),20201 .abi_align = Alignment.fromByteUnits((try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),
20203 };20202 };
2020420203
20205 if (field_ty.zigTypeTag(mod) == .Opaque) {20204 if (field_ty.zigTypeTag(mod) == .Opaque) {
...@@ -20306,7 +20305,7 @@ fn zirReify(...@@ -20306,7 +20305,7 @@ fn zirReify(
20306 if (alignment == target_util.defaultFunctionAlignment(target)) {20305 if (alignment == target_util.defaultFunctionAlignment(target)) {
20307 break :alignment .none;20306 break :alignment .none;
20308 } else {20307 } else {
20309 break :alignment InternPool.Alignment.fromByteUnits(alignment);20308 break :alignment Alignment.fromByteUnits(alignment);
20310 }20309 }
20311 };20310 };
20312 const return_type = return_type_val.optionalValue(mod) orelse20311 const return_type = return_type_val.optionalValue(mod) orelse
...@@ -20455,7 +20454,7 @@ fn reifyStruct(...@@ -20455,7 +20454,7 @@ fn reifyStruct(
20455 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {20454 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
20456 return sema.fail(block, src, "alignment must fit in 'u32'", .{});20455 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
20457 }20456 }
20458 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?);20457 const abi_align = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
2045920458
20460 if (layout == .Packed) {20459 if (layout == .Packed) {
20461 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});20460 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
...@@ -20502,7 +20501,7 @@ fn reifyStruct(...@@ -20502,7 +20501,7 @@ fn reifyStruct(
2050220501
20503 gop.value_ptr.* = .{20502 gop.value_ptr.* = .{
20504 .ty = field_ty,20503 .ty = field_ty,
20505 .abi_align = abi_align,20504 .abi_align = Alignment.fromByteUnits(abi_align),
20506 .default_val = default_val,20505 .default_val = default_val,
20507 .is_comptime = is_comptime_val.toBool(),20506 .is_comptime = is_comptime_val.toBool(),
20508 .offset = undefined,20507 .offset = undefined,
...@@ -20604,7 +20603,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -20604,7 +20603,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
20604 try sema.checkPtrOperand(block, ptr_src, ptr_ty);20603 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
2060520604
20606 var ptr_info = ptr_ty.ptrInfo(mod);20605 var ptr_info = ptr_ty.ptrInfo(mod);
20607 const src_addrspace = ptr_info.@"addrspace";20606 const src_addrspace = ptr_info.flags.address_space;
20608 if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) {20607 if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) {
20609 const msg = msg: {20608 const msg = msg: {
20610 const msg = try sema.errMsg(block, src, "invalid address space cast", .{});20609 const msg = try sema.errMsg(block, src, "invalid address space cast", .{});
...@@ -20615,10 +20614,10 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -20615,10 +20614,10 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
20615 return sema.failWithOwnedErrorMsg(msg);20614 return sema.failWithOwnedErrorMsg(msg);
20616 }20615 }
2061720616
20618 ptr_info.@"addrspace" = dest_addrspace;20617 ptr_info.flags.address_space = dest_addrspace;
20619 const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);20618 const dest_ptr_ty = try mod.ptrType(ptr_info);
20620 const dest_ty = if (ptr_ty.zigTypeTag(mod) == .Optional)20619 const dest_ty = if (ptr_ty.zigTypeTag(mod) == .Optional)
20621 try Type.optional(sema.arena, dest_ptr_ty, mod)20620 try mod.optionalType(dest_ptr_ty.toIntern())
20622 else20621 else
20623 dest_ptr_ty;20622 dest_ptr_ty;
2062420623
...@@ -20636,11 +20635,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -20636,11 +20635,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2063620635
20637fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {20636fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
20638 const va_list_ty = try sema.getBuiltinType("VaList");20637 const va_list_ty = try sema.getBuiltinType("VaList");
20639 const va_list_ptr = try Type.ptr(sema.arena, sema.mod, .{20638 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);
20640 .pointee_type = va_list_ty,
20641 .mutable = true,
20642 .@"addrspace" = .generic,
20643 });
2064420639
20645 const inst = try sema.resolveInst(zir_ref);20640 const inst = try sema.resolveInst(zir_ref);
20646 return sema.coerce(block, va_list_ptr, inst, src);20641 return sema.coerce(block, va_list_ptr, inst, src);
...@@ -20717,20 +20712,22 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20717,20 +20712,22 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20717 var anon_decl = try block.startAnonDecl();20712 var anon_decl = try block.startAnonDecl();
20718 defer anon_decl.deinit();20713 defer anon_decl.deinit();
2071920714
20720 const bytes = try ty.nameAllocArena(sema.arena, mod);20715 var bytes = std.ArrayList(u8).init(sema.arena);
20716 defer bytes.deinit();
20717 try ty.print(bytes.writer(), mod);
2072120718
20722 const decl_ty = try mod.arrayType(.{20719 const decl_ty = try mod.arrayType(.{
20723 .len = bytes.len,20720 .len = bytes.items.len,
20724 .child = .u8_type,
20725 .sentinel = .zero_u8,20721 .sentinel = .zero_u8,
20722 .child = .u8_type,
20726 });20723 });
20727 const new_decl = try anon_decl.finish(20724 const new_decl = try anon_decl.finish(
20728 decl_ty,20725 decl_ty,
20729 (try mod.intern(.{ .aggregate = .{20726 (try mod.intern(.{ .aggregate = .{
20730 .ty = decl_ty.toIntern(),20727 .ty = decl_ty.toIntern(),
20731 .storage = .{ .bytes = bytes },20728 .storage = .{ .bytes = bytes.items },
20732 } })).toValue(),20729 } })).toValue(),
20733 0, // default alignment20730 .none, // default alignment
20734 );20731 );
2073520732
20736 return sema.analyzeDeclRef(new_decl);20733 return sema.analyzeDeclRef(new_decl);
...@@ -20981,7 +20978,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20981,7 +20978,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2098120978
20982 const operand_info = operand_ty.ptrInfo(mod);20979 const operand_info = operand_ty.ptrInfo(mod);
20983 const dest_info = dest_ty.ptrInfo(mod);20980 const dest_info = dest_ty.ptrInfo(mod);
20984 if (!operand_info.mutable and dest_info.mutable) {20981 if (operand_info.flags.is_const and !dest_info.flags.is_const) {
20985 const msg = msg: {20982 const msg = msg: {
20986 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});20983 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});
20987 errdefer msg.destroy(sema.gpa);20984 errdefer msg.destroy(sema.gpa);
...@@ -20991,7 +20988,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20991,7 +20988,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20991 };20988 };
20992 return sema.failWithOwnedErrorMsg(msg);20989 return sema.failWithOwnedErrorMsg(msg);
20993 }20990 }
20994 if (operand_info.@"volatile" and !dest_info.@"volatile") {20991 if (operand_info.flags.is_volatile and !dest_info.flags.is_volatile) {
20995 const msg = msg: {20992 const msg = msg: {
20996 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});20993 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});
20997 errdefer msg.destroy(sema.gpa);20994 errdefer msg.destroy(sema.gpa);
...@@ -21001,7 +20998,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21001,7 +20998,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21001 };20998 };
21002 return sema.failWithOwnedErrorMsg(msg);20999 return sema.failWithOwnedErrorMsg(msg);
21003 }21000 }
21004 if (operand_info.@"addrspace" != dest_info.@"addrspace") {21001 if (operand_info.flags.address_space != dest_info.flags.address_space) {
21005 const msg = msg: {21002 const msg = msg: {
21006 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});21003 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
21007 errdefer msg.destroy(sema.gpa);21004 errdefer msg.destroy(sema.gpa);
...@@ -21033,14 +21030,12 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21033,14 +21030,12 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21033 // If the destination is less aligned than the source, preserve the source alignment21030 // If the destination is less aligned than the source, preserve the source alignment
21034 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {21031 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
21035 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result21032 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result
21033 var dest_ptr_info = dest_ty.ptrInfo(mod);
21034 dest_ptr_info.flags.alignment = Alignment.fromNonzeroByteUnits(operand_align);
21036 if (dest_ty.zigTypeTag(mod) == .Optional) {21035 if (dest_ty.zigTypeTag(mod) == .Optional) {
21037 var dest_ptr_info = dest_ty.optionalChild(mod).ptrInfo(mod);21036 break :blk try mod.optionalType((try mod.ptrType(dest_ptr_info)).toIntern());
21038 dest_ptr_info.@"align" = operand_align;
21039 break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, mod, dest_ptr_info), mod);
21040 } else {21037 } else {
21041 var dest_ptr_info = dest_ty.ptrInfo(mod);21038 break :blk try mod.ptrType(dest_ptr_info);
21042 dest_ptr_info.@"align" = operand_align;
21043 break :blk try Type.ptr(sema.arena, mod, dest_ptr_info);
21044 }21039 }
21045 };21040 };
2104621041
...@@ -21107,8 +21102,8 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -21107,8 +21102,8 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
21107 try sema.checkPtrOperand(block, operand_src, operand_ty);21102 try sema.checkPtrOperand(block, operand_src, operand_ty);
2110821103
21109 var ptr_info = operand_ty.ptrInfo(mod);21104 var ptr_info = operand_ty.ptrInfo(mod);
21110 ptr_info.mutable = true;21105 ptr_info.flags.is_const = false;
21111 const dest_ty = try Type.ptr(sema.arena, mod, ptr_info);21106 const dest_ty = try mod.ptrType(ptr_info);
2111221107
21113 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {21108 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
21114 return sema.addConstant(dest_ty, try mod.getCoerced(operand_val, dest_ty));21109 return sema.addConstant(dest_ty, try mod.getCoerced(operand_val, dest_ty));
...@@ -21128,8 +21123,8 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -21128,8 +21123,8 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
21128 try sema.checkPtrOperand(block, operand_src, operand_ty);21123 try sema.checkPtrOperand(block, operand_src, operand_ty);
2112921124
21130 var ptr_info = operand_ty.ptrInfo(mod);21125 var ptr_info = operand_ty.ptrInfo(mod);
21131 ptr_info.@"volatile" = false;21126 ptr_info.flags.is_volatile = false;
21132 const dest_ty = try Type.ptr(sema.arena, mod, ptr_info);21127 const dest_ty = try mod.ptrType(ptr_info);
2113321128
21134 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {21129 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
21135 return sema.addConstant(dest_ty, operand_val);21130 return sema.addConstant(dest_ty, operand_val);
...@@ -21238,28 +21233,29 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -21238,28 +21233,29 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
21238 try sema.checkPtrOperand(block, ptr_src, ptr_ty);21233 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
2123921234
21240 var ptr_info = ptr_ty.ptrInfo(mod);21235 var ptr_info = ptr_ty.ptrInfo(mod);
21241 ptr_info.@"align" = dest_align;21236 ptr_info.flags.alignment = dest_align;
21242 var dest_ty = try Type.ptr(sema.arena, mod, ptr_info);21237 var dest_ty = try mod.ptrType(ptr_info);
21243 if (ptr_ty.zigTypeTag(mod) == .Optional) {21238 if (ptr_ty.zigTypeTag(mod) == .Optional) {
21244 dest_ty = try mod.optionalType(dest_ty.toIntern());21239 dest_ty = try mod.optionalType(dest_ty.toIntern());
21245 }21240 }
2124621241
21247 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {21242 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {
21248 if (try val.getUnsignedIntAdvanced(mod, null)) |addr| {21243 if (try val.getUnsignedIntAdvanced(mod, null)) |addr| {
21249 if (addr % dest_align != 0) {21244 const dest_align_bytes = dest_align.toByteUnitsOptional().?;
21250 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });21245 if (addr % dest_align_bytes != 0) {
21246 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align_bytes });
21251 }21247 }
21252 }21248 }
21253 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));21249 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
21254 }21250 }
2125521251
21256 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);21252 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
21257 if (block.wantSafety() and dest_align > 1 and21253 if (block.wantSafety() and dest_align.order(Alignment.fromNonzeroByteUnits(1)).compare(.gt) and
21258 try sema.typeHasRuntimeBits(ptr_info.pointee_type))21254 try sema.typeHasRuntimeBits(ptr_info.child.toType()))
21259 {21255 {
21260 const align_minus_1 = try sema.addConstant(21256 const align_minus_1 = try sema.addConstant(
21261 Type.usize,21257 Type.usize,
21262 try mod.intValue(Type.usize, dest_align - 1),21258 try mod.intValue(Type.usize, dest_align.toByteUnitsOptional().? - 1),
21263 );21259 );
21264 const actual_ptr = if (ptr_ty.isSlice(mod))21260 const actual_ptr = if (ptr_ty.isSlice(mod))
21265 try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)21261 try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)
...@@ -21704,28 +21700,29 @@ fn checkAtomicPtrOperand(...@@ -21704,28 +21700,29 @@ fn checkAtomicPtrOperand(
21704 ),21700 ),
21705 };21701 };
2170621702
21707 var wanted_ptr_data: Type.Payload.Pointer.Data = .{21703 var wanted_ptr_data: InternPool.Key.PtrType = .{
21708 .pointee_type = elem_ty,21704 .child = elem_ty.toIntern(),
21709 .@"align" = alignment,21705 .flags = .{
21710 .@"addrspace" = .generic,21706 .alignment = alignment,
21711 .mutable = !ptr_const,21707 .is_const = ptr_const,
21708 },
21712 };21709 };
2171321710
21714 const ptr_ty = sema.typeOf(ptr);21711 const ptr_ty = sema.typeOf(ptr);
21715 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {21712 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
21716 .Pointer => ptr_ty.ptrInfo(mod),21713 .Pointer => ptr_ty.ptrInfo(mod),
21717 else => {21714 else => {
21718 const wanted_ptr_ty = try Type.ptr(sema.arena, mod, wanted_ptr_data);21715 const wanted_ptr_ty = try mod.ptrType(wanted_ptr_data);
21719 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);21716 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
21720 unreachable;21717 unreachable;
21721 },21718 },
21722 };21719 };
2172321720
21724 wanted_ptr_data.@"addrspace" = ptr_data.@"addrspace";21721 wanted_ptr_data.flags.address_space = ptr_data.flags.address_space;
21725 wanted_ptr_data.@"allowzero" = ptr_data.@"allowzero";21722 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
21726 wanted_ptr_data.@"volatile" = ptr_data.@"volatile";21723 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;
2172721724
21728 const wanted_ptr_ty = try Type.ptr(sema.arena, mod, wanted_ptr_data);21725 const wanted_ptr_ty = try mod.ptrType(wanted_ptr_data);
21729 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);21726 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2173021727
21731 return casted_ptr;21728 return casted_ptr;
...@@ -22078,7 +22075,7 @@ fn zirCmpxchg(...@@ -22078,7 +22075,7 @@ fn zirCmpxchg(
22078 return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{});22075 return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{});
22079 }22076 }
2208022077
22081 const result_ty = try Type.optional(sema.arena, elem_ty, mod);22078 const result_ty = try mod.optionalType(elem_ty.toIntern());
2208222079
22083 // special case zero bit types22080 // special case zero bit types
22084 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {22081 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {
...@@ -22844,31 +22841,33 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -22844,31 +22841,33 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
22844 try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);22841 try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);
22845 const field_ptr_ty_info = field_ptr_ty.ptrInfo(mod);22842 const field_ptr_ty_info = field_ptr_ty.ptrInfo(mod);
2284622843
22847 var ptr_ty_data: Type.Payload.Pointer.Data = .{22844 var ptr_ty_data: InternPool.Key.PtrType = .{
22848 .pointee_type = parent_ty.structFieldType(field_index, mod),22845 .child = parent_ty.structFieldType(field_index, mod).toIntern(),
22849 .mutable = field_ptr_ty_info.mutable,22846 .flags = .{
22850 .@"addrspace" = field_ptr_ty_info.@"addrspace",22847 .address_space = field_ptr_ty_info.flags.address_space,
22848 .is_const = field_ptr_ty_info.flags.is_const,
22849 },
22851 };22850 };
2285222851
22853 if (parent_ty.containerLayout(mod) == .Packed) {22852 if (parent_ty.containerLayout(mod) == .Packed) {
22854 return sema.fail(block, src, "TODO handle packed structs/unions with @fieldParentPtr", .{});22853 return sema.fail(block, src, "TODO handle packed structs/unions with @fieldParentPtr", .{});
22855 } else {22854 } else {
22856 ptr_ty_data.@"align" = blk: {22855 ptr_ty_data.flags.alignment = blk: {
22857 if (mod.typeToStruct(parent_ty)) |struct_obj| {22856 if (mod.typeToStruct(parent_ty)) |struct_obj| {
22858 break :blk struct_obj.fields.values()[field_index].abi_align;22857 break :blk struct_obj.fields.values()[field_index].abi_align;
22859 } else if (mod.typeToUnion(parent_ty)) |union_obj| {22858 } else if (mod.typeToUnion(parent_ty)) |union_obj| {
22860 break :blk union_obj.fields.values()[field_index].abi_align;22859 break :blk union_obj.fields.values()[field_index].abi_align;
22861 } else {22860 } else {
22862 break :blk 0;22861 break :blk .none;
22863 }22862 }
22864 };22863 };
22865 }22864 }
2286622865
22867 const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);22866 const actual_field_ptr_ty = try mod.ptrType(ptr_ty_data);
22868 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);22867 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
2286922868
22870 ptr_ty_data.pointee_type = parent_ty;22869 ptr_ty_data.child = parent_ty.toIntern();
22871 const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);22870 const result_ptr = try mod.ptrType(ptr_ty_data);
2287222871
22873 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {22872 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
22874 const field = switch (ip.indexToKey(field_ptr_val.toIntern())) {22873 const field = switch (ip.indexToKey(field_ptr_val.toIntern())) {
...@@ -23191,21 +23190,25 @@ fn analyzeMinMax(...@@ -23191,21 +23190,25 @@ fn analyzeMinMax(
23191fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {23190fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {
23192 const mod = sema.mod;23191 const mod = sema.mod;
23193 const info = sema.typeOf(ptr).ptrInfo(mod);23192 const info = sema.typeOf(ptr).ptrInfo(mod);
23194 if (info.size == .One) {23193 if (info.flags.size == .One) {
23195 // Already an array pointer.23194 // Already an array pointer.
23196 return ptr;23195 return ptr;
23197 }23196 }
23198 const new_ty = try Type.ptr(sema.arena, mod, .{23197 const new_ty = try mod.ptrType(.{
23199 .pointee_type = try Type.array(sema.arena, len, info.sentinel, info.pointee_type, mod),23198 .child = (try mod.arrayType(.{
23200 .sentinel = null,23199 .len = len,
23201 .@"align" = info.@"align",23200 .sentinel = info.sentinel,
23202 .@"addrspace" = info.@"addrspace",23201 .child = info.child,
23203 .mutable = info.mutable,23202 })).toIntern(),
23204 .@"allowzero" = info.@"allowzero",23203 .flags = .{
23205 .@"volatile" = info.@"volatile",23204 .alignment = info.flags.alignment,
23206 .size = .One,23205 .is_const = info.flags.is_const,
23206 .is_volatile = info.flags.is_volatile,
23207 .is_allowzero = info.flags.is_allowzero,
23208 .address_space = info.flags.address_space,
23209 },
23207 });23210 });
23208 if (info.size == .Slice) {23211 if (info.flags.size == .Slice) {
23209 return block.addTyOp(.slice_ptr, new_ty, ptr);23212 return block.addTyOp(.slice_ptr, new_ty, ptr);
23210 }23213 }
23211 return block.addBitCast(new_ty, ptr);23214 return block.addBitCast(new_ty, ptr);
...@@ -23623,7 +23626,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -23623,7 +23626,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
23623 return sema.fail(block, align_src, "target does not support function alignment", .{});23626 return sema.fail(block, align_src, "target does not support function alignment", .{});
23624 }23627 }
2362523628
23626 const @"align": ?u32 = if (extra.data.bits.has_align_body) blk: {23629 const @"align": ?Alignment = if (extra.data.bits.has_align_body) blk: {
23627 const body_len = sema.code.extra[extra_index];23630 const body_len = sema.code.extra[extra_index];
23628 extra_index += 1;23631 extra_index += 1;
23629 const body = sema.code.extra[extra_index..][0..body_len];23632 const body = sema.code.extra[extra_index..][0..body_len];
...@@ -23636,9 +23639,9 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -23636,9 +23639,9 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
23636 const alignment = @intCast(u32, val.toUnsignedInt(mod));23639 const alignment = @intCast(u32, val.toUnsignedInt(mod));
23637 try sema.validateAlign(block, align_src, alignment);23640 try sema.validateAlign(block, align_src, alignment);
23638 if (alignment == target_util.defaultFunctionAlignment(target)) {23641 if (alignment == target_util.defaultFunctionAlignment(target)) {
23639 break :blk 0;23642 break :blk .none;
23640 } else {23643 } else {
23641 break :blk alignment;23644 break :blk Alignment.fromNonzeroByteUnits(alignment);
23642 }23645 }
23643 } else if (extra.data.bits.has_align_ref) blk: {23646 } else if (extra.data.bits.has_align_ref) blk: {
23644 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);23647 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);
...@@ -23652,11 +23655,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -23652,11 +23655,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
23652 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod));23655 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod));
23653 try sema.validateAlign(block, align_src, alignment);23656 try sema.validateAlign(block, align_src, alignment);
23654 if (alignment == target_util.defaultFunctionAlignment(target)) {23657 if (alignment == target_util.defaultFunctionAlignment(target)) {
23655 break :blk 0;23658 break :blk .none;
23656 } else {23659 } else {
23657 break :blk alignment;23660 break :blk Alignment.fromNonzeroByteUnits(alignment);
23658 }23661 }
23659 } else 0;23662 } else .none;
2366023663
23661 const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: {23664 const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: {
23662 const body_len = sema.code.extra[extra_index];23665 const body_len = sema.code.extra[extra_index];
...@@ -24051,7 +24054,7 @@ fn zirBuiltinExtern(...@@ -24051,7 +24054,7 @@ fn zirBuiltinExtern(
24051 };24054 };
2405224055
24053 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {24056 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {
24054 ty = try Type.optional(sema.arena, ty, mod);24057 ty = try mod.optionalType(ty.toIntern());
24055 }24058 }
2405624059
24057 // TODO check duplicate extern24060 // TODO check duplicate extern
...@@ -24077,7 +24080,7 @@ fn zirBuiltinExtern(...@@ -24077,7 +24080,7 @@ fn zirBuiltinExtern(
24077 // below, so this type doesn't matter24080 // below, so this type doesn't matter
24078 new_decl.ty = ty;24081 new_decl.ty = ty;
24079 new_decl.val = new_var.toValue();24082 new_decl.val = new_var.toValue();
24080 new_decl.@"align" = 0;24083 new_decl.alignment = .none;
24081 new_decl.@"linksection" = .none;24084 new_decl.@"linksection" = .none;
24082 new_decl.has_tv = true;24085 new_decl.has_tv = true;
24083 new_decl.analysis = .complete;24086 new_decl.analysis = .complete;
...@@ -24967,18 +24970,19 @@ fn fieldVal(...@@ -24967,18 +24970,19 @@ fn fieldVal(
24967 );24970 );
24968 } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {24971 } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {
24969 const ptr_info = object_ty.ptrInfo(mod);24972 const ptr_info = object_ty.ptrInfo(mod);
24970 const result_ty = try Type.ptr(sema.arena, mod, .{24973 const result_ty = try mod.ptrType(.{
24971 .pointee_type = ptr_info.pointee_type.childType(mod),24974 .child = ptr_info.child.toType().childType(mod).toIntern(),
24972 .sentinel = ptr_info.sentinel,24975 .sentinel = ptr_info.sentinel,
24973 .@"align" = ptr_info.@"align",24976 .flags = .{
24974 .@"addrspace" = ptr_info.@"addrspace",24977 .size = .Many,
24975 .bit_offset = ptr_info.bit_offset,24978 .alignment = ptr_info.flags.alignment,
24976 .host_size = ptr_info.host_size,24979 .is_const = ptr_info.flags.is_const,
24977 .vector_index = ptr_info.vector_index,24980 .is_volatile = ptr_info.flags.is_volatile,
24978 .@"allowzero" = ptr_info.@"allowzero",24981 .is_allowzero = ptr_info.flags.is_allowzero,
24979 .mutable = ptr_info.mutable,24982 .address_space = ptr_info.flags.address_space,
24980 .@"volatile" = ptr_info.@"volatile",24983 .vector_index = ptr_info.flags.vector_index,
24981 .size = .Many,24984 },
24985 .packed_offset = ptr_info.packed_offset,
24982 });24986 });
24983 return sema.coerce(block, result_ty, object, src);24987 return sema.coerce(block, result_ty, object, src);
24984 } else {24988 } else {
...@@ -24992,7 +24996,7 @@ fn fieldVal(...@@ -24992,7 +24996,7 @@ fn fieldVal(
24992 },24996 },
24993 .Pointer => {24997 .Pointer => {
24994 const ptr_info = inner_ty.ptrInfo(mod);24998 const ptr_info = inner_ty.ptrInfo(mod);
24995 if (ptr_info.size == .Slice) {24999 if (ptr_info.flags.size == .Slice) {
24996 if (ip.stringEqlSlice(field_name, "ptr")) {25000 if (ip.stringEqlSlice(field_name, "ptr")) {
24997 const slice = if (is_pointer_to)25001 const slice = if (is_pointer_to)
24998 try sema.analyzeLoad(block, src, object, object_src)25002 try sema.analyzeLoad(block, src, object, object_src)
...@@ -25166,7 +25170,7 @@ fn fieldPtr(...@@ -25166,7 +25170,7 @@ fn fieldPtr(
25166 return sema.analyzeDeclRef(try anon_decl.finish(25170 return sema.analyzeDeclRef(try anon_decl.finish(
25167 Type.usize,25171 Type.usize,
25168 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),25172 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
25169 0, // default alignment25173 .none, // default alignment
25170 ));25174 ));
25171 } else {25175 } else {
25172 return sema.fail(25176 return sema.fail(
...@@ -25188,11 +25192,13 @@ fn fieldPtr(...@@ -25188,11 +25192,13 @@ fn fieldPtr(
25188 if (ip.stringEqlSlice(field_name, "ptr")) {25192 if (ip.stringEqlSlice(field_name, "ptr")) {
25189 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);25193 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2519025194
25191 const result_ty = try Type.ptr(sema.arena, mod, .{25195 const result_ty = try mod.ptrType(.{
25192 .pointee_type = slice_ptr_ty,25196 .child = slice_ptr_ty.toIntern(),
25193 .mutable = attr_ptr_ty.ptrIsMutable(mod),25197 .flags = .{
25194 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),25198 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
25195 .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),25199 .is_volatile = attr_ptr_ty.isVolatilePtr(mod),
25200 .address_space = attr_ptr_ty.ptrAddressSpace(mod),
25201 },
25196 });25202 });
2519725203
25198 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {25204 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
...@@ -25208,11 +25214,13 @@ fn fieldPtr(...@@ -25208,11 +25214,13 @@ fn fieldPtr(
2520825214
25209 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);25215 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
25210 } else if (ip.stringEqlSlice(field_name, "len")) {25216 } else if (ip.stringEqlSlice(field_name, "len")) {
25211 const result_ty = try Type.ptr(sema.arena, mod, .{25217 const result_ty = try mod.ptrType(.{
25212 .pointee_type = Type.usize,25218 .child = .usize_type,
25213 .mutable = attr_ptr_ty.ptrIsMutable(mod),25219 .flags = .{
25214 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),25220 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
25215 .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),25221 .is_volatile = attr_ptr_ty.isVolatilePtr(mod),
25222 .address_space = attr_ptr_ty.ptrAddressSpace(mod),
25223 },
25216 });25224 });
2521725225
25218 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {25226 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
...@@ -25280,7 +25288,7 @@ fn fieldPtr(...@@ -25280,7 +25288,7 @@ fn fieldPtr(
25280 .ty = error_set_type.toIntern(),25288 .ty = error_set_type.toIntern(),
25281 .name = field_name,25289 .name = field_name,
25282 } })).toValue(),25290 } })).toValue(),
25283 0, // default alignment25291 .none, // default alignment
25284 ));25292 ));
25285 },25293 },
25286 .Union => {25294 .Union => {
...@@ -25298,7 +25306,7 @@ fn fieldPtr(...@@ -25298,7 +25306,7 @@ fn fieldPtr(
25298 return sema.analyzeDeclRef(try anon_decl.finish(25306 return sema.analyzeDeclRef(try anon_decl.finish(
25299 enum_ty,25307 enum_ty,
25300 try mod.enumValueFieldIndex(enum_ty, field_index_u32),25308 try mod.enumValueFieldIndex(enum_ty, field_index_u32),
25301 0, // default alignment25309 .none, // default alignment
25302 ));25310 ));
25303 }25311 }
25304 }25312 }
...@@ -25319,7 +25327,7 @@ fn fieldPtr(...@@ -25319,7 +25327,7 @@ fn fieldPtr(
25319 return sema.analyzeDeclRef(try anon_decl.finish(25327 return sema.analyzeDeclRef(try anon_decl.finish(
25320 child_type,25328 child_type,
25321 try mod.enumValueFieldIndex(child_type, field_index_u32),25329 try mod.enumValueFieldIndex(child_type, field_index_u32),
25322 0, // default alignment25330 .none, // default alignment
25323 ));25331 ));
25324 },25332 },
25325 .Struct, .Opaque => {25333 .Struct, .Opaque => {
...@@ -25533,11 +25541,12 @@ fn finishFieldCallBind(...@@ -25533,11 +25541,12 @@ fn finishFieldCallBind(
25533 object_ptr: Air.Inst.Ref,25541 object_ptr: Air.Inst.Ref,
25534) CompileError!ResolvedFieldCallee {25542) CompileError!ResolvedFieldCallee {
25535 const mod = sema.mod;25543 const mod = sema.mod;
25536 const arena = sema.arena;25544 const ptr_field_ty = try mod.ptrType(.{
25537 const ptr_field_ty = try Type.ptr(arena, mod, .{25545 .child = field_ty.toIntern(),
25538 .pointee_type = field_ty,25546 .flags = .{
25539 .mutable = ptr_ty.ptrIsMutable(mod),25547 .is_const = !ptr_ty.ptrIsMutable(mod),
25540 .@"addrspace" = ptr_ty.ptrAddressSpace(mod),25548 .address_space = ptr_ty.ptrAddressSpace(mod),
25549 },
25541 });25550 });
2554225551
25543 const container_ty = ptr_ty.childType(mod);25552 const container_ty = ptr_ty.childType(mod);
...@@ -25670,11 +25679,13 @@ fn structFieldPtrByIndex(...@@ -25670,11 +25679,13 @@ fn structFieldPtrByIndex(
25670 const struct_ptr_ty = sema.typeOf(struct_ptr);25679 const struct_ptr_ty = sema.typeOf(struct_ptr);
25671 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);25680 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);
2567225681
25673 var ptr_ty_data: Type.Payload.Pointer.Data = .{25682 var ptr_ty_data: InternPool.Key.PtrType = .{
25674 .pointee_type = field.ty,25683 .child = field.ty.toIntern(),
25675 .mutable = struct_ptr_ty_info.mutable,25684 .flags = .{
25676 .@"volatile" = struct_ptr_ty_info.@"volatile",25685 .is_const = struct_ptr_ty_info.flags.is_const,
25677 .@"addrspace" = struct_ptr_ty_info.@"addrspace",25686 .is_volatile = struct_ptr_ty_info.flags.is_volatile,
25687 .address_space = struct_ptr_ty_info.flags.address_space,
25688 },
25678 };25689 };
2567925690
25680 const target = mod.getTarget();25691 const target = mod.getTarget();
...@@ -25687,24 +25698,22 @@ fn structFieldPtrByIndex(...@@ -25687,24 +25698,22 @@ fn structFieldPtrByIndex(
25687 if (!(try sema.typeHasRuntimeBits(f.ty))) continue;25698 if (!(try sema.typeHasRuntimeBits(f.ty))) continue;
2568825699
25689 if (i == field_index) {25700 if (i == field_index) {
25690 ptr_ty_data.bit_offset = running_bits;25701 ptr_ty_data.packed_offset.bit_offset = running_bits;
25691 }25702 }
25692 running_bits += @intCast(u16, f.ty.bitSize(mod));25703 running_bits += @intCast(u16, f.ty.bitSize(mod));
25693 }25704 }
25694 ptr_ty_data.host_size = (running_bits + 7) / 8;25705 ptr_ty_data.packed_offset.host_size = (running_bits + 7) / 8;
2569525706
25696 // If this is a packed struct embedded in another one, we need to offset25707 // If this is a packed struct embedded in another one, we need to offset
25697 // the bits against each other.25708 // the bits against each other.
25698 if (struct_ptr_ty_info.host_size != 0) {25709 if (struct_ptr_ty_info.packed_offset.host_size != 0) {
25699 ptr_ty_data.host_size = struct_ptr_ty_info.host_size;25710 ptr_ty_data.packed_offset.host_size = struct_ptr_ty_info.packed_offset.host_size;
25700 ptr_ty_data.bit_offset += struct_ptr_ty_info.bit_offset;25711 ptr_ty_data.packed_offset.bit_offset += struct_ptr_ty_info.packed_offset.bit_offset;
25701 }25712 }
2570225713
25703 const parent_align = if (struct_ptr_ty_info.@"align" != 0)25714 const parent_align = struct_ptr_ty_info.flags.alignment.toByteUnitsOptional() orelse
25704 struct_ptr_ty_info.@"align"25715 struct_ptr_ty_info.child.toType().abiAlignment(mod);
25705 else25716 ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align);
25706 struct_ptr_ty_info.pointee_type.abiAlignment(mod);
25707 ptr_ty_data.@"align" = parent_align;
2570825717
25709 // If the field happens to be byte-aligned, simplify the pointer type.25718 // If the field happens to be byte-aligned, simplify the pointer type.
25710 // The pointee type bit size must match its ABI byte size so that loads and stores25719 // The pointee type bit size must match its ABI byte size so that loads and stores
...@@ -25714,24 +25723,24 @@ fn structFieldPtrByIndex(...@@ -25714,24 +25723,24 @@ fn structFieldPtrByIndex(
25714 // targets before adding the necessary complications to this code. This will not25723 // targets before adding the necessary complications to this code. This will not
25715 // cause miscompilations; it only means the field pointer uses bit masking when it25724 // cause miscompilations; it only means the field pointer uses bit masking when it
25716 // might not be strictly necessary.25725 // might not be strictly necessary.
25717 if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0 and25726 if (parent_align != 0 and ptr_ty_data.packed_offset.bit_offset % 8 == 0 and
25718 target.cpu.arch.endian() == .Little)25727 target.cpu.arch.endian() == .Little)
25719 {25728 {
25720 const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(mod);25729 const elem_size_bytes = ptr_ty_data.child.toType().abiSize(mod);
25721 const elem_size_bits = ptr_ty_data.pointee_type.bitSize(mod);25730 const elem_size_bits = ptr_ty_data.child.toType().bitSize(mod);
25722 if (elem_size_bytes * 8 == elem_size_bits) {25731 if (elem_size_bytes * 8 == elem_size_bits) {
25723 const byte_offset = ptr_ty_data.bit_offset / 8;25732 const byte_offset = ptr_ty_data.packed_offset.bit_offset / 8;
25724 const new_align = @as(u32, 1) << @intCast(u5, @ctz(byte_offset | parent_align));25733 const new_align = @enumFromInt(Alignment, @ctz(byte_offset | parent_align));
25725 ptr_ty_data.bit_offset = 0;25734 assert(new_align != .none);
25726 ptr_ty_data.host_size = 0;25735 ptr_ty_data.flags.alignment = new_align;
25727 ptr_ty_data.@"align" = new_align;25736 ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 };
25728 }25737 }
25729 }25738 }
25730 } else {25739 } else {
25731 ptr_ty_data.@"align" = field.abi_align;25740 ptr_ty_data.flags.alignment = field.abi_align;
25732 }25741 }
2573325742
25734 const ptr_field_ty = try Type.ptr(sema.arena, mod, ptr_ty_data);25743 const ptr_field_ty = try mod.ptrType(ptr_ty_data);
2573525744
25736 if (field.is_comptime) {25745 if (field.is_comptime) {
25737 const val = try mod.intern(.{ .ptr = .{25746 const val = try mod.intern(.{ .ptr = .{
...@@ -25893,7 +25902,6 @@ fn unionFieldPtr(...@@ -25893,7 +25902,6 @@ fn unionFieldPtr(
25893 unresolved_union_ty: Type,25902 unresolved_union_ty: Type,
25894 initializing: bool,25903 initializing: bool,
25895) CompileError!Air.Inst.Ref {25904) CompileError!Air.Inst.Ref {
25896 const arena = sema.arena;
25897 const mod = sema.mod;25905 const mod = sema.mod;
25898 const ip = &mod.intern_pool;25906 const ip = &mod.intern_pool;
2589925907
...@@ -25904,11 +25912,13 @@ fn unionFieldPtr(...@@ -25904,11 +25912,13 @@ fn unionFieldPtr(
25904 const union_obj = mod.typeToUnion(union_ty).?;25912 const union_obj = mod.typeToUnion(union_ty).?;
25905 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);25913 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
25906 const field = union_obj.fields.values()[field_index];25914 const field = union_obj.fields.values()[field_index];
25907 const ptr_field_ty = try Type.ptr(arena, mod, .{25915 const ptr_field_ty = try mod.ptrType(.{
25908 .pointee_type = field.ty,25916 .child = field.ty.toIntern(),
25909 .mutable = union_ptr_ty.ptrIsMutable(mod),25917 .flags = .{
25910 .@"volatile" = union_ptr_ty.isVolatilePtr(mod),25918 .is_const = !union_ptr_ty.ptrIsMutable(mod),
25911 .@"addrspace" = union_ptr_ty.ptrAddressSpace(mod),25919 .is_volatile = union_ptr_ty.isVolatilePtr(mod),
25920 .address_space = union_ptr_ty.ptrAddressSpace(mod),
25921 },
25912 });25922 });
25913 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);25923 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);
2591425924
...@@ -26269,11 +26279,13 @@ fn tupleFieldPtr(...@@ -26269,11 +26279,13 @@ fn tupleFieldPtr(
26269 }26279 }
2627026280
26271 const field_ty = tuple_ty.structFieldType(field_index, mod);26281 const field_ty = tuple_ty.structFieldType(field_index, mod);
26272 const ptr_field_ty = try Type.ptr(sema.arena, mod, .{26282 const ptr_field_ty = try mod.ptrType(.{
26273 .pointee_type = field_ty,26283 .child = field_ty.toIntern(),
26274 .mutable = tuple_ptr_ty.ptrIsMutable(mod),26284 .flags = .{
26275 .@"volatile" = tuple_ptr_ty.isVolatilePtr(mod),26285 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),
26276 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod),26286 .is_volatile = tuple_ptr_ty.isVolatilePtr(mod),
26287 .address_space = tuple_ptr_ty.ptrAddressSpace(mod),
26288 },
26277 });26289 });
2627826290
26279 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {26291 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
...@@ -26724,15 +26736,15 @@ fn coerceExtra(...@@ -26724,15 +26736,15 @@ fn coerceExtra(
2672426736
26725 // *T to *[1]T26737 // *T to *[1]T
26726 single_item: {26738 single_item: {
26727 if (dest_info.size != .One) break :single_item;26739 if (dest_info.flags.size != .One) break :single_item;
26728 if (!inst_ty.isSinglePointer(mod)) break :single_item;26740 if (!inst_ty.isSinglePointer(mod)) break :single_item;
26729 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;26741 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
26730 const ptr_elem_ty = inst_ty.childType(mod);26742 const ptr_elem_ty = inst_ty.childType(mod);
26731 const array_ty = dest_info.pointee_type;26743 const array_ty = dest_info.child.toType();
26732 if (array_ty.zigTypeTag(mod) != .Array) break :single_item;26744 if (array_ty.zigTypeTag(mod) != .Array) break :single_item;
26733 const array_elem_ty = array_ty.childType(mod);26745 const array_elem_ty = array_ty.childType(mod);
26734 if (array_ty.arrayLen(mod) != 1) break :single_item;26746 if (array_ty.arrayLen(mod) != 1) break :single_item;
26735 const dest_is_mut = dest_info.mutable;26747 const dest_is_mut = !dest_info.flags.is_const;
26736 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {26748 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
26737 .ok => {},26749 .ok => {},
26738 else => break :single_item,26750 else => break :single_item,
...@@ -26747,9 +26759,9 @@ fn coerceExtra(...@@ -26747,9 +26759,9 @@ fn coerceExtra(
26747 const array_ty = inst_ty.childType(mod);26759 const array_ty = inst_ty.childType(mod);
26748 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;26760 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
26749 const array_elem_type = array_ty.childType(mod);26761 const array_elem_type = array_ty.childType(mod);
26750 const dest_is_mut = dest_info.mutable;26762 const dest_is_mut = !dest_info.flags.is_const;
2675126763
26752 const dst_elem_type = dest_info.pointee_type;26764 const dst_elem_type = dest_info.child.toType();
26753 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src);26765 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src);
26754 switch (elem_res) {26766 switch (elem_res) {
26755 .ok => {},26767 .ok => {},
...@@ -26763,12 +26775,12 @@ fn coerceExtra(...@@ -26763,12 +26775,12 @@ fn coerceExtra(
26763 },26775 },
26764 }26776 }
2676526777
26766 if (dest_info.sentinel) |dest_sent| {26778 if (dest_info.sentinel != .none) {
26767 if (array_ty.sentinel(mod)) |inst_sent| {26779 if (array_ty.sentinel(mod)) |inst_sent| {
26768 if (!dest_sent.eql(inst_sent, dst_elem_type, mod)) {26780 if (dest_info.sentinel != (try mod.getCoerced(inst_sent, dst_elem_type)).toIntern()) {
26769 in_memory_result = .{ .ptr_sentinel = .{26781 in_memory_result = .{ .ptr_sentinel = .{
26770 .actual = inst_sent,26782 .actual = inst_sent,
26771 .wanted = dest_sent,26783 .wanted = dest_info.sentinel.toValue(),
26772 .ty = dst_elem_type,26784 .ty = dst_elem_type,
26773 } };26785 } };
26774 break :src_array_ptr;26786 break :src_array_ptr;
...@@ -26776,14 +26788,14 @@ fn coerceExtra(...@@ -26776,14 +26788,14 @@ fn coerceExtra(
26776 } else {26788 } else {
26777 in_memory_result = .{ .ptr_sentinel = .{26789 in_memory_result = .{ .ptr_sentinel = .{
26778 .actual = Value.@"unreachable",26790 .actual = Value.@"unreachable",
26779 .wanted = dest_sent,26791 .wanted = dest_info.sentinel.toValue(),
26780 .ty = dst_elem_type,26792 .ty = dst_elem_type,
26781 } };26793 } };
26782 break :src_array_ptr;26794 break :src_array_ptr;
26783 }26795 }
26784 }26796 }
2678526797
26786 switch (dest_info.size) {26798 switch (dest_info.flags.size) {
26787 .Slice => {26799 .Slice => {
26788 // *[N]T to []T26800 // *[N]T to []T
26789 return sema.coerceArrayPtrToSlice(block, dest_ty, inst, inst_src);26801 return sema.coerceArrayPtrToSlice(block, dest_ty, inst, inst_src);
...@@ -26806,8 +26818,8 @@ fn coerceExtra(...@@ -26806,8 +26818,8 @@ fn coerceExtra(
26806 // In this case we must add a safety check because the C pointer26818 // In this case we must add a safety check because the C pointer
26807 // could be null.26819 // could be null.
26808 const src_elem_ty = inst_ty.childType(mod);26820 const src_elem_ty = inst_ty.childType(mod);
26809 const dest_is_mut = dest_info.mutable;26821 const dest_is_mut = !dest_info.flags.is_const;
26810 const dst_elem_type = dest_info.pointee_type;26822 const dst_elem_type = dest_info.child.toType();
26811 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {26823 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
26812 .ok => {},26824 .ok => {},
26813 else => break :src_c_ptr,26825 else => break :src_c_ptr,
...@@ -26817,7 +26829,7 @@ fn coerceExtra(...@@ -26817,7 +26829,7 @@ fn coerceExtra(
2681726829
26818 // cast from *T and [*]T to *anyopaque26830 // cast from *T and [*]T to *anyopaque
26819 // but don't do it if the source type is a double pointer26831 // but don't do it if the source type is a double pointer
26820 if (dest_info.pointee_type.toIntern() == .anyopaque_type and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: {26832 if (dest_info.child == .anyopaque_type and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: {
26821 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;26833 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
26822 const elem_ty = inst_ty.elemType2(mod);26834 const elem_ty = inst_ty.elemType2(mod);
26823 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {26835 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
...@@ -26838,7 +26850,7 @@ fn coerceExtra(...@@ -26838,7 +26850,7 @@ fn coerceExtra(
26838 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);26850 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
26839 }26851 }
2684026852
26841 switch (dest_info.size) {26853 switch (dest_info.flags.size) {
26842 // coercion to C pointer26854 // coercion to C pointer
26843 .C => switch (inst_ty.zigTypeTag(mod)) {26855 .C => switch (inst_ty.zigTypeTag(mod)) {
26844 .Null => {26856 .Null => {
...@@ -26871,9 +26883,9 @@ fn coerceExtra(...@@ -26871,9 +26883,9 @@ fn coerceExtra(
26871 const inst_info = inst_ty.ptrInfo(mod);26883 const inst_info = inst_ty.ptrInfo(mod);
26872 switch (try sema.coerceInMemoryAllowed(26884 switch (try sema.coerceInMemoryAllowed(
26873 block,26885 block,
26874 dest_info.pointee_type,26886 dest_info.child.toType(),
26875 inst_info.pointee_type,26887 inst_info.child.toType(),
26876 dest_info.mutable,26888 !dest_info.flags.is_const,
26877 target,26889 target,
26878 dest_ty_src,26890 dest_ty_src,
26879 inst_src,26891 inst_src,
...@@ -26881,10 +26893,10 @@ fn coerceExtra(...@@ -26881,10 +26893,10 @@ fn coerceExtra(
26881 .ok => {},26893 .ok => {},
26882 else => break :p,26894 else => break :p,
26883 }26895 }
26884 if (inst_info.size == .Slice) {26896 if (inst_info.flags.size == .Slice) {
26885 assert(dest_info.sentinel == null);26897 assert(dest_info.sentinel == .none);
26886 if (inst_info.sentinel == null or26898 if (inst_info.sentinel == .none or
26887 !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, mod))26899 inst_info.sentinel != (try mod.intValue(inst_info.child.toType(), 0)).toIntern())
26888 break :p;26900 break :p;
2688926901
26890 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);26902 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -26894,7 +26906,7 @@ fn coerceExtra(...@@ -26894,7 +26906,7 @@ fn coerceExtra(
26894 },26906 },
26895 else => {},26907 else => {},
26896 },26908 },
26897 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {26909 .One => switch (dest_info.child.toType().zigTypeTag(mod)) {
26898 .Union => {26910 .Union => {
26899 // pointer to anonymous struct to pointer to union26911 // pointer to anonymous struct to pointer to union
26900 if (inst_ty.isSinglePointer(mod) and26912 if (inst_ty.isSinglePointer(mod) and
...@@ -26948,16 +26960,16 @@ fn coerceExtra(...@@ -26948,16 +26960,16 @@ fn coerceExtra(
26948 // we use a dummy pointer value with the required alignment.26960 // we use a dummy pointer value with the required alignment.
26949 return sema.addConstant(dest_ty, (try mod.intern(.{ .ptr = .{26961 return sema.addConstant(dest_ty, (try mod.intern(.{ .ptr = .{
26950 .ty = dest_ty.toIntern(),26962 .ty = dest_ty.toIntern(),
26951 .addr = .{ .int = (if (dest_info.@"align" != 0)26963 .addr = .{ .int = (if (dest_info.flags.alignment != .none)
26952 try mod.intValue(Type.usize, dest_info.@"align")26964 try mod.intValue(Type.usize, dest_info.flags.alignment.toByteUnitsOptional().?)
26953 else26965 else
26954 try mod.getCoerced(try dest_info.pointee_type.lazyAbiAlignment(mod), Type.usize)).toIntern() },26966 try mod.getCoerced(try dest_info.child.toType().lazyAbiAlignment(mod), Type.usize)).toIntern() },
26955 .len = (try mod.intValue(Type.usize, 0)).toIntern(),26967 .len = (try mod.intValue(Type.usize, 0)).toIntern(),
26956 } })).toValue());26968 } })).toValue());
26957 }26969 }
2695826970
26959 // pointer to tuple to slice26971 // pointer to tuple to slice
26960 if (dest_info.mutable) {26972 if (!dest_info.flags.is_const) {
26961 const err_msg = err_msg: {26973 const err_msg = err_msg: {
26962 const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)});26974 const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)});
26963 errdefer err_msg.deinit(sema.gpa);26975 errdefer err_msg.deinit(sema.gpa);
...@@ -26975,9 +26987,9 @@ fn coerceExtra(...@@ -26975,9 +26987,9 @@ fn coerceExtra(
2697526987
26976 switch (try sema.coerceInMemoryAllowed(26988 switch (try sema.coerceInMemoryAllowed(
26977 block,26989 block,
26978 dest_info.pointee_type,26990 dest_info.child.toType(),
26979 inst_info.pointee_type,26991 inst_info.child.toType(),
26980 dest_info.mutable,26992 !dest_info.flags.is_const,
26981 target,26993 target,
26982 dest_ty_src,26994 dest_ty_src,
26983 inst_src,26995 inst_src,
...@@ -26986,12 +26998,9 @@ fn coerceExtra(...@@ -26986,12 +26998,9 @@ fn coerceExtra(
26986 else => break :p,26998 else => break :p,
26987 }26999 }
2698827000
26989 if (dest_info.sentinel == null or inst_info.sentinel == null or27001 if (dest_info.sentinel == .none or inst_info.sentinel == .none or
26990 !dest_info.sentinel.?.eql(27002 dest_info.sentinel !=
26991 try mod.getCoerced(inst_info.sentinel.?, dest_info.pointee_type),27003 try mod.intern_pool.getCoerced(sema.gpa, inst_info.sentinel, dest_info.child))
26992 dest_info.pointee_type,
26993 mod,
26994 ))
26995 break :p;27004 break :p;
2699627005
26997 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);27006 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -28117,41 +28126,41 @@ fn coerceInMemoryAllowedPtrs(...@@ -28117,41 +28126,41 @@ fn coerceInMemoryAllowedPtrs(
28117 const dest_info = dest_ptr_ty.ptrInfo(mod);28126 const dest_info = dest_ptr_ty.ptrInfo(mod);
28118 const src_info = src_ptr_ty.ptrInfo(mod);28127 const src_info = src_ptr_ty.ptrInfo(mod);
2811928128
28120 const ok_ptr_size = src_info.size == dest_info.size or28129 const ok_ptr_size = src_info.flags.size == dest_info.flags.size or
28121 src_info.size == .C or dest_info.size == .C;28130 src_info.flags.size == .C or dest_info.flags.size == .C;
28122 if (!ok_ptr_size) {28131 if (!ok_ptr_size) {
28123 return InMemoryCoercionResult{ .ptr_size = .{28132 return InMemoryCoercionResult{ .ptr_size = .{
28124 .actual = src_info.size,28133 .actual = src_info.flags.size,
28125 .wanted = dest_info.size,28134 .wanted = dest_info.flags.size,
28126 } };28135 } };
28127 }28136 }
2812828137
28129 const ok_cv_qualifiers =28138 const ok_cv_qualifiers =
28130 (src_info.mutable or !dest_info.mutable) and28139 (!src_info.flags.is_const or dest_info.flags.is_const) and
28131 (!src_info.@"volatile" or dest_info.@"volatile");28140 (!src_info.flags.is_volatile or dest_info.flags.is_volatile);
2813228141
28133 if (!ok_cv_qualifiers) {28142 if (!ok_cv_qualifiers) {
28134 return InMemoryCoercionResult{ .ptr_qualifiers = .{28143 return InMemoryCoercionResult{ .ptr_qualifiers = .{
28135 .actual_const = !src_info.mutable,28144 .actual_const = src_info.flags.is_const,
28136 .wanted_const = !dest_info.mutable,28145 .wanted_const = dest_info.flags.is_const,
28137 .actual_volatile = src_info.@"volatile",28146 .actual_volatile = src_info.flags.is_volatile,
28138 .wanted_volatile = dest_info.@"volatile",28147 .wanted_volatile = dest_info.flags.is_volatile,
28139 } };28148 } };
28140 }28149 }
2814128150
28142 if (dest_info.@"addrspace" != src_info.@"addrspace") {28151 if (dest_info.flags.address_space != src_info.flags.address_space) {
28143 return InMemoryCoercionResult{ .ptr_addrspace = .{28152 return InMemoryCoercionResult{ .ptr_addrspace = .{
28144 .actual = src_info.@"addrspace",28153 .actual = src_info.flags.address_space,
28145 .wanted = dest_info.@"addrspace",28154 .wanted = dest_info.flags.address_space,
28146 } };28155 } };
28147 }28156 }
2814828157
28149 const child = try sema.coerceInMemoryAllowed(block, dest_info.pointee_type, src_info.pointee_type, dest_info.mutable, target, dest_src, src_src);28158 const child = try sema.coerceInMemoryAllowed(block, dest_info.child.toType(), src_info.child.toType(), !dest_info.flags.is_const, target, dest_src, src_src);
28150 if (child != .ok) {28159 if (child != .ok) {
28151 return InMemoryCoercionResult{ .ptr_child = .{28160 return InMemoryCoercionResult{ .ptr_child = .{
28152 .child = try child.dupe(sema.arena),28161 .child = try child.dupe(sema.arena),
28153 .actual = src_info.pointee_type,28162 .actual = src_info.child.toType(),
28154 .wanted = dest_info.pointee_type,28163 .wanted = dest_info.child.toType(),
28155 } };28164 } };
28156 }28165 }
2815728166
...@@ -28168,28 +28177,31 @@ fn coerceInMemoryAllowedPtrs(...@@ -28168,28 +28177,31 @@ fn coerceInMemoryAllowedPtrs(
28168 } };28177 } };
28169 }28178 }
2817028179
28171 if (src_info.host_size != dest_info.host_size or28180 if (src_info.packed_offset.host_size != dest_info.packed_offset.host_size or
28172 src_info.bit_offset != dest_info.bit_offset)28181 src_info.packed_offset.bit_offset != dest_info.packed_offset.bit_offset)
28173 {28182 {
28174 return InMemoryCoercionResult{ .ptr_bit_range = .{28183 return InMemoryCoercionResult{ .ptr_bit_range = .{
28175 .actual_host = src_info.host_size,28184 .actual_host = src_info.packed_offset.host_size,
28176 .wanted_host = dest_info.host_size,28185 .wanted_host = dest_info.packed_offset.host_size,
28177 .actual_offset = src_info.bit_offset,28186 .actual_offset = src_info.packed_offset.bit_offset,
28178 .wanted_offset = dest_info.bit_offset,28187 .wanted_offset = dest_info.packed_offset.bit_offset,
28179 } };28188 } };
28180 }28189 }
2818128190
28182 const ok_sent = dest_info.sentinel == null or src_info.size == .C or28191 const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or
28183 (src_info.sentinel != null and dest_info.sentinel.?.eql(28192 (src_info.sentinel != .none and
28184 try mod.getCoerced(src_info.sentinel.?, dest_info.pointee_type),28193 dest_info.sentinel == try mod.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child));
28185 dest_info.pointee_type,
28186 sema.mod,
28187 ));
28188 if (!ok_sent) {28194 if (!ok_sent) {
28189 return InMemoryCoercionResult{ .ptr_sentinel = .{28195 return InMemoryCoercionResult{ .ptr_sentinel = .{
28190 .actual = src_info.sentinel orelse Value.@"unreachable",28196 .actual = switch (src_info.sentinel) {
28191 .wanted = dest_info.sentinel orelse Value.@"unreachable",28197 .none => Value.@"unreachable",
28192 .ty = dest_info.pointee_type,28198 else => src_info.sentinel.toValue(),
28199 },
28200 .wanted = switch (dest_info.sentinel) {
28201 .none => Value.@"unreachable",
28202 else => dest_info.sentinel.toValue(),
28203 },
28204 .ty = dest_info.child.toType(),
28193 } };28205 } };
28194 }28206 }
2819528207
...@@ -28197,22 +28209,14 @@ fn coerceInMemoryAllowedPtrs(...@@ -28197,22 +28209,14 @@ fn coerceInMemoryAllowedPtrs(
28197 // In this case, if they share the same child type, no need to resolve28209 // In this case, if they share the same child type, no need to resolve
28198 // pointee type alignment. Otherwise both pointee types must have their alignment28210 // pointee type alignment. Otherwise both pointee types must have their alignment
28199 // resolved and we compare the alignment numerically.28211 // resolved and we compare the alignment numerically.
28200 alignment: {28212 if (src_info.flags.alignment != .none or dest_info.flags.alignment != .none or
28201 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and28213 dest_info.child != src_info.child)
28202 dest_info.pointee_type.eql(src_info.pointee_type, sema.mod))28214 {
28203 {28215 const src_align = src_info.flags.alignment.toByteUnitsOptional() orelse
28204 break :alignment;28216 src_info.child.toType().abiAlignment(mod);
28205 }
28206
28207 const src_align = if (src_info.@"align" != 0)
28208 src_info.@"align"
28209 else
28210 src_info.pointee_type.abiAlignment(mod);
2821128217
28212 const dest_align = if (dest_info.@"align" != 0)28218 const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse
28213 dest_info.@"align"28219 dest_info.child.toType().abiAlignment(mod);
28214 else
28215 dest_info.pointee_type.abiAlignment(mod);
2821628220
28217 if (dest_align > src_align) {28221 if (dest_align > src_align) {
28218 return InMemoryCoercionResult{ .ptr_alignment = .{28222 return InMemoryCoercionResult{ .ptr_alignment = .{
...@@ -28220,8 +28224,6 @@ fn coerceInMemoryAllowedPtrs(...@@ -28220,8 +28224,6 @@ fn coerceInMemoryAllowedPtrs(
28220 .wanted = dest_align,28224 .wanted = dest_align,
28221 } };28225 } };
28222 }28226 }
28223
28224 break :alignment;
28225 }28227 }
2822628228
28227 return .ok;28229 return .ok;
...@@ -28386,7 +28388,7 @@ fn storePtr2(...@@ -28386,7 +28388,7 @@ fn storePtr2(
28386 try sema.requireRuntimeBlock(block, src, runtime_src);28388 try sema.requireRuntimeBlock(block, src, runtime_src);
28387 try sema.queueFullTypeResolution(elem_ty);28389 try sema.queueFullTypeResolution(elem_ty);
2838828390
28389 if (ptr_ty.ptrInfo(mod).vector_index == .runtime) {28391 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
28390 const ptr_inst = Air.refToIndex(ptr).?;28392 const ptr_inst = Air.refToIndex(ptr).?;
28391 const air_tags = sema.air_instructions.items(.tag);28393 const air_tags = sema.air_instructions.items(.tag);
28392 if (air_tags[ptr_inst] == .ptr_elem_ptr) {28394 if (air_tags[ptr_inst] == .ptr_elem_ptr) {
...@@ -29238,11 +29240,14 @@ fn beginComptimePtrLoad(...@@ -29238,11 +29240,14 @@ fn beginComptimePtrLoad(
29238 // It's possible that we're loading a [N]T, in which case we'd like to slice29240 // It's possible that we're loading a [N]T, in which case we'd like to slice
29239 // the pointee array directly from our parent array.29241 // the pointee array directly from our parent array.
29240 if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) {29242 if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) {
29241 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));29243 const len = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));
29242 const elem_idx = try sema.usizeCast(block, src, elem_ptr.index);29244 const elem_idx = try sema.usizeCast(block, src, elem_ptr.index);
29243 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{29245 deref.pointee = if (elem_ptr.index + len <= check_len) TypedValue{
29244 .ty = try Type.array(sema.arena, N, null, elem_ty, mod),29246 .ty = try mod.arrayType(.{
29245 .val = try array_tv.val.sliceArray(mod, sema.arena, elem_idx, elem_idx + N),29247 .len = len,
29248 .child = elem_ty.toIntern(),
29249 }),
29250 .val = try array_tv.val.sliceArray(mod, sema.arena, elem_idx, elem_idx + len),
29246 } else null;29251 } else null;
29247 break :blk deref;29252 break :blk deref;
29248 }29253 }
...@@ -29429,42 +29434,38 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul...@@ -29429,42 +29434,38 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul
29429 const mod = sema.mod;29434 const mod = sema.mod;
29430 const dest_info = dest_ty.ptrInfo(mod);29435 const dest_info = dest_ty.ptrInfo(mod);
29431 const inst_info = inst_ty.ptrInfo(mod);29436 const inst_info = inst_ty.ptrInfo(mod);
29432 const len0 = (inst_info.pointee_type.zigTypeTag(mod) == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel(mod) == 0 or29437 const len0 = (inst_info.child.toType().zigTypeTag(mod) == .Array and (inst_info.child.toType().arrayLenIncludingSentinel(mod) == 0 or
29433 (inst_info.pointee_type.arrayLen(mod) == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or29438 (inst_info.child.toType().arrayLen(mod) == 0 and dest_info.sentinel == .none and dest_info.flags.size != .C and dest_info.flags.size != .Many))) or
29434 (inst_info.pointee_type.isTuple(mod) and inst_info.pointee_type.structFieldCount(mod) == 0);29439 (inst_info.child.toType().isTuple(mod) and inst_info.child.toType().structFieldCount(mod) == 0);
2943529440
29436 const ok_cv_qualifiers =29441 const ok_cv_qualifiers =
29437 ((inst_info.mutable or !dest_info.mutable) or len0) and29442 ((!inst_info.flags.is_const or dest_info.flags.is_const) or len0) and
29438 (!inst_info.@"volatile" or dest_info.@"volatile");29443 (!inst_info.flags.is_volatile or dest_info.flags.is_volatile);
2943929444
29440 if (!ok_cv_qualifiers) {29445 if (!ok_cv_qualifiers) {
29441 in_memory_result.* = .{ .ptr_qualifiers = .{29446 in_memory_result.* = .{ .ptr_qualifiers = .{
29442 .actual_const = !inst_info.mutable,29447 .actual_const = inst_info.flags.is_const,
29443 .wanted_const = !dest_info.mutable,29448 .wanted_const = dest_info.flags.is_const,
29444 .actual_volatile = inst_info.@"volatile",29449 .actual_volatile = inst_info.flags.is_volatile,
29445 .wanted_volatile = dest_info.@"volatile",29450 .wanted_volatile = dest_info.flags.is_volatile,
29446 } };29451 } };
29447 return false;29452 return false;
29448 }29453 }
29449 if (dest_info.@"addrspace" != inst_info.@"addrspace") {29454 if (dest_info.flags.address_space != inst_info.flags.address_space) {
29450 in_memory_result.* = .{ .ptr_addrspace = .{29455 in_memory_result.* = .{ .ptr_addrspace = .{
29451 .actual = inst_info.@"addrspace",29456 .actual = inst_info.flags.address_space,
29452 .wanted = dest_info.@"addrspace",29457 .wanted = dest_info.flags.address_space,
29453 } };29458 } };
29454 return false;29459 return false;
29455 }29460 }
29456 if (inst_info.@"align" == 0 and dest_info.@"align" == 0) return true;29461 if (inst_info.flags.alignment == .none and dest_info.flags.alignment == .none) return true;
29457 if (len0) return true;29462 if (len0) return true;
2945829463
29459 const inst_align = if (inst_info.@"align" != 0)29464 const inst_align = inst_info.flags.alignment.toByteUnitsOptional() orelse
29460 inst_info.@"align"29465 inst_info.child.toType().abiAlignment(mod);
29461 else
29462 inst_info.pointee_type.abiAlignment(mod);
2946329466
29464 const dest_align = if (dest_info.@"align" != 0)29467 const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse
29465 dest_info.@"align"29468 dest_info.child.toType().abiAlignment(mod);
29466 else
29467 dest_info.pointee_type.abiAlignment(mod);
2946829469
29469 if (dest_align > inst_align) {29470 if (dest_align > inst_align) {
29470 in_memory_result.* = .{ .ptr_alignment = .{29471 in_memory_result.* = .{ .ptr_alignment = .{
...@@ -29901,9 +29902,13 @@ fn coerceTupleToSlicePtrs(...@@ -29901,9 +29902,13 @@ fn coerceTupleToSlicePtrs(
29901 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);29902 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);
29902 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);29903 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
29903 const slice_info = slice_ty.ptrInfo(mod);29904 const slice_info = slice_ty.ptrInfo(mod);
29904 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(mod), slice_info.sentinel, slice_info.pointee_type, sema.mod);29905 const array_ty = try mod.arrayType(.{
29906 .len = tuple_ty.structFieldCount(mod),
29907 .sentinel = slice_info.sentinel,
29908 .child = slice_info.child,
29909 });
29905 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);29910 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
29906 if (slice_info.@"align" != 0) {29911 if (slice_info.flags.alignment != .none) {
29907 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});29912 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
29908 }29913 }
29909 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst);29914 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst);
...@@ -29922,9 +29927,9 @@ fn coerceTupleToArrayPtrs(...@@ -29922,9 +29927,9 @@ fn coerceTupleToArrayPtrs(
29922 const mod = sema.mod;29927 const mod = sema.mod;
29923 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);29928 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
29924 const ptr_info = ptr_array_ty.ptrInfo(mod);29929 const ptr_info = ptr_array_ty.ptrInfo(mod);
29925 const array_ty = ptr_info.pointee_type;29930 const array_ty = ptr_info.child.toType();
29926 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);29931 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);
29927 if (ptr_info.@"align" != 0) {29932 if (ptr_info.flags.alignment != .none) {
29928 return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});29933 return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});
29929 }29934 }
29930 const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst);29935 const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst);
...@@ -30263,7 +30268,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {...@@ -30263,7 +30268,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
30263 const decl = try anon_decl.finish(30268 const decl = try anon_decl.finish(
30264 ty,30269 ty,
30265 val,30270 val,
30266 0, // default alignment30271 .none, // default alignment
30267 );30272 );
30268 try sema.maybeQueueFuncBodyAnalysis(decl);30273 try sema.maybeQueueFuncBodyAnalysis(decl);
30269 try mod.declareDeclDependency(sema.owner_decl_index, decl);30274 try mod.declareDeclDependency(sema.owner_decl_index, decl);
...@@ -30304,7 +30309,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo...@@ -30304,7 +30309,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo
30304 const ptr_ty = try mod.ptrType(.{30309 const ptr_ty = try mod.ptrType(.{
30305 .child = decl_tv.ty.toIntern(),30310 .child = decl_tv.ty.toIntern(),
30306 .flags = .{30311 .flags = .{
30307 .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"),30312 .alignment = decl.alignment,
30308 .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true,30313 .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true,
30309 .address_space = decl.@"addrspace",30314 .address_space = decl.@"addrspace",
30310 },30315 },
...@@ -30334,12 +30339,13 @@ fn analyzeRef(...@@ -30334,12 +30339,13 @@ fn analyzeRef(
30334 src: LazySrcLoc,30339 src: LazySrcLoc,
30335 operand: Air.Inst.Ref,30340 operand: Air.Inst.Ref,
30336) CompileError!Air.Inst.Ref {30341) CompileError!Air.Inst.Ref {
30342 const mod = sema.mod;
30337 const operand_ty = sema.typeOf(operand);30343 const operand_ty = sema.typeOf(operand);
3033830344
30339 if (try sema.resolveMaybeUndefVal(operand)) |val| {30345 if (try sema.resolveMaybeUndefVal(operand)) |val| {
30340 switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {30346 switch (mod.intern_pool.indexToKey(val.toIntern())) {
30341 .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),30347 .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),
30342 .func => |func| return sema.analyzeDeclRef(sema.mod.funcPtr(func.index).owner_decl),30348 .func => |func| return sema.analyzeDeclRef(mod.funcPtr(func.index).owner_decl),
30343 else => {},30349 else => {},
30344 }30350 }
30345 var anon_decl = try block.startAnonDecl();30351 var anon_decl = try block.startAnonDecl();
...@@ -30347,20 +30353,22 @@ fn analyzeRef(...@@ -30347,20 +30353,22 @@ fn analyzeRef(
30347 return sema.analyzeDeclRef(try anon_decl.finish(30353 return sema.analyzeDeclRef(try anon_decl.finish(
30348 operand_ty,30354 operand_ty,
30349 val,30355 val,
30350 0, // default alignment30356 .none, // default alignment
30351 ));30357 ));
30352 }30358 }
3035330359
30354 try sema.requireRuntimeBlock(block, src, null);30360 try sema.requireRuntimeBlock(block, src, null);
30355 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);30361 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);
30356 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{30362 const ptr_type = try mod.ptrType(.{
30357 .pointee_type = operand_ty,30363 .child = operand_ty.toIntern(),
30358 .mutable = false,30364 .flags = .{
30359 .@"addrspace" = address_space,30365 .is_const = true,
30366 .address_space = address_space,
30367 },
30360 });30368 });
30361 const mut_ptr_type = try Type.ptr(sema.arena, sema.mod, .{30369 const mut_ptr_type = try mod.ptrType(.{
30362 .pointee_type = operand_ty,30370 .child = operand_ty.toIntern(),
30363 .@"addrspace" = address_space,30371 .flags = .{ .address_space = address_space },
30364 });30372 });
30365 const alloc = try block.addTy(.alloc, mut_ptr_type);30373 const alloc = try block.addTy(.alloc, mut_ptr_type);
30366 try sema.storePtr(block, src, alloc, operand);30374 try sema.storePtr(block, src, alloc, operand);
...@@ -30393,7 +30401,7 @@ fn analyzeLoad(...@@ -30393,7 +30401,7 @@ fn analyzeLoad(
30393 }30401 }
30394 }30402 }
3039530403
30396 if (ptr_ty.ptrInfo(mod).vector_index == .runtime) {30404 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
30397 const ptr_inst = Air.refToIndex(ptr).?;30405 const ptr_inst = Air.refToIndex(ptr).?;
30398 const air_tags = sema.air_instructions.items(.tag);30406 const air_tags = sema.air_instructions.items(.tag);
30399 if (air_tags[ptr_inst] == .ptr_elem_ptr) {30407 if (air_tags[ptr_inst] == .ptr_elem_ptr) {
...@@ -30919,20 +30927,24 @@ fn analyzeSlice(...@@ -30919,20 +30927,24 @@ fn analyzeSlice(
30919 const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len);30927 const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len);
3092030928
30921 const new_ptr_ty_info = new_ptr_ty.ptrInfo(mod);30929 const new_ptr_ty_info = new_ptr_ty.ptrInfo(mod);
30922 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize(mod) != .C;30930 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;
3092330931
30924 if (opt_new_len_val) |new_len_val| {30932 if (opt_new_len_val) |new_len_val| {
30925 const new_len_int = new_len_val.toUnsignedInt(mod);30933 const new_len_int = new_len_val.toUnsignedInt(mod);
3092630934
30927 const return_ty = try Type.ptr(sema.arena, mod, .{30935 const return_ty = try mod.ptrType(.{
30928 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod),30936 .child = (try mod.arrayType(.{
30929 .sentinel = null,30937 .len = new_len_int,
30930 .@"align" = new_ptr_ty_info.@"align",30938 .sentinel = if (sentinel) |s| s.toIntern() else .none,
30931 .@"addrspace" = new_ptr_ty_info.@"addrspace",30939 .child = elem_ty.toIntern(),
30932 .mutable = new_ptr_ty_info.mutable,30940 })).toIntern(),
30933 .@"allowzero" = new_allowzero,30941 .flags = .{
30934 .@"volatile" = new_ptr_ty_info.@"volatile",30942 .alignment = new_ptr_ty_info.flags.alignment,
30935 .size = .One,30943 .is_const = new_ptr_ty_info.flags.is_const,
30944 .is_allowzero = new_allowzero,
30945 .is_volatile = new_ptr_ty_info.flags.is_volatile,
30946 .address_space = new_ptr_ty_info.flags.address_space,
30947 },
30936 });30948 });
3093730949
30938 const opt_new_ptr_val = try sema.resolveMaybeUndefVal(new_ptr);30950 const opt_new_ptr_val = try sema.resolveMaybeUndefVal(new_ptr);
...@@ -30981,15 +30993,17 @@ fn analyzeSlice(...@@ -30981,15 +30993,17 @@ fn analyzeSlice(
30981 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});30993 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
30982 }30994 }
3098330995
30984 const return_ty = try Type.ptr(sema.arena, mod, .{30996 const return_ty = try mod.ptrType(.{
30985 .pointee_type = elem_ty,30997 .child = elem_ty.toIntern(),
30986 .sentinel = sentinel,30998 .sentinel = if (sentinel) |s| s.toIntern() else .none,
30987 .@"align" = new_ptr_ty_info.@"align",30999 .flags = .{
30988 .@"addrspace" = new_ptr_ty_info.@"addrspace",31000 .size = .Slice,
30989 .mutable = new_ptr_ty_info.mutable,31001 .alignment = new_ptr_ty_info.flags.alignment,
30990 .@"allowzero" = new_allowzero,31002 .is_const = new_ptr_ty_info.flags.is_const,
30991 .@"volatile" = new_ptr_ty_info.@"volatile",31003 .is_volatile = new_ptr_ty_info.flags.is_volatile,
30992 .size = .Slice,31004 .is_allowzero = new_allowzero,
31005 .address_space = new_ptr_ty_info.flags.address_space,
31006 },
30993 });31007 });
3099431008
30995 try sema.requireRuntimeBlock(block, src, runtime_src.?);31009 try sema.requireRuntimeBlock(block, src, runtime_src.?);
...@@ -31735,7 +31749,7 @@ const PeerResolveStrategy = enum {...@@ -31735,7 +31749,7 @@ const PeerResolveStrategy = enum {
31735 .Int => .fixed_int,31749 .Int => .fixed_int,
31736 .ComptimeFloat => .comptime_float,31750 .ComptimeFloat => .comptime_float,
31737 .Float => .fixed_float,31751 .Float => .fixed_float,
31738 .Pointer => if (ty.ptrInfo(mod).size == .C) .c_ptr else .ptr,31752 .Pointer => if (ty.ptrInfo(mod).flags.size == .C) .c_ptr else .ptr,
31739 .Array => .array,31753 .Array => .array,
31740 .Vector => .vector,31754 .Vector => .vector,
31741 .Optional => .optional,31755 .Optional => .optional,
...@@ -32160,7 +32174,7 @@ fn resolvePeerTypesInner(...@@ -32160,7 +32174,7 @@ fn resolvePeerTypesInner(
32160 },32174 },
3216132175
32162 .c_ptr => {32176 .c_ptr => {
32163 var opt_ptr_info: ?Type.Payload.Pointer.Data = null;32177 var opt_ptr_info: ?InternPool.Key.PtrType = null;
32164 var first_idx: usize = undefined;32178 var first_idx: usize = undefined;
32165 for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| {32179 for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| {
32166 const ty = opt_ty orelse continue;32180 const ty = opt_ty orelse continue;
...@@ -32191,42 +32205,47 @@ fn resolvePeerTypesInner(...@@ -32191,42 +32205,47 @@ fn resolvePeerTypesInner(
3219132205
32192 var ptr_info = opt_ptr_info orelse {32206 var ptr_info = opt_ptr_info orelse {
32193 opt_ptr_info = peer_info;32207 opt_ptr_info = peer_info;
32194 opt_ptr_info.?.size = .C;32208 opt_ptr_info.?.flags.size = .C;
32195 first_idx = i;32209 first_idx = i;
32196 continue;32210 continue;
32197 };32211 };
3219832212
32199 // Try peer -> cur, then cur -> peer32213 // Try peer -> cur, then cur -> peer
32200 ptr_info.pointee_type = (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) orelse {32214 ptr_info.child = ((try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) orelse {
32201 return .{ .conflict = .{32215 return .{ .conflict = .{
32202 .peer_idx_a = first_idx,32216 .peer_idx_a = first_idx,
32203 .peer_idx_b = i,32217 .peer_idx_b = i,
32204 } };32218 } };
32205 };32219 }).toIntern();
3220632220
32207 if (ptr_info.sentinel != null and peer_info.sentinel != null) {32221 if (ptr_info.sentinel != .none and peer_info.sentinel != .none) {
32208 const peer_sent = try mod.getCoerced(ptr_info.sentinel.?, ptr_info.pointee_type);32222 const peer_sent = try mod.intern_pool.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child);
32209 const ptr_sent = try mod.getCoerced(peer_info.sentinel.?, ptr_info.pointee_type);32223 const ptr_sent = try mod.intern_pool.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child);
32210 if (ptr_sent.eql(peer_sent, ptr_info.pointee_type, mod)) {32224 if (ptr_sent == peer_sent) {
32211 ptr_info.sentinel = ptr_sent;32225 ptr_info.sentinel = ptr_sent;
32212 } else {32226 } else {
32213 ptr_info.sentinel = null;32227 ptr_info.sentinel = .none;
32214 }32228 }
32215 } else {32229 } else {
32216 ptr_info.sentinel = null;32230 ptr_info.sentinel = .none;
32217 }32231 }
3221832232
32219 // Note that the align can be always non-zero; Type.ptr will canonicalize it32233 // Note that the align can be always non-zero; Module.ptrType will canonicalize it
32220 ptr_info.@"align" = @min(ptr_info.alignment(mod), peer_info.alignment(mod));32234 ptr_info.flags.alignment = Alignment.fromByteUnits(@min(
32221 if (ptr_info.@"addrspace" != peer_info.@"addrspace") {32235 ptr_info.flags.alignment.toByteUnitsOptional() orelse
32236 ptr_info.child.toType().abiAlignment(mod),
32237 peer_info.flags.alignment.toByteUnitsOptional() orelse
32238 peer_info.child.toType().abiAlignment(mod),
32239 ));
32240 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
32222 return .{ .conflict = .{32241 return .{ .conflict = .{
32223 .peer_idx_a = first_idx,32242 .peer_idx_a = first_idx,
32224 .peer_idx_b = i,32243 .peer_idx_b = i,
32225 } };32244 } };
32226 }32245 }
3222732246
32228 if (ptr_info.bit_offset != peer_info.bit_offset or32247 if (ptr_info.packed_offset.bit_offset != peer_info.packed_offset.bit_offset or
32229 ptr_info.host_size != peer_info.host_size)32248 ptr_info.packed_offset.host_size != peer_info.packed_offset.host_size)
32230 {32249 {
32231 return .{ .conflict = .{32250 return .{ .conflict = .{
32232 .peer_idx_a = first_idx,32251 .peer_idx_a = first_idx,
...@@ -32234,12 +32253,12 @@ fn resolvePeerTypesInner(...@@ -32234,12 +32253,12 @@ fn resolvePeerTypesInner(
32234 } };32253 } };
32235 }32254 }
3223632255
32237 ptr_info.mutable = ptr_info.mutable and peer_info.mutable;32256 ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const;
32238 ptr_info.@"volatile" = ptr_info.@"volatile" or peer_info.@"volatile";32257 ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile;
3223932258
32240 opt_ptr_info = ptr_info;32259 opt_ptr_info = ptr_info;
32241 }32260 }
32242 return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) };32261 return .{ .success = try mod.ptrType(opt_ptr_info.?) };
32243 },32262 },
3224432263
32245 .ptr => {32264 .ptr => {
...@@ -32247,17 +32266,19 @@ fn resolvePeerTypesInner(...@@ -32247,17 +32266,19 @@ fn resolvePeerTypesInner(
32247 // if there were no actual slices. Else, we want the slice index to report a conflict.32266 // if there were no actual slices. Else, we want the slice index to report a conflict.
32248 var opt_slice_idx: ?usize = null;32267 var opt_slice_idx: ?usize = null;
3224932268
32250 var opt_ptr_info: ?Type.Payload.Pointer.Data = null;32269 var opt_ptr_info: ?InternPool.Key.PtrType = null;
32251 var first_idx: usize = undefined;32270 var first_idx: usize = undefined;
32252 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error32271 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error
3225332272
32254 for (peer_tys, 0..) |opt_ty, i| {32273 for (peer_tys, 0..) |opt_ty, i| {
32255 const ty = opt_ty orelse continue;32274 const ty = opt_ty orelse continue;
32256 const peer_info: Type.Payload.Pointer.Data = switch (ty.zigTypeTag(mod)) {32275 const peer_info: InternPool.Key.PtrType = switch (ty.zigTypeTag(mod)) {
32257 .Pointer => ty.ptrInfo(mod),32276 .Pointer => ty.ptrInfo(mod),
32258 .Fn => .{32277 .Fn => .{
32259 .pointee_type = ty,32278 .child = ty.toIntern(),
32260 .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant),32279 .flags = .{
32280 .address_space = target_util.defaultAddressSpace(target, .global_constant),
32281 },
32261 },32282 },
32262 else => return .{ .conflict = .{32283 else => return .{ .conflict = .{
32263 .peer_idx_a = strat_reason,32284 .peer_idx_a = strat_reason,
...@@ -32265,7 +32286,7 @@ fn resolvePeerTypesInner(...@@ -32265,7 +32286,7 @@ fn resolvePeerTypesInner(
32265 } },32286 } },
32266 };32287 };
3226732288
32268 switch (peer_info.size) {32289 switch (peer_info.flags.size) {
32269 .One, .Many => {},32290 .One, .Many => {},
32270 .Slice => opt_slice_idx = i,32291 .Slice => opt_slice_idx = i,
32271 .C => return .{ .conflict = .{32292 .C => return .{ .conflict = .{
...@@ -32289,51 +32310,56 @@ fn resolvePeerTypesInner(...@@ -32289,51 +32310,56 @@ fn resolvePeerTypesInner(
32289 } };32310 } };
3229032311
32291 // Note that the align can be always non-zero; Type.ptr will canonicalize it32312 // Note that the align can be always non-zero; Type.ptr will canonicalize it
32292 ptr_info.@"align" = @min(ptr_info.alignment(mod), peer_info.alignment(mod));32313 ptr_info.flags.alignment = Alignment.fromByteUnits(@min(
32314 ptr_info.flags.alignment.toByteUnitsOptional() orelse
32315 ptr_info.child.toType().abiAlignment(mod),
32316 peer_info.flags.alignment.toByteUnitsOptional() orelse
32317 peer_info.child.toType().abiAlignment(mod),
32318 ));
3229332319
32294 if (ptr_info.@"addrspace" != peer_info.@"addrspace") {32320 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
32295 return generic_err;32321 return generic_err;
32296 }32322 }
3229732323
32298 if (ptr_info.bit_offset != peer_info.bit_offset or32324 if (ptr_info.packed_offset.bit_offset != peer_info.packed_offset.bit_offset or
32299 ptr_info.host_size != peer_info.host_size)32325 ptr_info.packed_offset.host_size != peer_info.packed_offset.host_size)
32300 {32326 {
32301 return generic_err;32327 return generic_err;
32302 }32328 }
3230332329
32304 ptr_info.mutable = ptr_info.mutable and peer_info.mutable;32330 ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const;
32305 ptr_info.@"volatile" = ptr_info.@"volatile" or peer_info.@"volatile";32331 ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile;
3230632332
32307 const peer_sentinel: ?Value = switch (peer_info.size) {32333 const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) {
32308 .One => switch (peer_info.pointee_type.zigTypeTag(mod)) {32334 .One => switch (mod.intern_pool.indexToKey(peer_info.child)) {
32309 .Array => peer_info.pointee_type.sentinel(mod),32335 .array_type => |array_type| array_type.sentinel,
32310 else => null,32336 else => .none,
32311 },32337 },
32312 .Many, .Slice => peer_info.sentinel,32338 .Many, .Slice => peer_info.sentinel,
32313 .C => unreachable,32339 .C => unreachable,
32314 };32340 };
3231532341
32316 const cur_sentinel: ?Value = switch (ptr_info.size) {32342 const cur_sentinel: InternPool.Index = switch (ptr_info.flags.size) {
32317 .One => switch (ptr_info.pointee_type.zigTypeTag(mod)) {32343 .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32318 .Array => ptr_info.pointee_type.sentinel(mod),32344 .array_type => |array_type| array_type.sentinel,
32319 else => null,32345 else => .none,
32320 },32346 },
32321 .Many, .Slice => ptr_info.sentinel,32347 .Many, .Slice => ptr_info.sentinel,
32322 .C => unreachable,32348 .C => unreachable,
32323 };32349 };
3232432350
32325 // We abstract array handling slightly so that tuple pointers can work like array pointers32351 // We abstract array handling slightly so that tuple pointers can work like array pointers
32326 const peer_pointee_array = sema.typeIsArrayLike(peer_info.pointee_type);32352 const peer_pointee_array = sema.typeIsArrayLike(peer_info.child.toType());
32327 const cur_pointee_array = sema.typeIsArrayLike(ptr_info.pointee_type);32353 const cur_pointee_array = sema.typeIsArrayLike(ptr_info.child.toType());
3232832354
32329 // This switch is just responsible for deciding the size and pointee (not including32355 // This switch is just responsible for deciding the size and pointee (not including
32330 // single-pointer array sentinel).32356 // single-pointer array sentinel).
32331 good: {32357 good: {
32332 switch (peer_info.size) {32358 switch (peer_info.flags.size) {
32333 .One => switch (ptr_info.size) {32359 .One => switch (ptr_info.flags.size) {
32334 .One => {32360 .One => {
32335 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {32361 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32336 ptr_info.pointee_type = pointee;32362 ptr_info.child = pointee.toIntern();
32337 break :good;32363 break :good;
32338 }32364 }
3233932365
...@@ -32343,29 +32369,29 @@ fn resolvePeerTypesInner(...@@ -32343,29 +32369,29 @@ fn resolvePeerTypesInner(
32343 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {32369 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {
32344 // *[n:x]T + *[n:y]T = *[n]T32370 // *[n:x]T + *[n:y]T = *[n]T
32345 if (cur_arr.len == peer_arr.len) {32371 if (cur_arr.len == peer_arr.len) {
32346 ptr_info.pointee_type = try mod.arrayType(.{32372 ptr_info.child = (try mod.arrayType(.{
32347 .len = cur_arr.len,32373 .len = cur_arr.len,
32348 .child = elem_ty.toIntern(),32374 .child = elem_ty.toIntern(),
32349 });32375 })).toIntern();
32350 break :good;32376 break :good;
32351 }32377 }
32352 // *[a]T + *[b]T = []T32378 // *[a]T + *[b]T = []T
32353 ptr_info.size = .Slice;32379 ptr_info.flags.size = .Slice;
32354 ptr_info.pointee_type = elem_ty;32380 ptr_info.child = elem_ty.toIntern();
32355 break :good;32381 break :good;
32356 }32382 }
3235732383
32358 if (peer_arr.elem_ty.toIntern() == .noreturn_type) {32384 if (peer_arr.elem_ty.toIntern() == .noreturn_type) {
32359 // *struct{} + *[a]T = []T32385 // *struct{} + *[a]T = []T
32360 ptr_info.size = .Slice;32386 ptr_info.flags.size = .Slice;
32361 ptr_info.pointee_type = cur_arr.elem_ty;32387 ptr_info.child = cur_arr.elem_ty.toIntern();
32362 break :good;32388 break :good;
32363 }32389 }
3236432390
32365 if (cur_arr.elem_ty.toIntern() == .noreturn_type) {32391 if (cur_arr.elem_ty.toIntern() == .noreturn_type) {
32366 // *[a]T + *struct{} = []T32392 // *[a]T + *struct{} = []T
32367 ptr_info.size = .Slice;32393 ptr_info.flags.size = .Slice;
32368 ptr_info.pointee_type = peer_arr.elem_ty;32394 ptr_info.child = peer_arr.elem_ty.toIntern();
32369 break :good;32395 break :good;
32370 }32396 }
3237132397
...@@ -32374,8 +32400,8 @@ fn resolvePeerTypesInner(...@@ -32374,8 +32400,8 @@ fn resolvePeerTypesInner(
32374 .Many => {32400 .Many => {
32375 // Only works for *[n]T + [*]T -> [*]T32401 // Only works for *[n]T + [*]T -> [*]T
32376 const arr = peer_pointee_array orelse return generic_err;32402 const arr = peer_pointee_array orelse return generic_err;
32377 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| {32403 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), arr.elem_ty)) |pointee| {
32378 ptr_info.pointee_type = pointee;32404 ptr_info.child = pointee.toIntern();
32379 break :good;32405 break :good;
32380 }32406 }
32381 if (arr.elem_ty.toIntern() == .noreturn_type) {32407 if (arr.elem_ty.toIntern() == .noreturn_type) {
...@@ -32387,8 +32413,8 @@ fn resolvePeerTypesInner(...@@ -32387,8 +32413,8 @@ fn resolvePeerTypesInner(
32387 .Slice => {32413 .Slice => {
32388 // Only works for *[n]T + []T -> []T32414 // Only works for *[n]T + []T -> []T
32389 const arr = peer_pointee_array orelse return generic_err;32415 const arr = peer_pointee_array orelse return generic_err;
32390 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| {32416 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), arr.elem_ty)) |pointee| {
32391 ptr_info.pointee_type = pointee;32417 ptr_info.child = pointee.toIntern();
32392 break :good;32418 break :good;
32393 }32419 }
32394 if (arr.elem_ty.toIntern() == .noreturn_type) {32420 if (arr.elem_ty.toIntern() == .noreturn_type) {
...@@ -32399,26 +32425,26 @@ fn resolvePeerTypesInner(...@@ -32399,26 +32425,26 @@ fn resolvePeerTypesInner(
32399 },32425 },
32400 .C => unreachable,32426 .C => unreachable,
32401 },32427 },
32402 .Many => switch (ptr_info.size) {32428 .Many => switch (ptr_info.flags.size) {
32403 .One => {32429 .One => {
32404 // Only works for [*]T + *[n]T -> [*]T32430 // Only works for [*]T + *[n]T -> [*]T
32405 const arr = cur_pointee_array orelse return generic_err;32431 const arr = cur_pointee_array orelse return generic_err;
32406 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| {32432 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.child.toType())) |pointee| {
32407 ptr_info.size = .Many;32433 ptr_info.flags.size = .Many;
32408 ptr_info.pointee_type = pointee;32434 ptr_info.child = pointee.toIntern();
32409 break :good;32435 break :good;
32410 }32436 }
32411 if (arr.elem_ty.toIntern() == .noreturn_type) {32437 if (arr.elem_ty.toIntern() == .noreturn_type) {
32412 // [*]T + *struct{} -> [*]T32438 // [*]T + *struct{} -> [*]T
32413 ptr_info.size = .Many;32439 ptr_info.flags.size = .Many;
32414 ptr_info.pointee_type = peer_info.pointee_type;32440 ptr_info.child = peer_info.child;
32415 break :good;32441 break :good;
32416 }32442 }
32417 return generic_err;32443 return generic_err;
32418 },32444 },
32419 .Many => {32445 .Many => {
32420 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {32446 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32421 ptr_info.pointee_type = pointee;32447 ptr_info.child = pointee.toIntern();
32422 break :good;32448 break :good;
32423 }32449 }
32424 return generic_err;32450 return generic_err;
...@@ -32432,28 +32458,28 @@ fn resolvePeerTypesInner(...@@ -32432,28 +32458,28 @@ fn resolvePeerTypesInner(
32432 } };32458 } };
32433 }32459 }
32434 // Okay, then works for [*]T + "[]T" -> [*]T32460 // Okay, then works for [*]T + "[]T" -> [*]T
32435 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {32461 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32436 ptr_info.size = .Many;32462 ptr_info.flags.size = .Many;
32437 ptr_info.pointee_type = pointee;32463 ptr_info.child = pointee.toIntern();
32438 break :good;32464 break :good;
32439 }32465 }
32440 return generic_err;32466 return generic_err;
32441 },32467 },
32442 .C => unreachable,32468 .C => unreachable,
32443 },32469 },
32444 .Slice => switch (ptr_info.size) {32470 .Slice => switch (ptr_info.flags.size) {
32445 .One => {32471 .One => {
32446 // Only works for []T + *[n]T -> []T32472 // Only works for []T + *[n]T -> []T
32447 const arr = cur_pointee_array orelse return generic_err;32473 const arr = cur_pointee_array orelse return generic_err;
32448 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| {32474 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.child.toType())) |pointee| {
32449 ptr_info.size = .Slice;32475 ptr_info.flags.size = .Slice;
32450 ptr_info.pointee_type = pointee;32476 ptr_info.child = pointee.toIntern();
32451 break :good;32477 break :good;
32452 }32478 }
32453 if (arr.elem_ty.toIntern() == .noreturn_type) {32479 if (arr.elem_ty.toIntern() == .noreturn_type) {
32454 // []T + *struct{} -> []T32480 // []T + *struct{} -> []T
32455 ptr_info.size = .Slice;32481 ptr_info.flags.size = .Slice;
32456 ptr_info.pointee_type = peer_info.pointee_type;32482 ptr_info.child = peer_info.child;
32457 break :good;32483 break :good;
32458 }32484 }
32459 return generic_err;32485 return generic_err;
...@@ -32463,8 +32489,8 @@ fn resolvePeerTypesInner(...@@ -32463,8 +32489,8 @@ fn resolvePeerTypesInner(
32463 return generic_err;32489 return generic_err;
32464 },32490 },
32465 .Slice => {32491 .Slice => {
32466 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {32492 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32467 ptr_info.pointee_type = pointee;32493 ptr_info.child = pointee.toIntern();
32468 break :good;32494 break :good;
32469 }32495 }
32470 return generic_err;32496 return generic_err;
...@@ -32475,40 +32501,43 @@ fn resolvePeerTypesInner(...@@ -32475,40 +32501,43 @@ fn resolvePeerTypesInner(
32475 }32501 }
32476 }32502 }
3247732503
32478 const sentinel_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Array) blk: {32504 const sentinel_ty = switch (ptr_info.flags.size) {
32479 break :blk ptr_info.pointee_type.childType(mod);32505 .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32480 } else ptr_info.pointee_type;32506 .array_type => |array_type| array_type.child,
3248132507 else => ptr_info.child,
32482 // TODO: once InternPool is in, we need to cast the sentinels to sentinel_ty32508 },
32509 .Many, .Slice, .C => ptr_info.child,
32510 };
3248332511
32484 sentinel: {32512 sentinel: {
32485 no_sentinel: {32513 no_sentinel: {
32486 if (peer_sentinel == null) break :no_sentinel;32514 if (peer_sentinel == .none) break :no_sentinel;
32487 if (cur_sentinel == null) break :no_sentinel;32515 if (cur_sentinel == .none) break :no_sentinel;
32488 const peer_sent_coerced = try mod.getCoerced(peer_sentinel.?, sentinel_ty);32516 const peer_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);
32489 const cur_sent_coerced = try mod.getCoerced(cur_sentinel.?, sentinel_ty);32517 const cur_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, cur_sentinel, sentinel_ty);
32490 if (!peer_sent_coerced.eql(cur_sent_coerced, sentinel_ty, mod)) break :no_sentinel;32518 if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel;
32491 // Sentinels match32519 // Sentinels match
32492 if (ptr_info.size == .One) {32520 if (ptr_info.flags.size == .One) switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32493 assert(ptr_info.pointee_type.zigTypeTag(mod) == .Array);32521 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
32494 ptr_info.pointee_type = try mod.arrayType(.{32522 .len = array_type.len,
32495 .len = ptr_info.pointee_type.arrayLen(mod),32523 .child = array_type.child,
32496 .child = ptr_info.pointee_type.childType(mod).toIntern(),32524 .sentinel = cur_sent_coerced,
32497 .sentinel = cur_sent_coerced.toIntern(),32525 })).toIntern(),
32498 });32526 else => unreachable,
32499 } else {32527 } else {
32500 ptr_info.sentinel = cur_sent_coerced;32528 ptr_info.sentinel = cur_sent_coerced;
32501 }32529 }
32502 break :sentinel;32530 break :sentinel;
32503 }32531 }
32504 // Clear existing sentinel32532 // Clear existing sentinel
32505 ptr_info.sentinel = null;32533 ptr_info.sentinel = .none;
32506 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {32534 switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32507 ptr_info.pointee_type = try mod.arrayType(.{32535 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
32508 .len = ptr_info.pointee_type.arrayLen(mod),32536 .len = array_type.len,
32509 .child = ptr_info.pointee_type.childType(mod).toIntern(),32537 .child = array_type.child,
32510 .sentinel = .none,32538 .sentinel = .none,
32511 });32539 })).toIntern(),
32540 else => {},
32512 }32541 }
32513 }32542 }
3251432543
...@@ -32519,17 +32548,22 @@ fn resolvePeerTypesInner(...@@ -32519,17 +32548,22 @@ fn resolvePeerTypesInner(
32519 // &.{} and &.{}, we'll currently have a pointer type of `*[0]noreturn` - we wanted to32548 // &.{} and &.{}, we'll currently have a pointer type of `*[0]noreturn` - we wanted to
32520 // coerce the empty struct to a specific type, but no peer provided one. We need to32549 // coerce the empty struct to a specific type, but no peer provided one. We need to
32521 // detect this case and emit an error.32550 // detect this case and emit an error.
32522 const pointee = opt_ptr_info.?.pointee_type;32551 const pointee = opt_ptr_info.?.child;
32523 if (pointee.toIntern() == .noreturn_type or32552 switch (pointee) {
32524 (pointee.zigTypeTag(mod) == .Array and pointee.childType(mod).toIntern() == .noreturn_type))32553 .noreturn_type => return .{ .conflict = .{
32525 {
32526 return .{ .conflict = .{
32527 .peer_idx_a = first_idx,32554 .peer_idx_a = first_idx,
32528 .peer_idx_b = other_idx,32555 .peer_idx_b = other_idx,
32529 } };32556 } },
32557 else => switch (mod.intern_pool.indexToKey(pointee)) {
32558 .array_type => |array_type| if (array_type.child == .noreturn_type) return .{ .conflict = .{
32559 .peer_idx_a = first_idx,
32560 .peer_idx_b = other_idx,
32561 } },
32562 else => {},
32563 },
32530 }32564 }
3253132565
32532 return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) };32566 return .{ .success = try mod.ptrType(opt_ptr_info.?) };
32533 },32567 },
3253432568
32535 .func => {32569 .func => {
...@@ -33749,6 +33783,8 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -33749,6 +33783,8 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3374933783
33750 .none => unreachable,33784 .none => unreachable,
3375133785
33786 .u0_type,
33787 .i0_type,
33752 .u1_type,33788 .u1_type,
33753 .u8_type,33789 .u8_type,
33754 .i8_type,33790 .i8_type,
...@@ -33797,6 +33833,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -33797,6 +33833,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
33797 .single_const_pointer_to_comptime_int_type,33833 .single_const_pointer_to_comptime_int_type,
33798 .slice_const_u8_type,33834 .slice_const_u8_type,
33799 .slice_const_u8_sentinel_0_type,33835 .slice_const_u8_sentinel_0_type,
33836 .optional_noreturn_type,
33800 .anyerror_void_error_union_type,33837 .anyerror_void_error_union_type,
33801 .generic_poison_type,33838 .generic_poison_type,
33802 .empty_struct_type,33839 .empty_struct_type,
...@@ -33833,18 +33870,25 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -33833,18 +33870,25 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
33833 .call_modifier_type => return sema.getBuiltinType("CallModifier"),33870 .call_modifier_type => return sema.getBuiltinType("CallModifier"),
33834 .prefetch_options_type => return sema.getBuiltinType("PrefetchOptions"),33871 .prefetch_options_type => return sema.getBuiltinType("PrefetchOptions"),
3383533872
33836 _ => switch (mod.intern_pool.indexToKey(ty.toIntern())) {33873 _ => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
33837 .struct_type => |struct_type| {33874 .type_struct,
33838 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return ty;33875 .type_struct_ns,
33839 try sema.resolveTypeFieldsStruct(ty, struct_obj);33876 .type_union_tagged,
33840 return ty;33877 .type_union_untagged,
33841 },33878 .type_union_safety,
33842 .union_type => |union_type| {33879 => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
33843 const union_obj = mod.unionPtr(union_type.index);33880 .struct_type => |struct_type| {
33844 try sema.resolveTypeFieldsUnion(ty, union_obj);33881 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return ty;
33845 return ty;33882 try sema.resolveTypeFieldsStruct(ty, struct_obj);
33883 return ty;
33884 },
33885 .union_type => |union_type| {
33886 const union_obj = mod.unionPtr(union_type.index);
33887 try sema.resolveTypeFieldsUnion(ty, union_obj);
33888 return ty;
33889 },
33890 else => unreachable,
33846 },33891 },
33847
33848 else => return ty,33892 else => return ty,
33849 },33893 },
33850 }33894 }
...@@ -34167,7 +34211,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -34167,7 +34211,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
34167 }34211 }
34168 gop.value_ptr.* = .{34212 gop.value_ptr.* = .{
34169 .ty = Type.noreturn,34213 .ty = Type.noreturn,
34170 .abi_align = 0,34214 .abi_align = .none,
34171 .default_val = .none,34215 .default_val = .none,
34172 .is_comptime = is_comptime,34216 .is_comptime = is_comptime,
34173 .offset = undefined,34217 .offset = undefined,
...@@ -34704,7 +34748,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -34704,7 +34748,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3470434748
34705 gop.value_ptr.* = .{34749 gop.value_ptr.* = .{
34706 .ty = field_ty,34750 .ty = field_ty,
34707 .abi_align = 0,34751 .abi_align = .none,
34708 };34752 };
3470934753
34710 if (align_ref != .none) {34754 if (align_ref != .none) {
...@@ -34720,7 +34764,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -34720,7 +34764,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
34720 else => |e| return e,34764 else => |e| return e,
34721 };34765 };
34722 } else {34766 } else {
34723 gop.value_ptr.abi_align = 0;34767 gop.value_ptr.abi_align = .none;
34724 }34768 }
34725 }34769 }
3472634770
...@@ -34935,231 +34979,311 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {...@@ -34935,231 +34979,311 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
34935pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {34979pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
34936 const mod = sema.mod;34980 const mod = sema.mod;
34937 return switch (ty.toIntern()) {34981 return switch (ty.toIntern()) {
34982 .u0_type,
34983 .i0_type,
34984 => try mod.intValue(ty, 0),
34985 .u1_type,
34986 .u8_type,
34987 .i8_type,
34988 .u16_type,
34989 .i16_type,
34990 .u29_type,
34991 .u32_type,
34992 .i32_type,
34993 .u64_type,
34994 .i64_type,
34995 .u80_type,
34996 .u128_type,
34997 .i128_type,
34998 .usize_type,
34999 .isize_type,
35000 .c_char_type,
35001 .c_short_type,
35002 .c_ushort_type,
35003 .c_int_type,
35004 .c_uint_type,
35005 .c_long_type,
35006 .c_ulong_type,
35007 .c_longlong_type,
35008 .c_ulonglong_type,
35009 .c_longdouble_type,
35010 .f16_type,
35011 .f32_type,
35012 .f64_type,
35013 .f80_type,
35014 .f128_type,
35015 .anyopaque_type,
35016 .bool_type,
35017 .type_type,
35018 .anyerror_type,
35019 .comptime_int_type,
35020 .comptime_float_type,
35021 .enum_literal_type,
35022 .atomic_order_type,
35023 .atomic_rmw_op_type,
35024 .calling_convention_type,
35025 .address_space_type,
35026 .float_mode_type,
35027 .reduce_op_type,
35028 .call_modifier_type,
35029 .prefetch_options_type,
35030 .export_options_type,
35031 .extern_options_type,
35032 .type_info_type,
35033 .manyptr_u8_type,
35034 .manyptr_const_u8_type,
35035 .manyptr_const_u8_sentinel_0_type,
35036 .single_const_pointer_to_comptime_int_type,
35037 .slice_const_u8_type,
35038 .slice_const_u8_sentinel_0_type,
35039 .anyerror_void_error_union_type,
35040 => null,
35041 .void_type => Value.void,
35042 .noreturn_type => Value.@"unreachable",
35043 .anyframe_type => unreachable,
35044 .null_type => Value.null,
35045 .undefined_type => Value.undef,
35046 .optional_noreturn_type => try mod.nullValue(ty),
35047 .generic_poison_type => error.GenericPoison,
34938 .empty_struct_type => Value.empty_struct,35048 .empty_struct_type => Value.empty_struct,
34939 else => switch (mod.intern_pool.indexToKey(ty.toIntern())) {35049 // values, not types
34940 .int_type => |int_type| {35050 .undef,
34941 if (int_type.bits == 0) {35051 .zero,
34942 return try mod.intValue(ty, 0);35052 .zero_usize,
34943 } else {35053 .zero_u8,
34944 return null;35054 .one,
34945 }35055 .one_usize,
34946 },35056 .one_u8,
3494735057 .four_u8,
34948 .ptr_type,35058 .negative_one,
34949 .error_union_type,35059 .calling_convention_c,
34950 .func_type,35060 .calling_convention_inline,
34951 .anyframe_type,35061 .void_value,
34952 .error_set_type,35062 .unreachable_value,
34953 .inferred_error_set_type,35063 .null_value,
35064 .bool_true,
35065 .bool_false,
35066 .empty_struct,
35067 .generic_poison,
35068 // invalid
35069 .var_args_param_type,
35070 .none,
35071 => unreachable,
35072 _ => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
35073 .type_int_signed, // i0 handled above
35074 .type_int_unsigned, // u0 handled above
35075 .type_pointer,
35076 .type_slice,
35077 .type_optional, // ?noreturn handled above
35078 .type_anyframe,
35079 .type_error_union,
35080 .type_error_set,
35081 .type_inferred_error_set,
35082 .type_opaque,
35083 .type_function,
34954 => null,35084 => null,
3495535085 .simple_type, // handled above
34956 inline .array_type, .vector_type => |seq_type, seq_tag| {35086 // values, not types
34957 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;35087 .undef,
34958 if (seq_type.len + @intFromBool(has_sentinel) == 0) return (try mod.intern(.{ .aggregate = .{35088 .runtime_value,
34959 .ty = ty.toIntern(),35089 .simple_value,
34960 .storage = .{ .elems = &.{} },35090 .ptr_decl,
34961 } })).toValue();35091 .ptr_mut_decl,
3496235092 .ptr_comptime_field,
34963 if (try sema.typeHasOnePossibleValue(seq_type.child.toType())) |opv| {35093 .ptr_int,
34964 return (try mod.intern(.{ .aggregate = .{35094 .ptr_eu_payload,
35095 .ptr_opt_payload,
35096 .ptr_elem,
35097 .ptr_field,
35098 .ptr_slice,
35099 .opt_payload,
35100 .opt_null,
35101 .int_u8,
35102 .int_u16,
35103 .int_u32,
35104 .int_i32,
35105 .int_usize,
35106 .int_comptime_int_u32,
35107 .int_comptime_int_i32,
35108 .int_small,
35109 .int_positive,
35110 .int_negative,
35111 .int_lazy_align,
35112 .int_lazy_size,
35113 .error_set_error,
35114 .error_union_error,
35115 .error_union_payload,
35116 .enum_literal,
35117 .enum_tag,
35118 .float_f16,
35119 .float_f32,
35120 .float_f64,
35121 .float_f80,
35122 .float_f128,
35123 .float_c_longdouble_f80,
35124 .float_c_longdouble_f128,
35125 .float_comptime_float,
35126 .variable,
35127 .extern_func,
35128 .func,
35129 .only_possible_value,
35130 .union_value,
35131 .bytes,
35132 .aggregate,
35133 .repeated,
35134 // memoized value, not types
35135 .memoized_call,
35136 => unreachable,
35137 .type_array_big,
35138 .type_array_small,
35139 .type_vector,
35140 .type_enum_auto,
35141 .type_enum_explicit,
35142 .type_enum_nonexhaustive,
35143 .type_struct,
35144 .type_struct_ns,
35145 .type_struct_anon,
35146 .type_tuple_anon,
35147 .type_union_tagged,
35148 .type_union_untagged,
35149 .type_union_safety,
35150 => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
35151 inline .array_type, .vector_type => |seq_type, seq_tag| {
35152 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
35153 if (seq_type.len + @intFromBool(has_sentinel) == 0) return (try mod.intern(.{ .aggregate = .{
34965 .ty = ty.toIntern(),35154 .ty = ty.toIntern(),
34966 .storage = .{ .repeated_elem = opv.toIntern() },35155 .storage = .{ .elems = &.{} },
34967 } })).toValue();35156 } })).toValue();
34968 }
34969 return null;
34970 },
34971 .opt_type => |child| {
34972 if (child == .noreturn_type) {
34973 return try mod.nullValue(ty);
34974 } else {
34975 return null;
34976 }
34977 },
34978
34979 .simple_type => |t| switch (t) {
34980 .f16,
34981 .f32,
34982 .f64,
34983 .f80,
34984 .f128,
34985 .usize,
34986 .isize,
34987 .c_char,
34988 .c_short,
34989 .c_ushort,
34990 .c_int,
34991 .c_uint,
34992 .c_long,
34993 .c_ulong,
34994 .c_longlong,
34995 .c_ulonglong,
34996 .c_longdouble,
34997 .anyopaque,
34998 .bool,
34999 .type,
35000 .anyerror,
35001 .comptime_int,
35002 .comptime_float,
35003 .enum_literal,
35004 .atomic_order,
35005 .atomic_rmw_op,
35006 .calling_convention,
35007 .address_space,
35008 .float_mode,
35009 .reduce_op,
35010 .call_modifier,
35011 .prefetch_options,
35012 .export_options,
35013 .extern_options,
35014 .type_info,
35015 => null,
3501635157
35017 .void => Value.void,35158 if (try sema.typeHasOnePossibleValue(seq_type.child.toType())) |opv| {
35018 .noreturn => Value.@"unreachable",35159 return (try mod.intern(.{ .aggregate = .{
35019 .null => Value.null,35160 .ty = ty.toIntern(),
35020 .undefined => Value.undef,35161 .storage = .{ .repeated_elem = opv.toIntern() },
35162 } })).toValue();
35163 }
35164 return null;
35165 },
3502135166
35022 .generic_poison => return error.GenericPoison,35167 .struct_type => |struct_type| {
35023 },35168 const resolved_ty = try sema.resolveTypeFields(ty);
35024 .struct_type => |struct_type| {35169 if (mod.structPtrUnwrap(struct_type.index)) |s| {
35025 const resolved_ty = try sema.resolveTypeFields(ty);35170 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
35026 if (mod.structPtrUnwrap(struct_type.index)) |s| {35171 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
35027 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());35172 if (field.is_comptime) {
35028 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {35173 field_val.* = field.default_val;
35029 if (field.is_comptime) {35174 continue;
35030 field_val.* = field.default_val;35175 }
35031 continue;35176 if (field.ty.eql(resolved_ty, sema.mod)) {
35032 }35177 const msg = try Module.ErrorMsg.create(
35033 if (field.ty.eql(resolved_ty, sema.mod)) {35178 sema.gpa,
35034 const msg = try Module.ErrorMsg.create(35179 s.srcLoc(sema.mod),
35035 sema.gpa,35180 "struct '{}' depends on itself",
35036 s.srcLoc(sema.mod),35181 .{ty.fmt(sema.mod)},
35037 "struct '{}' depends on itself",35182 );
35038 .{ty.fmt(sema.mod)},35183 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
35039 );35184 return sema.failWithOwnedErrorMsg(msg);
35040 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});35185 }
35041 return sema.failWithOwnedErrorMsg(msg);35186 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {
35187 field_val.* = try field_opv.intern(field.ty, mod);
35188 } else return null;
35042 }35189 }
35043 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {35190
35044 field_val.* = try field_opv.intern(field.ty, mod);35191 // In this case the struct has no runtime-known fields and
35045 } else return null;35192 // therefore has one possible value.
35193 return (try mod.intern(.{ .aggregate = .{
35194 .ty = ty.toIntern(),
35195 .storage = .{ .elems = field_vals },
35196 } })).toValue();
35046 }35197 }
3504735198
35048 // In this case the struct has no runtime-known fields and35199 // In this case the struct has no fields at all and
35049 // therefore has one possible value.35200 // therefore has one possible value.
35050 return (try mod.intern(.{ .aggregate = .{35201 return (try mod.intern(.{ .aggregate = .{
35051 .ty = ty.toIntern(),35202 .ty = ty.toIntern(),
35052 .storage = .{ .elems = field_vals },35203 .storage = .{ .elems = &.{} },
35053 } })).toValue();35204 } })).toValue();
35054 }35205 },
35055
35056 // In this case the struct has no fields at all and
35057 // therefore has one possible value.
35058 return (try mod.intern(.{ .aggregate = .{
35059 .ty = ty.toIntern(),
35060 .storage = .{ .elems = &.{} },
35061 } })).toValue();
35062 },
35063
35064 .anon_struct_type => |tuple| {
35065 for (tuple.values) |val| {
35066 if (val == .none) return null;
35067 }
35068 // In this case the struct has all comptime-known fields and
35069 // therefore has one possible value.
35070 // TODO: write something like getCoercedInts to avoid needing to dupe
35071 return (try mod.intern(.{ .aggregate = .{
35072 .ty = ty.toIntern(),
35073 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values) },
35074 } })).toValue();
35075 },
3507635206
35077 .union_type => |union_type| {35207 .anon_struct_type => |tuple| {
35078 const resolved_ty = try sema.resolveTypeFields(ty);35208 for (tuple.values) |val| {
35079 const union_obj = mod.unionPtr(union_type.index);35209 if (val == .none) return null;
35080 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse35210 }
35081 return null;35211 // In this case the struct has all comptime-known fields and
35082 const fields = union_obj.fields.values();35212 // therefore has one possible value.
35083 if (fields.len == 0) {35213 // TODO: write something like getCoercedInts to avoid needing to dupe
35084 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });35214 return (try mod.intern(.{ .aggregate = .{
35085 return only.toValue();35215 .ty = ty.toIntern(),
35086 }35216 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values) },
35087 const only_field = fields[0];35217 } })).toValue();
35088 if (only_field.ty.eql(resolved_ty, sema.mod)) {35218 },
35089 const msg = try Module.ErrorMsg.create(
35090 sema.gpa,
35091 union_obj.srcLoc(sema.mod),
35092 "union '{}' depends on itself",
35093 .{ty.fmt(sema.mod)},
35094 );
35095 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});
35096 return sema.failWithOwnedErrorMsg(msg);
35097 }
35098 const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse
35099 return null;
35100 const only = try mod.intern(.{ .un = .{
35101 .ty = resolved_ty.toIntern(),
35102 .tag = tag_val.toIntern(),
35103 .val = val_val.toIntern(),
35104 } });
35105 return only.toValue();
35106 },
35107 .opaque_type => null,
35108 .enum_type => |enum_type| switch (enum_type.tag_mode) {
35109 .nonexhaustive => {
35110 if (enum_type.tag_ty == .comptime_int_type) return null;
3511135219
35112 if (try sema.typeHasOnePossibleValue(enum_type.tag_ty.toType())) |int_opv| {35220 .union_type => |union_type| {
35113 const only = try mod.intern(.{ .enum_tag = .{35221 const resolved_ty = try sema.resolveTypeFields(ty);
35114 .ty = ty.toIntern(),35222 const union_obj = mod.unionPtr(union_type.index);
35115 .int = int_opv.toIntern(),35223 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse
35116 } });35224 return null;
35225 const fields = union_obj.fields.values();
35226 if (fields.len == 0) {
35227 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
35117 return only.toValue();35228 return only.toValue();
35118 }35229 }
3511935230 const only_field = fields[0];
35120 return null;35231 if (only_field.ty.eql(resolved_ty, sema.mod)) {
35232 const msg = try Module.ErrorMsg.create(
35233 sema.gpa,
35234 union_obj.srcLoc(sema.mod),
35235 "union '{}' depends on itself",
35236 .{ty.fmt(sema.mod)},
35237 );
35238 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});
35239 return sema.failWithOwnedErrorMsg(msg);
35240 }
35241 const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse
35242 return null;
35243 const only = try mod.intern(.{ .un = .{
35244 .ty = resolved_ty.toIntern(),
35245 .tag = tag_val.toIntern(),
35246 .val = val_val.toIntern(),
35247 } });
35248 return only.toValue();
35121 },35249 },
35122 .auto, .explicit => {
35123 if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null;
3512435250
35125 switch (enum_type.names.len) {35251 .enum_type => |enum_type| switch (enum_type.tag_mode) {
35126 0 => {35252 .nonexhaustive => {
35127 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });35253 if (enum_type.tag_ty == .comptime_int_type) return null;
35254
35255 if (try sema.typeHasOnePossibleValue(enum_type.tag_ty.toType())) |int_opv| {
35256 const only = try mod.intern(.{ .enum_tag = .{
35257 .ty = ty.toIntern(),
35258 .int = int_opv.toIntern(),
35259 } });
35128 return only.toValue();35260 return only.toValue();
35129 },35261 }
35130 1 => return try mod.getCoerced((if (enum_type.values.len == 0)35262
35131 try mod.intern(.{ .int = .{35263 return null;
35132 .ty = enum_type.tag_ty,35264 },
35133 .storage = .{ .u64 = 0 },35265 .auto, .explicit => {
35134 } })35266 if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null;
35135 else35267
35136 enum_type.values[0]).toValue(), ty),35268 switch (enum_type.names.len) {
35137 else => return null,35269 0 => {
35138 }35270 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
35271 return only.toValue();
35272 },
35273 1 => return try mod.getCoerced((if (enum_type.values.len == 0)
35274 try mod.intern(.{ .int = .{
35275 .ty = enum_type.tag_ty,
35276 .storage = .{ .u64 = 0 },
35277 } })
35278 else
35279 enum_type.values[0]).toValue(), ty),
35280 else => return null,
35281 }
35282 },
35139 },35283 },
35140 },
3514135284
35142 // values, not types35285 else => unreachable,
35143 .undef,35286 },
35144 .runtime_value,
35145 .simple_value,
35146 .variable,
35147 .extern_func,
35148 .func,
35149 .int,
35150 .err,
35151 .error_union,
35152 .enum_literal,
35153 .enum_tag,
35154 .empty_enum_value,
35155 .float,
35156 .ptr,
35157 .opt,
35158 .aggregate,
35159 .un,
35160 // memoization, not types
35161 .memoized_call,
35162 => unreachable,
35163 },35287 },
35164 };35288 };
35165}35289}
...@@ -35264,15 +35388,19 @@ fn analyzeComptimeAlloc(...@@ -35264,15 +35388,19 @@ fn analyzeComptimeAlloc(
35264 sema: *Sema,35388 sema: *Sema,
35265 block: *Block,35389 block: *Block,
35266 var_type: Type,35390 var_type: Type,
35267 alignment: u32,35391 alignment: Alignment,
35268) CompileError!Air.Inst.Ref {35392) CompileError!Air.Inst.Ref {
35393 const mod = sema.mod;
35394
35269 // Needed to make an anon decl with type `var_type` (the `finish()` call below).35395 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
35270 _ = try sema.typeHasOnePossibleValue(var_type);35396 _ = try sema.typeHasOnePossibleValue(var_type);
3527135397
35272 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{35398 const ptr_type = try mod.ptrType(.{
35273 .pointee_type = var_type,35399 .child = var_type.toIntern(),
35274 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),35400 .flags = .{
35275 .@"align" = alignment,35401 .alignment = alignment,
35402 .address_space = target_util.defaultAddressSpace(mod.getTarget(), .global_constant),
35403 },
35276 });35404 });
3527735405
35278 var anon_decl = try block.startAnonDecl();35406 var anon_decl = try block.startAnonDecl();
...@@ -35283,15 +35411,15 @@ fn analyzeComptimeAlloc(...@@ -35283,15 +35411,15 @@ fn analyzeComptimeAlloc(
35283 // There will be stores before the first load, but they may be to sub-elements or35411 // There will be stores before the first load, but they may be to sub-elements or
35284 // sub-fields. So we need to initialize with undef to allow the mechanism to expand35412 // sub-fields. So we need to initialize with undef to allow the mechanism to expand
35285 // into fields/elements and have those overridden with stored values.35413 // into fields/elements and have those overridden with stored values.
35286 (try sema.mod.intern(.{ .undef = var_type.toIntern() })).toValue(),35414 (try mod.intern(.{ .undef = var_type.toIntern() })).toValue(),
35287 alignment,35415 alignment,
35288 );35416 );
35289 const decl = sema.mod.declPtr(decl_index);35417 const decl = mod.declPtr(decl_index);
35290 decl.@"align" = alignment;35418 decl.alignment = alignment;
3529135419
35292 try sema.comptime_mutable_decls.append(decl_index);35420 try sema.comptime_mutable_decls.append(decl_index);
35293 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);35421 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
35294 return sema.addConstant(ptr_type, (try sema.mod.intern(.{ .ptr = .{35422 return sema.addConstant(ptr_type, (try mod.intern(.{ .ptr = .{
35295 .ty = ptr_type.toIntern(),35423 .ty = ptr_type.toIntern(),
35296 .addr = .{ .mut_decl = .{35424 .addr = .{ .mut_decl = .{
35297 .decl = decl_index,35425 .decl = decl_index,
...@@ -35676,14 +35804,10 @@ fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {...@@ -35676,14 +35804,10 @@ fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {
35676/// Not valid to call for packed unions.35804/// Not valid to call for packed unions.
35677/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.35805/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.
35678fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 {35806fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 {
35679 const mod = sema.mod;35807 return @intCast(u32, if (field.ty.isNoReturn(sema.mod))
35680 if (field.ty.zigTypeTag(mod) == .NoReturn) {35808 0
35681 return @as(u32, 0);35809 else
35682 } else if (field.abi_align == 0) {35810 field.abi_align.toByteUnitsOptional() orelse try sema.typeAbiAlignment(field.ty));
35683 return sema.typeAbiAlignment(field.ty);
35684 } else {
35685 return field.abi_align;
35686 }
35687}35811}
3568835812
35689/// Synchronize logic with `Type.isFnOrHasRuntimeBits`.35813/// Synchronize logic with `Type.isFnOrHasRuntimeBits`.
...@@ -36334,16 +36458,16 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {...@@ -36334,16 +36458,16 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
36334 const mod = sema.mod;36458 const mod = sema.mod;
36335 const ptr_info = ptr_ty.ptrInfo(mod);36459 const ptr_info = ptr_ty.ptrInfo(mod);
36336 const elem_ty = ptr_ty.elemType2(mod);36460 const elem_ty = ptr_ty.elemType2(mod);
36337 const allow_zero = ptr_info.@"allowzero" and (offset orelse 0) == 0;36461 const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0;
36338 const parent_ty = ptr_ty.childType(mod);36462 const parent_ty = ptr_ty.childType(mod);
3633936463
36340 const VI = Type.Payload.Pointer.Data.VectorIndex;36464 const VI = InternPool.Key.PtrType.VectorIndex;
3634136465
36342 const vector_info: struct {36466 const vector_info: struct {
36343 host_size: u16 = 0,36467 host_size: u16 = 0,
36344 alignment: u32 = 0,36468 alignment: u32 = 0,
36345 vector_index: VI = .none,36469 vector_index: VI = .none,
36346 } = if (parent_ty.isVector(mod) and ptr_info.size == .One) blk: {36470 } = if (parent_ty.isVector(mod) and ptr_info.flags.size == .One) blk: {
36347 const elem_bits = elem_ty.bitSize(mod);36471 const elem_bits = elem_ty.bitSize(mod);
36348 if (elem_bits == 0) break :blk .{};36472 if (elem_bits == 0) break :blk .{};
36349 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);36473 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
...@@ -36351,17 +36475,17 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {...@@ -36351,17 +36475,17 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3635136475
36352 break :blk .{36476 break :blk .{
36353 .host_size = @intCast(u16, parent_ty.arrayLen(mod)),36477 .host_size = @intCast(u16, parent_ty.arrayLen(mod)),
36354 .alignment = @intCast(u16, parent_ty.abiAlignment(mod)),36478 .alignment = @intCast(u32, parent_ty.abiAlignment(mod)),
36355 .vector_index = if (offset) |some| @enumFromInt(VI, some) else .runtime,36479 .vector_index = if (offset) |some| @enumFromInt(VI, some) else .runtime,
36356 };36480 };
36357 } else .{};36481 } else .{};
3635836482
36359 const alignment: u32 = a: {36483 const alignment: Alignment = a: {
36360 // Calculate the new pointer alignment.36484 // Calculate the new pointer alignment.
36361 if (ptr_info.@"align" == 0) {36485 if (ptr_info.flags.alignment == .none) {
36362 if (vector_info.alignment != 0) break :a vector_info.alignment;36486 if (vector_info.alignment != 0) break :a Alignment.fromNonzeroByteUnits(vector_info.alignment);
36363 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.36487 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
36364 break :a 0;36488 break :a .none;
36365 }36489 }
36366 // If the addend is not a comptime-known value we can still count on36490 // If the addend is not a comptime-known value we can still count on
36367 // it being a multiple of the type size.36491 // it being a multiple of the type size.
...@@ -36371,18 +36495,27 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {...@@ -36371,18 +36495,27 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
36371 // The resulting pointer is aligned to the lcd between the offset (an36495 // The resulting pointer is aligned to the lcd between the offset (an
36372 // arbitrary number) and the alignment factor (always a power of two,36496 // arbitrary number) and the alignment factor (always a power of two,
36373 // non zero).36497 // non zero).
36374 const new_align = @as(u32, 1) << @intCast(u5, @ctz(addend | ptr_info.@"align"));36498 const new_align = @enumFromInt(Alignment, @min(
36499 @ctz(addend),
36500 @intFromEnum(ptr_info.flags.alignment),
36501 ));
36502 assert(new_align != .none);
36375 break :a new_align;36503 break :a new_align;
36376 };36504 };
36377 return try Type.ptr(sema.arena, sema.mod, .{36505 return mod.ptrType(.{
36378 .pointee_type = elem_ty,36506 .child = elem_ty.toIntern(),
36379 .mutable = ptr_info.mutable,36507 .flags = .{
36380 .@"addrspace" = ptr_info.@"addrspace",36508 .alignment = alignment,
36381 .@"allowzero" = allow_zero,36509 .is_const = ptr_info.flags.is_const,
36382 .@"volatile" = ptr_info.@"volatile",36510 .is_volatile = ptr_info.flags.is_volatile,
36383 .@"align" = alignment,36511 .is_allowzero = is_allowzero,
36384 .host_size = vector_info.host_size,36512 .address_space = ptr_info.flags.address_space,
36385 .vector_index = vector_info.vector_index,36513 .vector_index = vector_info.vector_index,
36514 },
36515 .packed_offset = .{
36516 .host_size = vector_info.host_size,
36517 .bit_offset = 0,
36518 },
36386 });36519 });
36387}36520}
3638836521
src/Zir.zig+3
...@@ -2005,6 +2005,8 @@ pub const Inst = struct {...@@ -2005,6 +2005,8 @@ pub const Inst = struct {
2005 /// The tag type is specified so that it is safe to bitcast between `[]u32`2005 /// The tag type is specified so that it is safe to bitcast between `[]u32`
2006 /// and `[]Ref`.2006 /// and `[]Ref`.
2007 pub const Ref = enum(u32) {2007 pub const Ref = enum(u32) {
2008 u0_type = @intFromEnum(InternPool.Index.u0_type),
2009 i0_type = @intFromEnum(InternPool.Index.i0_type),
2008 u1_type = @intFromEnum(InternPool.Index.u1_type),2010 u1_type = @intFromEnum(InternPool.Index.u1_type),
2009 u8_type = @intFromEnum(InternPool.Index.u8_type),2011 u8_type = @intFromEnum(InternPool.Index.u8_type),
2010 i8_type = @intFromEnum(InternPool.Index.i8_type),2012 i8_type = @intFromEnum(InternPool.Index.i8_type),
...@@ -2064,6 +2066,7 @@ pub const Inst = struct {...@@ -2064,6 +2066,7 @@ pub const Inst = struct {
2064 single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),2066 single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),
2065 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),2067 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
2066 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),2068 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
2069 optional_noreturn_type = @intFromEnum(InternPool.Index.optional_noreturn_type),
2067 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),2070 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
2068 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),2071 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
2069 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),2072 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),
src/arch/wasm/CodeGen.zig+15-15
...@@ -2308,25 +2308,25 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2308,25 +2308,25 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
2308 const ptr_info = ptr_ty.ptrInfo(mod);2308 const ptr_info = ptr_ty.ptrInfo(mod);
2309 const ty = ptr_ty.childType(mod);2309 const ty = ptr_ty.childType(mod);
23102310
2311 if (ptr_info.host_size == 0) {2311 if (ptr_info.packed_offset.host_size == 0) {
2312 try func.store(lhs, rhs, ty, 0);2312 try func.store(lhs, rhs, ty, 0);
2313 } else {2313 } else {
2314 // at this point we have a non-natural alignment, we must2314 // at this point we have a non-natural alignment, we must
2315 // load the value, and then shift+or the rhs into the result location.2315 // load the value, and then shift+or the rhs into the result location.
2316 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);2316 const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
23172317
2318 if (isByRef(int_elem_ty, mod)) {2318 if (isByRef(int_elem_ty, mod)) {
2319 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});2319 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
2320 }2320 }
23212321
2322 var mask = @intCast(u64, (@as(u65, 1) << @intCast(u7, ty.bitSize(mod))) - 1);2322 var mask = @intCast(u64, (@as(u65, 1) << @intCast(u7, ty.bitSize(mod))) - 1);
2323 mask <<= @intCast(u6, ptr_info.bit_offset);2323 mask <<= @intCast(u6, ptr_info.packed_offset.bit_offset);
2324 mask ^= ~@as(u64, 0);2324 mask ^= ~@as(u64, 0);
2325 const shift_val = if (ptr_info.host_size <= 4)2325 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2326 WValue{ .imm32 = ptr_info.bit_offset }2326 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
2327 else2327 else
2328 WValue{ .imm64 = ptr_info.bit_offset };2328 WValue{ .imm64 = ptr_info.packed_offset.bit_offset };
2329 const mask_val = if (ptr_info.host_size <= 4)2329 const mask_val = if (ptr_info.packed_offset.host_size <= 4)
2330 WValue{ .imm32 = @truncate(u32, mask) }2330 WValue{ .imm32 = @truncate(u32, mask) }
2331 else2331 else
2332 WValue{ .imm64 = mask };2332 WValue{ .imm64 = mask };
...@@ -2335,7 +2335,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2335,7 +2335,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
2335 const loaded = try func.load(lhs, int_elem_ty, 0);2335 const loaded = try func.load(lhs, int_elem_ty, 0);
2336 const anded = try func.binOp(loaded, mask_val, int_elem_ty, .@"and");2336 const anded = try func.binOp(loaded, mask_val, int_elem_ty, .@"and");
2337 const extended_value = try func.intcast(rhs, ty, int_elem_ty);2337 const extended_value = try func.intcast(rhs, ty, int_elem_ty);
2338 const shifted_value = if (ptr_info.bit_offset > 0) shifted: {2338 const shifted_value = if (ptr_info.packed_offset.bit_offset > 0) shifted: {
2339 break :shifted try func.binOp(extended_value, shift_val, int_elem_ty, .shl);2339 break :shifted try func.binOp(extended_value, shift_val, int_elem_ty, .shl);
2340 } else extended_value;2340 } else extended_value;
2341 const result = try func.binOp(anded, shifted_value, int_elem_ty, .@"or");2341 const result = try func.binOp(anded, shifted_value, int_elem_ty, .@"or");
...@@ -2468,18 +2468,18 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2468,18 +2468,18 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2468 break :result new_local;2468 break :result new_local;
2469 }2469 }
24702470
2471 if (ptr_info.host_size == 0) {2471 if (ptr_info.packed_offset.host_size == 0) {
2472 const stack_loaded = try func.load(operand, ty, 0);2472 const stack_loaded = try func.load(operand, ty, 0);
2473 break :result try stack_loaded.toLocal(func, ty);2473 break :result try stack_loaded.toLocal(func, ty);
2474 }2474 }
24752475
2476 // at this point we have a non-natural alignment, we must2476 // at this point we have a non-natural alignment, we must
2477 // shift the value to obtain the correct bit.2477 // shift the value to obtain the correct bit.
2478 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);2478 const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
2479 const shift_val = if (ptr_info.host_size <= 4)2479 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2480 WValue{ .imm32 = ptr_info.bit_offset }2480 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
2481 else if (ptr_info.host_size <= 8)2481 else if (ptr_info.packed_offset.host_size <= 8)
2482 WValue{ .imm64 = ptr_info.bit_offset }2482 WValue{ .imm64 = ptr_info.packed_offset.bit_offset }
2483 else2483 else
2484 return func.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{});2484 return func.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{});
24852485
...@@ -3699,7 +3699,7 @@ fn structFieldPtr(...@@ -3699,7 +3699,7 @@ fn structFieldPtr(
3699 const offset = switch (struct_ty.containerLayout(mod)) {3699 const offset = switch (struct_ty.containerLayout(mod)) {
3700 .Packed => switch (struct_ty.zigTypeTag(mod)) {3700 .Packed => switch (struct_ty.zigTypeTag(mod)) {
3701 .Struct => offset: {3701 .Struct => offset: {
3702 if (result_ty.ptrInfo(mod).host_size != 0) {3702 if (result_ty.ptrInfo(mod).packed_offset.host_size != 0) {
3703 break :offset @as(u32, 0);3703 break :offset @as(u32, 0);
3704 }3704 }
3705 break :offset struct_ty.packedStructFieldByteOffset(index, mod);3705 break :offset struct_ty.packedStructFieldByteOffset(index, mod);
src/arch/wasm/abi.zig+2-2
...@@ -34,8 +34,8 @@ pub fn classifyType(ty: Type, mod: *Module) [2]Class {...@@ -34,8 +34,8 @@ pub fn classifyType(ty: Type, mod: *Module) [2]Class {
34 if (ty.structFieldCount(mod) > 1) return memory;34 if (ty.structFieldCount(mod) > 1) return memory;
35 // When the struct's alignment is non-natural35 // When the struct's alignment is non-natural
36 const field = ty.structFields(mod).values()[0];36 const field = ty.structFields(mod).values()[0];
37 if (field.abi_align != 0) {37 if (field.abi_align != .none) {
38 if (field.abi_align > field.ty.abiAlignment(mod)) {38 if (field.abi_align.toByteUnitsOptional().? > field.ty.abiAlignment(mod)) {
39 return memory;39 return memory;
40 }40 }
41 }41 }
src/arch/x86_64/CodeGen.zig+10-10
...@@ -694,7 +694,7 @@ pub fn generate(...@@ -694,7 +694,7 @@ pub fn generate(
694 FrameAlloc.init(.{694 FrameAlloc.init(.{
695 .size = 0,695 .size = 0,
696 .alignment = if (mod.align_stack_fns.get(module_fn_index)) |set_align_stack|696 .alignment = if (mod.align_stack_fns.get(module_fn_index)) |set_align_stack|
697 set_align_stack.alignment697 @intCast(u32, set_align_stack.alignment.toByteUnitsOptional().?)
698 else698 else
699 1,699 1,
700 }),700 }),
...@@ -5254,12 +5254,12 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn...@@ -5254,12 +5254,12 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn
5254 const mod = self.bin_file.options.module.?;5254 const mod = self.bin_file.options.module.?;
5255 const ptr_info = ptr_ty.ptrInfo(mod);5255 const ptr_info = ptr_ty.ptrInfo(mod);
52565256
5257 const val_ty = ptr_info.pointee_type;5257 const val_ty = ptr_info.child.toType();
5258 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));5258 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));
5259 const limb_abi_size: u32 = @min(val_abi_size, 8);5259 const limb_abi_size: u32 = @min(val_abi_size, 8);
5260 const limb_abi_bits = limb_abi_size * 8;5260 const limb_abi_bits = limb_abi_size * 8;
5261 const val_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);5261 const val_byte_off = @intCast(i32, ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size);
5262 const val_bit_off = ptr_info.bit_offset % limb_abi_bits;5262 const val_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;
5263 const val_extra_bits = self.regExtraBits(val_ty);5263 const val_extra_bits = self.regExtraBits(val_ty);
52645264
5265 if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{5265 if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{
...@@ -5385,7 +5385,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -5385,7 +5385,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
5385 else5385 else
5386 try self.allocRegOrMem(inst, true);5386 try self.allocRegOrMem(inst, true);
53875387
5388 if (ptr_ty.ptrInfo(mod).host_size > 0) {5388 if (ptr_ty.ptrInfo(mod).packed_offset.host_size > 0) {
5389 try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv);5389 try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv);
5390 } else {5390 } else {
5391 try self.load(dst_mcv, ptr_ty, ptr_mcv);5391 try self.load(dst_mcv, ptr_ty, ptr_mcv);
...@@ -5400,12 +5400,12 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In...@@ -5400,12 +5400,12 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
5400 const ptr_info = ptr_ty.ptrInfo(mod);5400 const ptr_info = ptr_ty.ptrInfo(mod);
5401 const src_ty = ptr_ty.childType(mod);5401 const src_ty = ptr_ty.childType(mod);
54025402
5403 const limb_abi_size: u16 = @min(ptr_info.host_size, 8);5403 const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8);
5404 const limb_abi_bits = limb_abi_size * 8;5404 const limb_abi_bits = limb_abi_size * 8;
54055405
5406 const src_bit_size = src_ty.bitSize(mod);5406 const src_bit_size = src_ty.bitSize(mod);
5407 const src_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);5407 const src_byte_off = @intCast(i32, ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size);
5408 const src_bit_off = ptr_info.bit_offset % limb_abi_bits;5408 const src_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;
54095409
5410 const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);5410 const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);
5411 const ptr_lock = self.register_manager.lockRegAssumeUnused(ptr_reg);5411 const ptr_lock = self.register_manager.lockRegAssumeUnused(ptr_reg);
...@@ -5516,7 +5516,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -5516,7 +5516,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
5516 const ptr_mcv = try self.resolveInst(bin_op.lhs);5516 const ptr_mcv = try self.resolveInst(bin_op.lhs);
5517 const ptr_ty = self.typeOf(bin_op.lhs);5517 const ptr_ty = self.typeOf(bin_op.lhs);
5518 const src_mcv = try self.resolveInst(bin_op.rhs);5518 const src_mcv = try self.resolveInst(bin_op.rhs);
5519 if (ptr_ty.ptrInfo(mod).host_size > 0) {5519 if (ptr_ty.ptrInfo(mod).packed_offset.host_size > 0) {
5520 try self.packedStore(ptr_ty, ptr_mcv, src_mcv);5520 try self.packedStore(ptr_ty, ptr_mcv, src_mcv);
5521 } else {5521 } else {
5522 try self.store(ptr_ty, ptr_mcv, src_mcv);5522 try self.store(ptr_ty, ptr_mcv, src_mcv);
...@@ -5545,7 +5545,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32...@@ -5545,7 +5545,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
5545 const field_offset = @intCast(i32, switch (container_ty.containerLayout(mod)) {5545 const field_offset = @intCast(i32, switch (container_ty.containerLayout(mod)) {
5546 .Auto, .Extern => container_ty.structFieldOffset(index, mod),5546 .Auto, .Extern => container_ty.structFieldOffset(index, mod),
5547 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and5547 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and
5548 ptr_field_ty.ptrInfo(mod).host_size == 0)5548 ptr_field_ty.ptrInfo(mod).packed_offset.host_size == 0)
5549 container_ty.packedStructFieldByteOffset(index, mod)5549 container_ty.packedStructFieldByteOffset(index, mod)
5550 else5550 else
5551 0,5551 0,
src/arch/x86_64/abi.zig+4-4
...@@ -223,8 +223,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {...@@ -223,8 +223,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {
223 var byte_i: usize = 0; // out of 8223 var byte_i: usize = 0; // out of 8
224 const fields = ty.structFields(mod);224 const fields = ty.structFields(mod);
225 for (fields.values()) |field| {225 for (fields.values()) |field| {
226 if (field.abi_align != 0) {226 if (field.abi_align != .none) {
227 if (field.abi_align < field.ty.abiAlignment(mod)) {227 if (field.abi_align.toByteUnitsOptional().? < field.ty.abiAlignment(mod)) {
228 return memory_class;228 return memory_class;
229 }229 }
230 }230 }
...@@ -340,8 +340,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {...@@ -340,8 +340,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {
340340
341 const fields = ty.unionFields(mod);341 const fields = ty.unionFields(mod);
342 for (fields.values()) |field| {342 for (fields.values()) |field| {
343 if (field.abi_align != 0) {343 if (field.abi_align != .none) {
344 if (field.abi_align < field.ty.abiAlignment(mod)) {344 if (field.abi_align.toByteUnitsOptional().? < field.ty.abiAlignment(mod)) {
345 return memory_class;345 return memory_class;
346 }346 }
347 }347 }
src/codegen/c.zig+33-28
...@@ -1714,7 +1714,7 @@ pub const DeclGen = struct {...@@ -1714,7 +1714,7 @@ pub const DeclGen = struct {
1714 ty: Type,1714 ty: Type,
1715 name: CValue,1715 name: CValue,
1716 qualifiers: CQualifiers,1716 qualifiers: CQualifiers,
1717 alignment: u32,1717 alignment: u64,
1718 kind: CType.Kind,1718 kind: CType.Kind,
1719 ) error{ OutOfMemory, AnalysisFail }!void {1719 ) error{ OutOfMemory, AnalysisFail }!void {
1720 const mod = dg.module;1720 const mod = dg.module;
...@@ -1733,10 +1733,10 @@ pub const DeclGen = struct {...@@ -1733,10 +1733,10 @@ pub const DeclGen = struct {
1733 const store = &dg.ctypes.set;1733 const store = &dg.ctypes.set;
1734 const mod = dg.module;1734 const mod = dg.module;
17351735
1736 switch (std.math.order(alignas.@"align", alignas.abi)) {1736 switch (alignas.abiOrder()) {
1737 .lt => try w.print("zig_under_align({}) ", .{alignas.getAlign()}),1737 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
1738 .eq => {},1738 .eq => {},
1739 .gt => try w.print("zig_align({}) ", .{alignas.getAlign()}),1739 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
1740 }1740 }
17411741
1742 const trailing =1742 const trailing =
...@@ -1840,7 +1840,7 @@ pub const DeclGen = struct {...@@ -1840,7 +1840,7 @@ pub const DeclGen = struct {
1840 decl.ty,1840 decl.ty,
1841 .{ .decl = decl_index },1841 .{ .decl = decl_index },
1842 CQualifiers.init(.{ .@"const" = variable.is_const }),1842 CQualifiers.init(.{ .@"const" = variable.is_const }),
1843 decl.@"align",1843 @intCast(u32, decl.alignment.toByteUnits(0)),
1844 .complete,1844 .complete,
1845 );1845 );
1846 try fwd_decl_writer.writeAll(";\n");1846 try fwd_decl_writer.writeAll(";\n");
...@@ -2314,10 +2314,10 @@ fn renderAggregateFields(...@@ -2314,10 +2314,10 @@ fn renderAggregateFields(
2314 const fields = cty.fields();2314 const fields = cty.fields();
2315 for (fields) |field| {2315 for (fields) |field| {
2316 try writer.writeByteNTimes(' ', indent + 1);2316 try writer.writeByteNTimes(' ', indent + 1);
2317 switch (std.math.order(field.alignas.@"align", field.alignas.abi)) {2317 switch (field.alignas.abiOrder()) {
2318 .lt => try writer.print("zig_under_align({}) ", .{field.alignas.getAlign()}),2318 .lt => try writer.print("zig_under_align({}) ", .{field.alignas.toByteUnits()}),
2319 .eq => {},2319 .eq => {},
2320 .gt => try writer.print("zig_align({}) ", .{field.alignas.getAlign()}),2320 .gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),
2321 }2321 }
2322 const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});2322 const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});
2323 try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });2323 try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });
...@@ -2639,7 +2639,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2639,7 +2639,7 @@ pub fn genFunc(f: *Function) !void {
2639 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {2639 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
2640 const lhs_ty = ctx.keys[lhs_index];2640 const lhs_ty = ctx.keys[lhs_index];
2641 const rhs_ty = ctx.keys[rhs_index];2641 const rhs_ty = ctx.keys[rhs_index];
2642 return lhs_ty.alignas.getAlign() > rhs_ty.alignas.getAlign();2642 return lhs_ty.alignas.order(rhs_ty.alignas).compare(.gt);
2643 }2643 }
2644 };2644 };
2645 free_locals.sort(SortContext{ .keys = free_locals.keys() });2645 free_locals.sort(SortContext{ .keys = free_locals.keys() });
...@@ -2690,7 +2690,7 @@ pub fn genDecl(o: *Object) !void {...@@ -2690,7 +2690,7 @@ pub fn genDecl(o: *Object) !void {
2690 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");2690 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
2691 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|2691 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2692 try w.print("zig_linksection(\"{s}\", ", .{s});2692 try w.print("zig_linksection(\"{s}\", ", .{s});
2693 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.@"align", .complete);2693 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.alignment.toByteUnits(0), .complete);
2694 if (decl.@"linksection" != .none) try w.writeAll(", read, write)");2694 if (decl.@"linksection" != .none) try w.writeAll(", read, write)");
2695 try w.writeAll(" = ");2695 try w.writeAll(" = ");
2696 try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);2696 try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);
...@@ -2701,14 +2701,14 @@ pub fn genDecl(o: *Object) !void {...@@ -2701,14 +2701,14 @@ pub fn genDecl(o: *Object) !void {
2701 const fwd_decl_writer = o.dg.fwd_decl.writer();2701 const fwd_decl_writer = o.dg.fwd_decl.writer();
27022702
2703 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");2703 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2704 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, decl.@"align", .complete);2704 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, decl.alignment.toByteUnits(0), .complete);
2705 try fwd_decl_writer.writeAll(";\n");2705 try fwd_decl_writer.writeAll(";\n");
27062706
2707 const w = o.writer();2707 const w = o.writer();
2708 if (!is_global) try w.writeAll("static ");2708 if (!is_global) try w.writeAll("static ");
2709 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|2709 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2710 try w.print("zig_linksection(\"{s}\", ", .{s});2710 try w.print("zig_linksection(\"{s}\", ", .{s});
2711 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, decl.@"align", .complete);2711 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, decl.alignment.toByteUnits(0), .complete);
2712 if (decl.@"linksection" != .none) try w.writeAll(", read)");2712 if (decl.@"linksection" != .none) try w.writeAll(", read)");
2713 try w.writeAll(" = ");2713 try w.writeAll(" = ");
2714 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);2714 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);
...@@ -3324,7 +3324,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3324,7 +3324,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3324 const ptr_ty = f.typeOf(ty_op.operand);3324 const ptr_ty = f.typeOf(ty_op.operand);
3325 const ptr_scalar_ty = ptr_ty.scalarType(mod);3325 const ptr_scalar_ty = ptr_ty.scalarType(mod);
3326 const ptr_info = ptr_scalar_ty.ptrInfo(mod);3326 const ptr_info = ptr_scalar_ty.ptrInfo(mod);
3327 const src_ty = ptr_info.pointee_type;3327 const src_ty = ptr_info.child.toType();
33283328
3329 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) {3329 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3330 try reap(f, inst, &.{ty_op.operand});3330 try reap(f, inst, &.{ty_op.operand});
...@@ -3335,7 +3335,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3335,7 +3335,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33353335
3336 try reap(f, inst, &.{ty_op.operand});3336 try reap(f, inst, &.{ty_op.operand});
33373337
3338 const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(mod);3338 const is_aligned = if (ptr_info.flags.alignment.toByteUnitsOptional()) |alignment|
3339 alignment >= src_ty.abiAlignment(mod)
3340 else
3341 true;
3339 const is_array = lowersToArray(src_ty, mod);3342 const is_array = lowersToArray(src_ty, mod);
3340 const need_memcpy = !is_aligned or is_array;3343 const need_memcpy = !is_aligned or is_array;
33413344
...@@ -3354,12 +3357,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3354,12 +3357,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3354 try writer.writeAll(", sizeof(");3357 try writer.writeAll(", sizeof(");
3355 try f.renderType(writer, src_ty);3358 try f.renderType(writer, src_ty);
3356 try writer.writeAll("))");3359 try writer.writeAll("))");
3357 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {3360 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3358 const host_bits: u16 = ptr_info.host_size * 8;3361 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;
3359 const host_ty = try mod.intType(.unsigned, host_bits);3362 const host_ty = try mod.intType(.unsigned, host_bits);
33603363
3361 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));3364 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
3362 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.bit_offset);3365 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
33633366
3364 const field_ty = try mod.intType(.unsigned, @intCast(u16, src_ty.bitSize(mod)));3367 const field_ty = try mod.intType(.unsigned, @intCast(u16, src_ty.bitSize(mod)));
33653368
...@@ -3593,20 +3596,22 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3593,20 +3596,22 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
35933596
3594 if (val_is_undef) {3597 if (val_is_undef) {
3595 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3598 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3596 if (safety and ptr_info.host_size == 0) {3599 if (safety and ptr_info.packed_offset.host_size == 0) {
3597 const writer = f.object.writer();3600 const writer = f.object.writer();
3598 try writer.writeAll("memset(");3601 try writer.writeAll("memset(");
3599 try f.writeCValue(writer, ptr_val, .FunctionArgument);3602 try f.writeCValue(writer, ptr_val, .FunctionArgument);
3600 try writer.writeAll(", 0xaa, sizeof(");3603 try writer.writeAll(", 0xaa, sizeof(");
3601 try f.renderType(writer, ptr_info.pointee_type);3604 try f.renderType(writer, ptr_info.child.toType());
3602 try writer.writeAll("));\n");3605 try writer.writeAll("));\n");
3603 }3606 }
3604 return .none;3607 return .none;
3605 }3608 }
36063609
3607 const is_aligned = ptr_info.@"align" == 0 or3610 const is_aligned = if (ptr_info.flags.alignment.toByteUnitsOptional()) |alignment|
3608 ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(mod);3611 alignment >= src_ty.abiAlignment(mod)
3609 const is_array = lowersToArray(ptr_info.pointee_type, mod);3612 else
3613 true;
3614 const is_array = lowersToArray(ptr_info.child.toType(), mod);
3610 const need_memcpy = !is_aligned or is_array;3615 const need_memcpy = !is_aligned or is_array;
36113616
3612 const src_val = try f.resolveInst(bin_op.rhs);3617 const src_val = try f.resolveInst(bin_op.rhs);
...@@ -3618,7 +3623,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3618,7 +3623,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3618 if (need_memcpy) {3623 if (need_memcpy) {
3619 // For this memcpy to safely work we need the rhs to have the same3624 // For this memcpy to safely work we need the rhs to have the same
3620 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).3625 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
3621 assert(src_ty.eql(ptr_info.pointee_type, f.object.dg.module));3626 assert(src_ty.eql(ptr_info.child.toType(), f.object.dg.module));
36223627
3623 // If the source is a constant, writeCValue will emit a brace initialization3628 // If the source is a constant, writeCValue will emit a brace initialization
3624 // so work around this by initializing into new local.3629 // so work around this by initializing into new local.
...@@ -3646,12 +3651,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3646,12 +3651,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3646 if (src_val == .constant) {3651 if (src_val == .constant) {
3647 try freeLocal(f, inst, array_src.new_local, 0);3652 try freeLocal(f, inst, array_src.new_local, 0);
3648 }3653 }
3649 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {3654 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3650 const host_bits = ptr_info.host_size * 8;3655 const host_bits = ptr_info.packed_offset.host_size * 8;
3651 const host_ty = try mod.intType(.unsigned, host_bits);3656 const host_ty = try mod.intType(.unsigned, host_bits);
36523657
3653 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));3658 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
3654 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.bit_offset);3659 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset);
36553660
3656 const src_bits = src_ty.bitSize(mod);3661 const src_bits = src_ty.bitSize(mod);
36573662
...@@ -3663,7 +3668,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3663,7 +3668,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3663 defer mask.deinit();3668 defer mask.deinit();
36643669
3665 try mask.setTwosCompIntLimit(.max, .unsigned, @intCast(usize, src_bits));3670 try mask.setTwosCompIntLimit(.max, .unsigned, @intCast(usize, src_bits));
3666 try mask.shiftLeft(&mask, ptr_info.bit_offset);3671 try mask.shiftLeft(&mask, ptr_info.packed_offset.bit_offset);
3667 try mask.bitNotWrap(&mask, .unsigned, host_bits);3672 try mask.bitNotWrap(&mask, .unsigned, host_bits);
36683673
3669 const mask_val = try mod.intValue_big(host_ty, mask.toConst());3674 const mask_val = try mod.intValue_big(host_ty, mask.toConst());
...@@ -5201,7 +5206,7 @@ fn fieldLocation(...@@ -5201,7 +5206,7 @@ fn fieldLocation(
5201 else5206 else
5202 .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } };5207 .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } };
5203 } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,5208 } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,
5204 .Packed => if (field_ptr_ty.ptrInfo(mod).host_size == 0)5209 .Packed => if (field_ptr_ty.ptrInfo(mod).packed_offset.host_size == 0)
5205 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }5210 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }
5206 else5211 else
5207 .begin,5212 .begin,
src/codegen/c/type.zig+31-28
...@@ -6,6 +6,7 @@ const assert = std.debug.assert;...@@ -6,6 +6,7 @@ const assert = std.debug.assert;
6const autoHash = std.hash.autoHash;6const autoHash = std.hash.autoHash;
7const Target = std.Target;7const Target = std.Target;
88
9const Alignment = @import("../../InternPool.zig").Alignment;
9const Module = @import("../../Module.zig");10const Module = @import("../../Module.zig");
10const Type = @import("../../type.zig").Type;11const Type = @import("../../type.zig").Type;
1112
...@@ -280,16 +281,15 @@ pub const CType = extern union {...@@ -280,16 +281,15 @@ pub const CType = extern union {
280 };281 };
281282
282 pub const AlignAs = struct {283 pub const AlignAs = struct {
283 @"align": std.math.Log2Int(u32),284 @"align": Alignment,
284 abi: std.math.Log2Int(u32),285 abi: Alignment,
285286
286 pub fn init(alignment: u32, abi_alignment: u32) AlignAs {287 pub fn init(alignment: u64, abi_alignment: u32) AlignAs {
287 const actual_align = if (alignment != 0) alignment else abi_alignment;288 const @"align" = Alignment.fromByteUnits(alignment);
288 assert(std.math.isPowerOfTwo(actual_align));289 const abi_align = Alignment.fromNonzeroByteUnits(abi_alignment);
289 assert(std.math.isPowerOfTwo(abi_alignment));
290 return .{290 return .{
291 .@"align" = std.math.log2_int(u32, actual_align),291 .@"align" = if (@"align" != .none) @"align" else abi_align,
292 .abi = std.math.log2_int(u32, abi_alignment),292 .abi = abi_align,
293 };293 };
294 }294 }
295 pub fn abiAlign(ty: Type, mod: *Module) AlignAs {295 pub fn abiAlign(ty: Type, mod: *Module) AlignAs {
...@@ -308,8 +308,14 @@ pub const CType = extern union {...@@ -308,8 +308,14 @@ pub const CType = extern union {
308 return init(union_payload_align, union_payload_align);308 return init(union_payload_align, union_payload_align);
309 }309 }
310310
311 pub fn getAlign(self: AlignAs) u32 {311 pub fn order(lhs: AlignAs, rhs: AlignAs) std.math.Order {
312 return @as(u32, 1) << self.@"align";312 return lhs.@"align".order(rhs.@"align");
313 }
314 pub fn abiOrder(self: AlignAs) std.math.Order {
315 return self.@"align".order(self.abi);
316 }
317 pub fn toByteUnits(self: AlignAs) u64 {
318 return self.@"align".toByteUnitsOptional().?;
313 }319 }
314 };320 };
315321
...@@ -1298,7 +1304,7 @@ pub const CType = extern union {...@@ -1298,7 +1304,7 @@ pub const CType = extern union {
1298 const slice = self.storage.anon.fields[0..fields_len];1304 const slice = self.storage.anon.fields[0..fields_len];
1299 mem.sort(Field, slice, {}, struct {1305 mem.sort(Field, slice, {}, struct {
1300 fn before(_: void, lhs: Field, rhs: Field) bool {1306 fn before(_: void, lhs: Field, rhs: Field) bool {
1301 return lhs.alignas.@"align" > rhs.alignas.@"align";1307 return lhs.alignas.order(rhs.alignas).compare(.gt);
1302 }1308 }
1303 }.before);1309 }.before);
1304 return slice;1310 return slice;
...@@ -1424,7 +1430,7 @@ pub const CType = extern union {...@@ -1424,7 +1430,7 @@ pub const CType = extern union {
14241430
1425 .Pointer => {1431 .Pointer => {
1426 const info = ty.ptrInfo(mod);1432 const info = ty.ptrInfo(mod);
1427 switch (info.size) {1433 switch (info.flags.size) {
1428 .Slice => {1434 .Slice => {
1429 if (switch (kind) {1435 if (switch (kind) {
1430 .forward, .forward_parameter => @as(Index, undefined),1436 .forward, .forward_parameter => @as(Index, undefined),
...@@ -1454,27 +1460,24 @@ pub const CType = extern union {...@@ -1454,27 +1460,24 @@ pub const CType = extern union {
1454 },1460 },
14551461
1456 .One, .Many, .C => {1462 .One, .Many, .C => {
1457 const t: Tag = switch (info.@"volatile") {1463 const t: Tag = switch (info.flags.is_volatile) {
1458 false => switch (info.mutable) {1464 false => switch (info.flags.is_const) {
1459 true => .pointer,1465 false => .pointer,
1460 false => .pointer_const,1466 true => .pointer_const,
1461 },1467 },
1462 true => switch (info.mutable) {1468 true => switch (info.flags.is_const) {
1463 true => .pointer_volatile,1469 false => .pointer_volatile,
1464 false => .pointer_const_volatile,1470 true => .pointer_const_volatile,
1465 },1471 },
1466 };1472 };
14671473
1468 const pointee_ty = if (info.host_size > 0 and info.vector_index == .none)1474 const pointee_ty = if (info.packed_offset.host_size > 0 and
1469 try mod.intType(.unsigned, info.host_size * 8)1475 info.flags.vector_index == .none)
1476 try mod.intType(.unsigned, info.packed_offset.host_size * 8)
1470 else1477 else
1471 info.pointee_type;1478 info.child.toType();
14721479
1473 if (if (info.size == .C and pointee_ty.ip_index == .u8_type)1480 if (try lookup.typeToIndex(pointee_ty, .forward)) |child_idx| {
1474 Tag.char.toIndex()
1475 else
1476 try lookup.typeToIndex(pointee_ty, .forward)) |child_idx|
1477 {
1478 self.storage = .{ .child = .{1481 self.storage = .{ .child = .{
1479 .base = .{ .tag = t },1482 .base = .{ .tag = t },
1480 .data = child_idx,1483 .data = child_idx,
...@@ -1586,7 +1589,7 @@ pub const CType = extern union {...@@ -1586,7 +1589,7 @@ pub const CType = extern union {
1586 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;1589 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
15871590
1588 const field_align = AlignAs.fieldAlign(ty, field_i, mod);1591 const field_align = AlignAs.fieldAlign(ty, field_i, mod);
1589 if (field_align.@"align" < field_align.abi) {1592 if (field_align.abiOrder().compare(.lt)) {
1590 is_packed = true;1593 is_packed = true;
1591 if (!lookup.isMutable()) break;1594 if (!lookup.isMutable()) break;
1592 }1595 }
src/codegen/llvm.zig+74-74
...@@ -885,7 +885,7 @@ pub const Object = struct {...@@ -885,7 +885,7 @@ pub const Object = struct {
885 const llvm_func = try dg.resolveLlvmFunction(decl_index);885 const llvm_func = try dg.resolveLlvmFunction(decl_index);
886886
887 if (mod.align_stack_fns.get(func_index)) |align_info| {887 if (mod.align_stack_fns.get(func_index)) |align_info| {
888 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment);888 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment.toByteUnitsOptional().?);
889 dg.addFnAttr(llvm_func, "noinline");889 dg.addFnAttr(llvm_func, "noinline");
890 } else {890 } else {
891 DeclGen.removeFnAttr(llvm_func, "alignstack");891 DeclGen.removeFnAttr(llvm_func, "alignstack");
...@@ -1063,15 +1063,12 @@ pub const Object = struct {...@@ -1063,15 +1063,12 @@ pub const Object = struct {
1063 if (param_ty.zigTypeTag(mod) != .Optional) {1063 if (param_ty.zigTypeTag(mod) != .Optional) {
1064 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");1064 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
1065 }1065 }
1066 if (!ptr_info.mutable) {1066 if (ptr_info.flags.is_const) {
1067 dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");1067 dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");
1068 }1068 }
1069 if (ptr_info.@"align" != 0) {1069 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
1070 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");1070 @max(ptr_info.child.toType().abiAlignment(mod), 1);
1071 } else {1071 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
1072 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
1073 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
1074 }
1075 const ptr_param = llvm_func.getParam(llvm_arg_i);1072 const ptr_param = llvm_func.getParam(llvm_arg_i);
1076 llvm_arg_i += 1;1073 llvm_arg_i += 1;
1077 const len_param = llvm_func.getParam(llvm_arg_i);1074 const len_param = llvm_func.getParam(llvm_arg_i);
...@@ -1474,7 +1471,7 @@ pub const Object = struct {...@@ -1474,7 +1471,7 @@ pub const Object = struct {
1474 .Int => {1471 .Int => {
1475 const info = ty.intInfo(mod);1472 const info = ty.intInfo(mod);
1476 assert(info.bits != 0);1473 assert(info.bits != 0);
1477 const name = try ty.nameAlloc(gpa, o.module);1474 const name = try o.allocTypeName(ty);
1478 defer gpa.free(name);1475 defer gpa.free(name);
1479 const dwarf_encoding: c_uint = switch (info.signedness) {1476 const dwarf_encoding: c_uint = switch (info.signedness) {
1480 .signed => DW.ATE.signed,1477 .signed => DW.ATE.signed,
...@@ -1536,7 +1533,7 @@ pub const Object = struct {...@@ -1536,7 +1533,7 @@ pub const Object = struct {
1536 const di_file = try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope);1533 const di_file = try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope);
1537 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);1534 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
15381535
1539 const name = try ty.nameAlloc(gpa, o.module);1536 const name = try o.allocTypeName(ty);
1540 defer gpa.free(name);1537 defer gpa.free(name);
15411538
1542 const enum_di_ty = dib.createEnumerationType(1539 const enum_di_ty = dib.createEnumerationType(
...@@ -1557,7 +1554,7 @@ pub const Object = struct {...@@ -1557,7 +1554,7 @@ pub const Object = struct {
1557 },1554 },
1558 .Float => {1555 .Float => {
1559 const bits = ty.floatBits(target);1556 const bits = ty.floatBits(target);
1560 const name = try ty.nameAlloc(gpa, o.module);1557 const name = try o.allocTypeName(ty);
1561 defer gpa.free(name);1558 defer gpa.free(name);
1562 const di_type = dib.createBasicType(name, bits, DW.ATE.float);1559 const di_type = dib.createBasicType(name, bits, DW.ATE.float);
1563 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);1560 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
...@@ -1571,7 +1568,7 @@ pub const Object = struct {...@@ -1571,7 +1568,7 @@ pub const Object = struct {
1571 },1568 },
1572 .Pointer => {1569 .Pointer => {
1573 // Normalize everything that the debug info does not represent.1570 // Normalize everything that the debug info does not represent.
1574 const ptr_info = Type.ptrInfoIp(&mod.intern_pool, ty.toIntern());1571 const ptr_info = ty.ptrInfo(mod);
15751572
1576 if (ptr_info.sentinel != .none or1573 if (ptr_info.sentinel != .none or
1577 ptr_info.flags.address_space != .generic or1574 ptr_info.flags.address_space != .generic or
...@@ -1607,7 +1604,7 @@ pub const Object = struct {...@@ -1607,7 +1604,7 @@ pub const Object = struct {
1607 const ptr_ty = ty.slicePtrFieldType(mod);1604 const ptr_ty = ty.slicePtrFieldType(mod);
1608 const len_ty = Type.usize;1605 const len_ty = Type.usize;
16091606
1610 const name = try ty.nameAlloc(gpa, o.module);1607 const name = try o.allocTypeName(ty);
1611 defer gpa.free(name);1608 defer gpa.free(name);
1612 const di_file: ?*llvm.DIFile = null;1609 const di_file: ?*llvm.DIFile = null;
1613 const line = 0;1610 const line = 0;
...@@ -1683,7 +1680,7 @@ pub const Object = struct {...@@ -1683,7 +1680,7 @@ pub const Object = struct {
1683 }1680 }
16841681
1685 const elem_di_ty = try o.lowerDebugType(ptr_info.child.toType(), .fwd);1682 const elem_di_ty = try o.lowerDebugType(ptr_info.child.toType(), .fwd);
1686 const name = try ty.nameAlloc(gpa, o.module);1683 const name = try o.allocTypeName(ty);
1687 defer gpa.free(name);1684 defer gpa.free(name);
1688 const ptr_di_ty = dib.createPointerType(1685 const ptr_di_ty = dib.createPointerType(
1689 elem_di_ty,1686 elem_di_ty,
...@@ -1701,7 +1698,7 @@ pub const Object = struct {...@@ -1701,7 +1698,7 @@ pub const Object = struct {
1701 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);1698 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1702 return di_ty;1699 return di_ty;
1703 }1700 }
1704 const name = try ty.nameAlloc(gpa, o.module);1701 const name = try o.allocTypeName(ty);
1705 defer gpa.free(name);1702 defer gpa.free(name);
1706 const owner_decl_index = ty.getOwnerDecl(mod);1703 const owner_decl_index = ty.getOwnerDecl(mod);
1707 const owner_decl = o.module.declPtr(owner_decl_index);1704 const owner_decl = o.module.declPtr(owner_decl_index);
...@@ -1738,7 +1735,7 @@ pub const Object = struct {...@@ -1738,7 +1735,7 @@ pub const Object = struct {
1738 .Int => blk: {1735 .Int => blk: {
1739 const info = elem_ty.intInfo(mod);1736 const info = elem_ty.intInfo(mod);
1740 assert(info.bits != 0);1737 assert(info.bits != 0);
1741 const name = try ty.nameAlloc(gpa, o.module);1738 const name = try o.allocTypeName(ty);
1742 defer gpa.free(name);1739 defer gpa.free(name);
1743 const dwarf_encoding: c_uint = switch (info.signedness) {1740 const dwarf_encoding: c_uint = switch (info.signedness) {
1744 .signed => DW.ATE.signed,1741 .signed => DW.ATE.signed,
...@@ -1761,7 +1758,7 @@ pub const Object = struct {...@@ -1761,7 +1758,7 @@ pub const Object = struct {
1761 return vector_di_ty;1758 return vector_di_ty;
1762 },1759 },
1763 .Optional => {1760 .Optional => {
1764 const name = try ty.nameAlloc(gpa, o.module);1761 const name = try o.allocTypeName(ty);
1765 defer gpa.free(name);1762 defer gpa.free(name);
1766 const child_ty = ty.optionalChild(mod);1763 const child_ty = ty.optionalChild(mod);
1767 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {1764 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -1857,7 +1854,7 @@ pub const Object = struct {...@@ -1857,7 +1854,7 @@ pub const Object = struct {
1857 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(err_set_di_ty));1854 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(err_set_di_ty));
1858 return err_set_di_ty;1855 return err_set_di_ty;
1859 }1856 }
1860 const name = try ty.nameAlloc(gpa, o.module);1857 const name = try o.allocTypeName(ty);
1861 defer gpa.free(name);1858 defer gpa.free(name);
1862 const di_file: ?*llvm.DIFile = null;1859 const di_file: ?*llvm.DIFile = null;
1863 const line = 0;1860 const line = 0;
...@@ -1949,7 +1946,7 @@ pub const Object = struct {...@@ -1949,7 +1946,7 @@ pub const Object = struct {
1949 },1946 },
1950 .Struct => {1947 .Struct => {
1951 const compile_unit_scope = o.di_compile_unit.?.toScope();1948 const compile_unit_scope = o.di_compile_unit.?.toScope();
1952 const name = try ty.nameAlloc(gpa, o.module);1949 const name = try o.allocTypeName(ty);
1953 defer gpa.free(name);1950 defer gpa.free(name);
19541951
1955 if (mod.typeToStruct(ty)) |struct_obj| {1952 if (mod.typeToStruct(ty)) |struct_obj| {
...@@ -2128,7 +2125,7 @@ pub const Object = struct {...@@ -2128,7 +2125,7 @@ pub const Object = struct {
2128 const compile_unit_scope = o.di_compile_unit.?.toScope();2125 const compile_unit_scope = o.di_compile_unit.?.toScope();
2129 const owner_decl_index = ty.getOwnerDecl(mod);2126 const owner_decl_index = ty.getOwnerDecl(mod);
21302127
2131 const name = try ty.nameAlloc(gpa, o.module);2128 const name = try o.allocTypeName(ty);
2132 defer gpa.free(name);2129 defer gpa.free(name);
21332130
2134 const fwd_decl = opt_fwd_decl orelse blk: {2131 const fwd_decl = opt_fwd_decl orelse blk: {
...@@ -2417,6 +2414,13 @@ pub const Object = struct {...@@ -2417,6 +2414,13 @@ pub const Object = struct {
2417 assert(stack_trace_decl.has_tv);2414 assert(stack_trace_decl.has_tv);
2418 return stack_trace_decl.val.toType();2415 return stack_trace_decl.val.toType();
2419 }2416 }
2417
2418 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {
2419 var buffer = std.ArrayList(u8).init(o.gpa);
2420 errdefer buffer.deinit();
2421 try ty.print(buffer.writer(), o.module);
2422 return buffer.toOwnedSliceSentinel(0);
2423 }
2420};2424};
24212425
2422pub const DeclGen = struct {2426pub const DeclGen = struct {
...@@ -2792,7 +2796,7 @@ pub const DeclGen = struct {...@@ -2792,7 +2796,7 @@ pub const DeclGen = struct {
2792 return dg.context.structType(&fields, fields.len, .False);2796 return dg.context.structType(&fields, fields.len, .False);
2793 }2797 }
2794 const ptr_info = t.ptrInfo(mod);2798 const ptr_info = t.ptrInfo(mod);
2795 const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target);2799 const llvm_addrspace = toLlvmAddressSpace(ptr_info.flags.address_space, target);
2796 return dg.context.pointerType(llvm_addrspace);2800 return dg.context.pointerType(llvm_addrspace);
2797 },2801 },
2798 .Opaque => {2802 .Opaque => {
...@@ -3392,7 +3396,7 @@ pub const DeclGen = struct {...@@ -3392,7 +3396,7 @@ pub const DeclGen = struct {
3392 .opt_payload,3396 .opt_payload,
3393 .elem,3397 .elem,
3394 .field,3398 .field,
3395 => try dg.lowerParentPtr(ptr_tv.val, ptr_tv.ty.ptrInfo(mod).bit_offset % 8 == 0),3399 => try dg.lowerParentPtr(ptr_tv.val, ptr_tv.ty.ptrInfo(mod).packed_offset.bit_offset % 8 == 0),
3396 .comptime_field => unreachable,3400 .comptime_field => unreachable,
3397 };3401 };
3398 switch (ptr.len) {3402 switch (ptr.len) {
...@@ -4034,7 +4038,6 @@ pub const DeclGen = struct {...@@ -4034,7 +4038,6 @@ pub const DeclGen = struct {
40344038
4035 fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value {4039 fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value {
4036 const mod = dg.module;4040 const mod = dg.module;
4037 const alignment = ptr_ty.ptrInfo(mod).@"align";
4038 // Even though we are pointing at something which has zero bits (e.g. `void`),4041 // Even though we are pointing at something which has zero bits (e.g. `void`),
4039 // Pointers are defined to have bits. So we must return something here.4042 // Pointers are defined to have bits. So we must return something here.
4040 // The value cannot be undefined, because we use the `nonnull` annotation4043 // The value cannot be undefined, because we use the `nonnull` annotation
...@@ -4042,7 +4045,7 @@ pub const DeclGen = struct {...@@ -4042,7 +4045,7 @@ pub const DeclGen = struct {
4042 // the address will never be dereferenced.4045 // the address will never be dereferenced.
4043 const llvm_usize = try dg.lowerType(Type.usize);4046 const llvm_usize = try dg.lowerType(Type.usize);
4044 const llvm_ptr_ty = try dg.lowerType(ptr_ty);4047 const llvm_ptr_ty = try dg.lowerType(ptr_ty);
4045 if (alignment != 0) {4048 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {
4046 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);4049 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);
4047 }4050 }
4048 // Note that these 0xaa values are appropriate even in release-optimized builds4051 // Note that these 0xaa values are appropriate even in release-optimized builds
...@@ -4163,18 +4166,15 @@ pub const DeclGen = struct {...@@ -4163,18 +4166,15 @@ pub const DeclGen = struct {
4163 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");4166 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
4164 }4167 }
4165 }4168 }
4166 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.@"allowzero") {4169 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.flags.is_allowzero) {
4167 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");4170 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4168 }4171 }
4169 if (!ptr_info.mutable) {4172 if (ptr_info.flags.is_const) {
4170 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");4173 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4171 }4174 }
4172 if (ptr_info.@"align" != 0) {4175 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
4173 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", ptr_info.@"align");4176 @max(ptr_info.child.toType().abiAlignment(mod), 1);
4174 } else {4177 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
4175 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
4176 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
4177 }
4178 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {4178 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
4179 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),4179 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
4180 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),4180 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
...@@ -4806,15 +4806,12 @@ pub const FuncGen = struct {...@@ -4806,15 +4806,12 @@ pub const FuncGen = struct {
4806 if (param_ty.zigTypeTag(mod) != .Optional) {4806 if (param_ty.zigTypeTag(mod) != .Optional) {
4807 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");4807 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");
4808 }4808 }
4809 if (!ptr_info.mutable) {4809 if (ptr_info.flags.is_const) {
4810 self.dg.addArgAttr(call, llvm_arg_i, "readonly");4810 self.dg.addArgAttr(call, llvm_arg_i, "readonly");
4811 }4811 }
4812 if (ptr_info.@"align" != 0) {4812 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
4813 self.dg.addArgAttrInt(call, llvm_arg_i, "align", ptr_info.@"align");4813 @max(ptr_info.child.toType().abiAlignment(mod), 1);
4814 } else {4814 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
4815 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
4816 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
4817 }
4818 },4815 },
4819 };4816 };
4820 }4817 }
...@@ -5737,7 +5734,7 @@ pub const FuncGen = struct {...@@ -5737,7 +5734,7 @@ pub const FuncGen = struct {
5737 const rhs = try self.resolveInst(bin_op.rhs);5734 const rhs = try self.resolveInst(bin_op.rhs);
57385735
5739 const elem_ptr = self.air.getRefType(ty_pl.ty);5736 const elem_ptr = self.air.getRefType(ty_pl.ty);
5740 if (elem_ptr.ptrInfo(mod).vector_index != .none) return base_ptr;5737 if (elem_ptr.ptrInfo(mod).flags.vector_index != .none) return base_ptr;
57415738
5742 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);5739 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5743 if (ptr_ty.isSinglePointer(mod)) {5740 if (ptr_ty.isSinglePointer(mod)) {
...@@ -8062,7 +8059,7 @@ pub const FuncGen = struct {...@@ -8062,7 +8059,7 @@ pub const FuncGen = struct {
8062 const ptr = try fg.resolveInst(ty_op.operand);8059 const ptr = try fg.resolveInst(ty_op.operand);
80638060
8064 elide: {8061 elide: {
8065 if (!isByRef(ptr_info.pointee_type, mod)) break :elide;8062 if (!isByRef(ptr_info.child.toType(), mod)) break :elide;
8066 if (!canElideLoad(fg, body_tail)) break :elide;8063 if (!canElideLoad(fg, body_tail)) break :elide;
8067 return ptr;8064 return ptr;
8068 }8065 }
...@@ -8235,13 +8232,14 @@ pub const FuncGen = struct {...@@ -8235,13 +8232,14 @@ pub const FuncGen = struct {
8235 const ptr = try self.resolveInst(atomic_load.ptr);8232 const ptr = try self.resolveInst(atomic_load.ptr);
8236 const ptr_ty = self.typeOf(atomic_load.ptr);8233 const ptr_ty = self.typeOf(atomic_load.ptr);
8237 const ptr_info = ptr_ty.ptrInfo(mod);8234 const ptr_info = ptr_ty.ptrInfo(mod);
8238 const elem_ty = ptr_info.pointee_type;8235 const elem_ty = ptr_info.child.toType();
8239 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))8236 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
8240 return null;8237 return null;
8241 const ordering = toLlvmAtomicOrdering(atomic_load.order);8238 const ordering = toLlvmAtomicOrdering(atomic_load.order);
8242 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);8239 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);
8243 const ptr_alignment = ptr_info.alignment(mod);8240 const ptr_alignment = @intCast(u32, ptr_info.flags.alignment.toByteUnitsOptional() orelse
8244 const ptr_volatile = llvm.Bool.fromBool(ptr_info.@"volatile");8241 ptr_info.child.toType().abiAlignment(mod));
8242 const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile);
8245 const elem_llvm_ty = try self.dg.lowerType(elem_ty);8243 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
82468244
8247 if (opt_abi_llvm_ty) |abi_llvm_ty| {8245 if (opt_abi_llvm_ty) |abi_llvm_ty| {
...@@ -9567,7 +9565,7 @@ pub const FuncGen = struct {...@@ -9567,7 +9565,7 @@ pub const FuncGen = struct {
9567 const result_ty = self.typeOfIndex(inst);9565 const result_ty = self.typeOfIndex(inst);
9568 const result_ty_info = result_ty.ptrInfo(mod);9566 const result_ty_info = result_ty.ptrInfo(mod);
95699567
9570 if (result_ty_info.host_size != 0) {9568 if (result_ty_info.packed_offset.host_size != 0) {
9571 // From LLVM's perspective, a pointer to a packed struct and a pointer9569 // From LLVM's perspective, a pointer to a packed struct and a pointer
9572 // to a field of a packed struct are the same. The difference is in the9570 // to a field of a packed struct are the same. The difference is in the
9573 // Zig pointer type which provides information for how to mask and shift9571 // Zig pointer type which provides information for how to mask and shift
...@@ -9651,16 +9649,18 @@ pub const FuncGen = struct {...@@ -9651,16 +9649,18 @@ pub const FuncGen = struct {
9651 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {9649 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {
9652 const mod = self.dg.module;9650 const mod = self.dg.module;
9653 const info = ptr_ty.ptrInfo(mod);9651 const info = ptr_ty.ptrInfo(mod);
9654 if (!info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) return null;9652 const elem_ty = info.child.toType();
9653 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
96559654
9656 const ptr_alignment = info.alignment(mod);9655 const ptr_alignment = @intCast(u32, info.flags.alignment.toByteUnitsOptional() orelse
9657 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr(mod));9656 elem_ty.abiAlignment(mod));
9657 const ptr_volatile = llvm.Bool.fromBool(info.flags.is_volatile);
96589658
9659 assert(info.vector_index != .runtime);9659 assert(info.flags.vector_index != .runtime);
9660 if (info.vector_index != .none) {9660 if (info.flags.vector_index != .none) {
9661 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.vector_index), .False);9661 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
9662 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);9662 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9663 const vec_ty = vec_elem_ty.vectorType(info.host_size);9663 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
96649664
9665 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");9665 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
9666 loaded_vector.setAlignment(ptr_alignment);9666 loaded_vector.setAlignment(ptr_alignment);
...@@ -9669,29 +9669,29 @@ pub const FuncGen = struct {...@@ -9669,29 +9669,29 @@ pub const FuncGen = struct {
9669 return self.builder.buildExtractElement(loaded_vector, index_u32, "");9669 return self.builder.buildExtractElement(loaded_vector, index_u32, "");
9670 }9670 }
96719671
9672 if (info.host_size == 0) {9672 if (info.packed_offset.host_size == 0) {
9673 if (isByRef(info.pointee_type, mod)) {9673 if (isByRef(elem_ty, mod)) {
9674 return self.loadByRef(ptr, info.pointee_type, ptr_alignment, info.@"volatile");9674 return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile);
9675 }9675 }
9676 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);9676 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
9677 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");9677 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
9678 llvm_inst.setAlignment(ptr_alignment);9678 llvm_inst.setAlignment(ptr_alignment);
9679 llvm_inst.setVolatile(ptr_volatile);9679 llvm_inst.setVolatile(ptr_volatile);
9680 return llvm_inst;9680 return llvm_inst;
9681 }9681 }
96829682
9683 const int_elem_ty = self.context.intType(info.host_size * 8);9683 const int_elem_ty = self.context.intType(info.packed_offset.host_size * 8);
9684 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");9684 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
9685 containing_int.setAlignment(ptr_alignment);9685 containing_int.setAlignment(ptr_alignment);
9686 containing_int.setVolatile(ptr_volatile);9686 containing_int.setVolatile(ptr_volatile);
96879687
9688 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));9688 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));
9689 const shift_amt = containing_int.typeOf().constInt(info.bit_offset, .False);9689 const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False);
9690 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");9690 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
9691 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);9691 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
96929692
9693 if (isByRef(info.pointee_type, mod)) {9693 if (isByRef(elem_ty, mod)) {
9694 const result_align = info.pointee_type.abiAlignment(mod);9694 const result_align = elem_ty.abiAlignment(mod);
9695 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);9695 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);
96969696
9697 const same_size_int = self.context.intType(elem_bits);9697 const same_size_int = self.context.intType(elem_bits);
...@@ -9701,13 +9701,13 @@ pub const FuncGen = struct {...@@ -9701,13 +9701,13 @@ pub const FuncGen = struct {
9701 return result_ptr;9701 return result_ptr;
9702 }9702 }
97039703
9704 if (info.pointee_type.zigTypeTag(mod) == .Float or info.pointee_type.zigTypeTag(mod) == .Vector) {9704 if (elem_ty.zigTypeTag(mod) == .Float or elem_ty.zigTypeTag(mod) == .Vector) {
9705 const same_size_int = self.context.intType(elem_bits);9705 const same_size_int = self.context.intType(elem_bits);
9706 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");9706 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
9707 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");9707 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
9708 }9708 }
97099709
9710 if (info.pointee_type.isPtrAtRuntime(mod)) {9710 if (elem_ty.isPtrAtRuntime(mod)) {
9711 const same_size_int = self.context.intType(elem_bits);9711 const same_size_int = self.context.intType(elem_bits);
9712 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");9712 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
9713 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");9713 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
...@@ -9725,18 +9725,18 @@ pub const FuncGen = struct {...@@ -9725,18 +9725,18 @@ pub const FuncGen = struct {
9725 ) !void {9725 ) !void {
9726 const mod = self.dg.module;9726 const mod = self.dg.module;
9727 const info = ptr_ty.ptrInfo(mod);9727 const info = ptr_ty.ptrInfo(mod);
9728 const elem_ty = info.pointee_type;9728 const elem_ty = info.child.toType();
9729 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {9729 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
9730 return;9730 return;
9731 }9731 }
9732 const ptr_alignment = ptr_ty.ptrAlignment(mod);9732 const ptr_alignment = ptr_ty.ptrAlignment(mod);
9733 const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");9733 const ptr_volatile = llvm.Bool.fromBool(info.flags.is_volatile);
97349734
9735 assert(info.vector_index != .runtime);9735 assert(info.flags.vector_index != .runtime);
9736 if (info.vector_index != .none) {9736 if (info.flags.vector_index != .none) {
9737 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.vector_index), .False);9737 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
9738 const vec_elem_ty = try self.dg.lowerType(elem_ty);9738 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9739 const vec_ty = vec_elem_ty.vectorType(info.host_size);9739 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
97409740
9741 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");9741 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
9742 loaded_vector.setAlignment(ptr_alignment);9742 loaded_vector.setAlignment(ptr_alignment);
...@@ -9751,15 +9751,15 @@ pub const FuncGen = struct {...@@ -9751,15 +9751,15 @@ pub const FuncGen = struct {
9751 return;9751 return;
9752 }9752 }
97539753
9754 if (info.host_size != 0) {9754 if (info.packed_offset.host_size != 0) {
9755 const int_elem_ty = self.context.intType(info.host_size * 8);9755 const int_elem_ty = self.context.intType(info.packed_offset.host_size * 8);
9756 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");9756 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
9757 assert(ordering == .NotAtomic);9757 assert(ordering == .NotAtomic);
9758 containing_int.setAlignment(ptr_alignment);9758 containing_int.setAlignment(ptr_alignment);
9759 containing_int.setVolatile(ptr_volatile);9759 containing_int.setVolatile(ptr_volatile);
9760 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));9760 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));
9761 const containing_int_ty = containing_int.typeOf();9761 const containing_int_ty = containing_int.typeOf();
9762 const shift_amt = containing_int_ty.constInt(info.bit_offset, .False);9762 const shift_amt = containing_int_ty.constInt(info.packed_offset.bit_offset, .False);
9763 // Convert to equally-sized integer type in order to perform the bit9763 // Convert to equally-sized integer type in order to perform the bit
9764 // operations on the value to store9764 // operations on the value to store
9765 const value_bits_type = self.context.intType(elem_bits);9765 const value_bits_type = self.context.intType(elem_bits);
...@@ -9799,7 +9799,7 @@ pub const FuncGen = struct {...@@ -9799,7 +9799,7 @@ pub const FuncGen = struct {
9799 elem,9799 elem,
9800 elem_ty.abiAlignment(mod),9800 elem_ty.abiAlignment(mod),
9801 self.context.intType(Type.usize.intInfo(mod).bits).constInt(size_bytes, .False),9801 self.context.intType(Type.usize.intInfo(mod).bits).constInt(size_bytes, .False),
9802 info.@"volatile",9802 info.flags.is_volatile,
9803 );9803 );
9804 }9804 }
98059805
src/codegen/spirv.zig+4-4
...@@ -1210,13 +1210,13 @@ pub const DeclGen = struct {...@@ -1210,13 +1210,13 @@ pub const DeclGen = struct {
1210 .Pointer => {1210 .Pointer => {
1211 const ptr_info = ty.ptrInfo(mod);1211 const ptr_info = ty.ptrInfo(mod);
12121212
1213 const storage_class = spvStorageClass(ptr_info.@"addrspace");1213 const storage_class = spvStorageClass(ptr_info.flags.address_space);
1214 const child_ty_ref = try self.resolveType(ptr_info.pointee_type, .indirect);1214 const child_ty_ref = try self.resolveType(ptr_info.child.toType(), .indirect);
1215 const ptr_ty_ref = try self.spv.resolve(.{ .ptr_type = .{1215 const ptr_ty_ref = try self.spv.resolve(.{ .ptr_type = .{
1216 .storage_class = storage_class,1216 .storage_class = storage_class,
1217 .child_type = child_ty_ref,1217 .child_type = child_ty_ref,
1218 } });1218 } });
1219 if (ptr_info.size != .Slice) {1219 if (ptr_info.flags.size != .Slice) {
1220 return ptr_ty_ref;1220 return ptr_ty_ref;
1221 }1221 }
12221222
...@@ -1573,7 +1573,7 @@ pub const DeclGen = struct {...@@ -1573,7 +1573,7 @@ pub const DeclGen = struct {
1573 init_val,1573 init_val,
1574 actual_storage_class,1574 actual_storage_class,
1575 final_storage_class == .Generic,1575 final_storage_class == .Generic,
1576 decl.@"align",1576 @intCast(u32, decl.alignment.toByteUnits(0)),
1577 );1577 );
1578 }1578 }
1579 }1579 }
src/link/Dwarf.zig+15-31
...@@ -163,7 +163,6 @@ pub const DeclState = struct {...@@ -163,7 +163,6 @@ pub const DeclState = struct {
163 atom_index: Atom.Index,163 atom_index: Atom.Index,
164 ty: Type,164 ty: Type,
165 ) error{OutOfMemory}!void {165 ) error{OutOfMemory}!void {
166 const arena = self.abbrev_type_arena.allocator();
167 const dbg_info_buffer = &self.dbg_info;166 const dbg_info_buffer = &self.dbg_info;
168 const target = mod.getTarget();167 const target = mod.getTarget();
169 const target_endian = target.cpu.arch.endian();168 const target_endian = target.cpu.arch.endian();
...@@ -344,10 +343,8 @@ pub const DeclState = struct {...@@ -344,10 +343,8 @@ pub const DeclState = struct {
344 .struct_type => |struct_type| s: {343 .struct_type => |struct_type| s: {
345 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse break :s;344 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse break :s;
346 // DW.AT.name, DW.FORM.string345 // DW.AT.name, DW.FORM.string
347 const struct_name = try ty.nameAllocArena(arena, mod);346 try ty.print(dbg_info_buffer.writer(), mod);
348 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);347 try dbg_info_buffer.append(0);
349 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
350 dbg_info_buffer.appendAssumeCapacity(0);
351348
352 if (struct_obj.layout == .Packed) {349 if (struct_obj.layout == .Packed) {
353 log.debug("TODO implement .debug_info for packed structs", .{});350 log.debug("TODO implement .debug_info for packed structs", .{});
...@@ -388,10 +385,8 @@ pub const DeclState = struct {...@@ -388,10 +385,8 @@ pub const DeclState = struct {
388 // DW.AT.byte_size, DW.FORM.udata385 // DW.AT.byte_size, DW.FORM.udata
389 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));386 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
390 // DW.AT.name, DW.FORM.string387 // DW.AT.name, DW.FORM.string
391 const enum_name = try ty.nameAllocArena(arena, mod);388 try ty.print(dbg_info_buffer.writer(), mod);
392 try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);389 try dbg_info_buffer.append(0);
393 dbg_info_buffer.appendSliceAssumeCapacity(enum_name);
394 dbg_info_buffer.appendAssumeCapacity(0);
395390
396 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;391 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
397 for (enum_type.names, 0..) |field_name_index, field_i| {392 for (enum_type.names, 0..) |field_name_index, field_i| {
...@@ -422,21 +417,18 @@ pub const DeclState = struct {...@@ -422,21 +417,18 @@ pub const DeclState = struct {
422 const union_obj = mod.typeToUnion(ty).?;417 const union_obj = mod.typeToUnion(ty).?;
423 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;418 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;
424 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;419 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;
425 const is_tagged = layout.tag_size > 0;
426 const union_name = try ty.nameAllocArena(arena, mod);
427
428 // TODO this is temporary to match current state of unions in Zig - we don't yet have420 // TODO this is temporary to match current state of unions in Zig - we don't yet have
429 // safety checks implemented meaning the implicit tag is not yet stored and generated421 // safety checks implemented meaning the implicit tag is not yet stored and generated
430 // for untagged unions.422 // for untagged unions.
423 const is_tagged = layout.tag_size > 0;
431 if (is_tagged) {424 if (is_tagged) {
432 // DW.AT.structure_type425 // DW.AT.structure_type
433 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_type));426 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_type));
434 // DW.AT.byte_size, DW.FORM.udata427 // DW.AT.byte_size, DW.FORM.udata
435 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size);428 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size);
436 // DW.AT.name, DW.FORM.string429 // DW.AT.name, DW.FORM.string
437 try dbg_info_buffer.ensureUnusedCapacity(union_name.len + 1);430 try ty.print(dbg_info_buffer.writer(), mod);
438 dbg_info_buffer.appendSliceAssumeCapacity(union_name);431 try dbg_info_buffer.append(0);
439 dbg_info_buffer.appendAssumeCapacity(0);
440432
441 // DW.AT.member433 // DW.AT.member
442 try dbg_info_buffer.ensureUnusedCapacity(9);434 try dbg_info_buffer.ensureUnusedCapacity(9);
...@@ -460,7 +452,8 @@ pub const DeclState = struct {...@@ -460,7 +452,8 @@ pub const DeclState = struct {
460 if (is_tagged) {452 if (is_tagged) {
461 try dbg_info_buffer.writer().print("AnonUnion\x00", .{});453 try dbg_info_buffer.writer().print("AnonUnion\x00", .{});
462 } else {454 } else {
463 try dbg_info_buffer.writer().print("{s}\x00", .{union_name});455 try ty.print(dbg_info_buffer.writer(), mod);
456 try dbg_info_buffer.append(0);
464 }457 }
465458
466 const fields = ty.unionFields(mod);459 const fields = ty.unionFields(mod);
...@@ -500,15 +493,7 @@ pub const DeclState = struct {...@@ -500,15 +493,7 @@ pub const DeclState = struct {
500 try dbg_info_buffer.append(0);493 try dbg_info_buffer.append(0);
501 }494 }
502 },495 },
503 .ErrorSet => {496 .ErrorSet => try addDbgInfoErrorSet(mod, ty, target, &self.dbg_info),
504 try addDbgInfoErrorSet(
505 self.abbrev_type_arena.allocator(),
506 mod,
507 ty,
508 target,
509 &self.dbg_info,
510 );
511 },
512 .ErrorUnion => {497 .ErrorUnion => {
513 const error_ty = ty.errorUnionSet(mod);498 const error_ty = ty.errorUnionSet(mod);
514 const payload_ty = ty.errorUnionPayload(mod);499 const payload_ty = ty.errorUnionPayload(mod);
...@@ -523,8 +508,8 @@ pub const DeclState = struct {...@@ -523,8 +508,8 @@ pub const DeclState = struct {
523 // DW.AT.byte_size, DW.FORM.udata508 // DW.AT.byte_size, DW.FORM.udata
524 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);509 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
525 // DW.AT.name, DW.FORM.string510 // DW.AT.name, DW.FORM.string
526 const name = try ty.nameAllocArena(arena, mod);511 try ty.print(dbg_info_buffer.writer(), mod);
527 try dbg_info_buffer.writer().print("{s}\x00", .{name});512 try dbg_info_buffer.append(0);
528513
529 if (!payload_ty.isNoReturn(mod)) {514 if (!payload_ty.isNoReturn(mod)) {
530 // DW.AT.member515 // DW.AT.member
...@@ -2527,7 +2512,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {...@@ -2527,7 +2512,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
25272512
2528 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });2513 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });
2529 var dbg_info_buffer = std.ArrayList(u8).init(arena);2514 var dbg_info_buffer = std.ArrayList(u8).init(arena);
2530 try addDbgInfoErrorSet(arena, module, error_ty.toType(), self.target, &dbg_info_buffer);2515 try addDbgInfoErrorSet(module, error_ty.toType(), self.target, &dbg_info_buffer);
25312516
2532 const di_atom_index = try self.createAtom(.di_atom);2517 const di_atom_index = try self.createAtom(.di_atom);
2533 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});2518 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});
...@@ -2644,7 +2629,6 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {...@@ -2644,7 +2629,6 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {
2644}2629}
26452630
2646fn addDbgInfoErrorSet(2631fn addDbgInfoErrorSet(
2647 arena: Allocator,
2648 mod: *Module,2632 mod: *Module,
2649 ty: Type,2633 ty: Type,
2650 target: std.Target,2634 target: std.Target,
...@@ -2658,8 +2642,8 @@ fn addDbgInfoErrorSet(...@@ -2658,8 +2642,8 @@ fn addDbgInfoErrorSet(
2658 const abi_size = Type.anyerror.abiSize(mod);2642 const abi_size = Type.anyerror.abiSize(mod);
2659 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);2643 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
2660 // DW.AT.name, DW.FORM.string2644 // DW.AT.name, DW.FORM.string
2661 const name = try ty.nameAllocArena(arena, mod);2645 try ty.print(dbg_info_buffer.writer(), mod);
2662 try dbg_info_buffer.writer().print("{s}\x00", .{name});2646 try dbg_info_buffer.append(0);
26632647
2664 // DW.AT.enumerator2648 // DW.AT.enumerator
2665 const no_error = "(no error)";2649 const no_error = "(no error)";
src/type.zig+36-184
...@@ -2,7 +2,6 @@ const std = @import("std");...@@ -2,7 +2,6 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const Value = @import("value.zig").Value;3const Value = @import("value.zig").Value;
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const Allocator = std.mem.Allocator;
6const Target = std.Target;5const Target = std.Target;
7const Module = @import("Module.zig");6const Module = @import("Module.zig");
8const log = std.log.scoped(.Type);7const log = std.log.scoped(.Type);
...@@ -102,10 +101,10 @@ pub const Type = struct {...@@ -102,10 +101,10 @@ pub const Type = struct {
102 };101 };
103 }102 }
104103
105 pub fn ptrInfoIp(ip: *const InternPool, ty: InternPool.Index) InternPool.Key.PtrType {104 pub fn ptrInfo(ty: Type, mod: *const Module) InternPool.Key.PtrType {
106 return switch (ip.indexToKey(ty)) {105 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
107 .ptr_type => |p| p,106 .ptr_type => |p| p,
108 .opt_type => |child| switch (ip.indexToKey(child)) {107 .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) {
109 .ptr_type => |p| p,108 .ptr_type => |p| p,
110 else => unreachable,109 else => unreachable,
111 },110 },
...@@ -113,10 +112,6 @@ pub const Type = struct {...@@ -113,10 +112,6 @@ pub const Type = struct {
113 };112 };
114 }113 }
115114
116 pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data {
117 return Payload.Pointer.Data.fromKey(ptrInfoIp(&mod.intern_pool, ty.toIntern()));
118 }
119
120 pub fn eql(a: Type, b: Type, mod: *const Module) bool {115 pub fn eql(a: Type, b: Type, mod: *const Module) bool {
121 _ = mod; // TODO: remove this parameter116 _ = mod; // TODO: remove this parameter
122 // The InternPool data structure hashes based on Key to make interned objects117 // The InternPool data structure hashes based on Key to make interned objects
...@@ -181,15 +176,6 @@ pub const Type = struct {...@@ -181,15 +176,6 @@ pub const Type = struct {
181 return writer.print("{any}", .{start_type.ip_index});176 return writer.print("{any}", .{start_type.ip_index});
182 }177 }
183178
184 pub const nameAllocArena = nameAlloc;
185
186 pub fn nameAlloc(ty: Type, ally: Allocator, module: *Module) Allocator.Error![:0]const u8 {
187 var buffer = std.ArrayList(u8).init(ally);
188 defer buffer.deinit();
189 try ty.print(buffer.writer(), module);
190 return buffer.toOwnedSliceSentinel(0);
191 }
192
193 /// Prints a name suitable for `@typeName`.179 /// Prints a name suitable for `@typeName`.
194 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {180 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {
195 switch (mod.intern_pool.indexToKey(ty.toIntern())) {181 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
...@@ -203,42 +189,44 @@ pub const Type = struct {...@@ -203,42 +189,44 @@ pub const Type = struct {
203 .ptr_type => {189 .ptr_type => {
204 const info = ty.ptrInfo(mod);190 const info = ty.ptrInfo(mod);
205191
206 if (info.sentinel) |s| switch (info.size) {192 if (info.sentinel != .none) switch (info.flags.size) {
207 .One, .C => unreachable,193 .One, .C => unreachable,
208 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),194 .Many => try writer.print("[*:{}]", .{info.sentinel.toValue().fmtValue(info.child.toType(), mod)}),
209 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),195 .Slice => try writer.print("[:{}]", .{info.sentinel.toValue().fmtValue(info.child.toType(), mod)}),
210 } else switch (info.size) {196 } else switch (info.flags.size) {
211 .One => try writer.writeAll("*"),197 .One => try writer.writeAll("*"),
212 .Many => try writer.writeAll("[*]"),198 .Many => try writer.writeAll("[*]"),
213 .C => try writer.writeAll("[*c]"),199 .C => try writer.writeAll("[*c]"),
214 .Slice => try writer.writeAll("[]"),200 .Slice => try writer.writeAll("[]"),
215 }201 }
216 if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) {202 if (info.flags.alignment != .none or
217 if (info.@"align" != 0) {203 info.packed_offset.host_size != 0 or
218 try writer.print("align({d}", .{info.@"align"});204 info.flags.vector_index != .none)
219 } else {205 {
220 const alignment = info.pointee_type.abiAlignment(mod);206 const alignment = info.flags.alignment.toByteUnitsOptional() orelse
221 try writer.print("align({d}", .{alignment});207 info.child.toType().abiAlignment(mod);
208 try writer.print("align({d}", .{alignment});
209
210 if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) {
211 try writer.print(":{d}:{d}", .{
212 info.packed_offset.bit_offset, info.packed_offset.host_size,
213 });
222 }214 }
223215 if (info.flags.vector_index == .runtime) {
224 if (info.bit_offset != 0 or info.host_size != 0) {
225 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
226 }
227 if (info.vector_index == .runtime) {
228 try writer.writeAll(":?");216 try writer.writeAll(":?");
229 } else if (info.vector_index != .none) {217 } else if (info.flags.vector_index != .none) {
230 try writer.print(":{d}", .{@intFromEnum(info.vector_index)});218 try writer.print(":{d}", .{@intFromEnum(info.flags.vector_index)});
231 }219 }
232 try writer.writeAll(") ");220 try writer.writeAll(") ");
233 }221 }
234 if (info.@"addrspace" != .generic) {222 if (info.flags.address_space != .generic) {
235 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});223 try writer.print("addrspace(.{s}) ", .{@tagName(info.flags.address_space)});
236 }224 }
237 if (!info.mutable) try writer.writeAll("const ");225 if (info.flags.is_const) try writer.writeAll("const ");
238 if (info.@"volatile") try writer.writeAll("volatile ");226 if (info.flags.is_volatile) try writer.writeAll("volatile ");
239 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");227 if (info.flags.is_allowzero and info.flags.size != .C) try writer.writeAll("allowzero ");
240228
241 try print(info.pointee_type, writer, mod);229 try print(info.child.toType(), writer, mod);
242 return;230 return;
243 },231 },
244 .array_type => |array_type| {232 .array_type => |array_type| {
...@@ -1035,9 +1023,8 @@ pub const Type = struct {...@@ -1035,9 +1023,8 @@ pub const Type = struct {
1035 else => |e| return e,1023 else => |e| return e,
1036 })) continue;1024 })) continue;
10371025
1038 const field_align = if (field.abi_align != 0)1026 const field_align = @intCast(u32, field.abi_align.toByteUnitsOptional() orelse
1039 field.abi_align1027 switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1040 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1041 .scalar => |a| a,1028 .scalar => |a| a,
1042 .val => switch (strat) {1029 .val => switch (strat) {
1043 .eager => unreachable, // struct layout not resolved1030 .eager => unreachable, // struct layout not resolved
...@@ -1047,7 +1034,7 @@ pub const Type = struct {...@@ -1047,7 +1034,7 @@ pub const Type = struct {
1047 .storage = .{ .lazy_align = ty.toIntern() },1034 .storage = .{ .lazy_align = ty.toIntern() },
1048 } })).toValue() },1035 } })).toValue() },
1049 },1036 },
1050 };1037 });
1051 big_align = @max(big_align, field_align);1038 big_align = @max(big_align, field_align);
10521039
1053 // This logic is duplicated in Module.Struct.Field.alignment.1040 // This logic is duplicated in Module.Struct.Field.alignment.
...@@ -1242,9 +1229,8 @@ pub const Type = struct {...@@ -1242,9 +1229,8 @@ pub const Type = struct {
1242 else => |e| return e,1229 else => |e| return e,
1243 })) continue;1230 })) continue;
12441231
1245 const field_align = if (field.abi_align != 0)1232 const field_align = @intCast(u32, field.abi_align.toByteUnitsOptional() orelse
1246 field.abi_align1233 switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1247 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1248 .scalar => |a| a,1234 .scalar => |a| a,
1249 .val => switch (strat) {1235 .val => switch (strat) {
1250 .eager => unreachable, // struct layout not resolved1236 .eager => unreachable, // struct layout not resolved
...@@ -1254,7 +1240,7 @@ pub const Type = struct {...@@ -1254,7 +1240,7 @@ pub const Type = struct {
1254 .storage = .{ .lazy_align = ty.toIntern() },1240 .storage = .{ .lazy_align = ty.toIntern() },
1255 } })).toValue() },1241 } })).toValue() },
1256 },1242 },
1257 };1243 });
1258 max_align = @max(max_align, field_align);1244 max_align = @max(max_align, field_align);
1259 }1245 }
1260 return AbiAlignmentAdvanced{ .scalar = max_align };1246 return AbiAlignmentAdvanced{ .scalar = max_align };
...@@ -1883,7 +1869,7 @@ pub const Type = struct {...@@ -1883,7 +1869,7 @@ pub const Type = struct {
1883 if (ty.isPtrLikeOptional(mod)) {1869 if (ty.isPtrLikeOptional(mod)) {
1884 return true;1870 return true;
1885 }1871 }
1886 return ty.ptrInfo(mod).@"allowzero";1872 return ty.ptrInfo(mod).flags.is_allowzero;
1887 }1873 }
18881874
1889 /// See also `isPtrLikeOptional`.1875 /// See also `isPtrLikeOptional`.
...@@ -2387,15 +2373,7 @@ pub const Type = struct {...@@ -2387,15 +2373,7 @@ pub const Type = struct {
23872373
2388 /// Asserts the type is a function or a function pointer.2374 /// Asserts the type is a function or a function pointer.
2389 pub fn fnReturnType(ty: Type, mod: *Module) Type {2375 pub fn fnReturnType(ty: Type, mod: *Module) Type {
2390 return fnReturnTypeIp(ty, &mod.intern_pool);2376 return mod.intern_pool.funcReturnType(ty.toIntern()).toType();
2391 }
2392
2393 pub fn fnReturnTypeIp(ty: Type, ip: *const InternPool) Type {
2394 return switch (ip.indexToKey(ty.toIntern())) {
2395 .ptr_type => |ptr_type| ip.indexToKey(ptr_type.child).func_type.return_type,
2396 .func_type => |func_type| func_type.return_type,
2397 else => unreachable,
2398 }.toType();
2399 }2377 }
24002378
2401 /// Asserts the type is a function.2379 /// Asserts the type is a function.
...@@ -3355,58 +3333,6 @@ pub const Type = struct {...@@ -3355,58 +3333,6 @@ pub const Type = struct {
3355 };3333 };
3356 }3334 }
33573335
3358 pub const Payload = struct {
3359 /// TODO: remove this data structure since we have `InternPool.Key.PtrType`.
3360 pub const Pointer = struct {
3361 pub const Data = struct {
3362 pointee_type: Type,
3363 sentinel: ?Value = null,
3364 /// If zero use pointee_type.abiAlignment()
3365 /// When creating pointer types, if alignment is equal to pointee type
3366 /// abi alignment, this value should be set to 0 instead.
3367 @"align": u32 = 0,
3368 /// See src/target.zig defaultAddressSpace function for how to obtain
3369 /// an appropriate value for this field.
3370 @"addrspace": std.builtin.AddressSpace,
3371 bit_offset: u16 = 0,
3372 /// If this is non-zero it means the pointer points to a sub-byte
3373 /// range of data, which is backed by a "host integer" with this
3374 /// number of bytes.
3375 /// When host_size=pointee_abi_size and bit_offset=0, this must be
3376 /// represented with host_size=0 instead.
3377 host_size: u16 = 0,
3378 vector_index: VectorIndex = .none,
3379 @"allowzero": bool = false,
3380 mutable: bool = true, // TODO rename this to const, not mutable
3381 @"volatile": bool = false,
3382 size: std.builtin.Type.Pointer.Size = .One,
3383
3384 pub const VectorIndex = InternPool.Key.PtrType.VectorIndex;
3385
3386 pub fn alignment(data: Data, mod: *Module) u32 {
3387 if (data.@"align" != 0) return data.@"align";
3388 return abiAlignment(data.pointee_type, mod);
3389 }
3390
3391 pub fn fromKey(p: InternPool.Key.PtrType) Data {
3392 return .{
3393 .pointee_type = p.child.toType(),
3394 .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null,
3395 .@"align" = @intCast(u32, p.flags.alignment.toByteUnits(0)),
3396 .@"addrspace" = p.flags.address_space,
3397 .bit_offset = p.packed_offset.bit_offset,
3398 .host_size = p.packed_offset.host_size,
3399 .vector_index = p.flags.vector_index,
3400 .@"allowzero" = p.flags.is_allowzero,
3401 .mutable = !p.flags.is_const,
3402 .@"volatile" = p.flags.is_volatile,
3403 .size = p.flags.size,
3404 };
3405 }
3406 };
3407 };
3408 };
3409
3410 pub const @"u1": Type = .{ .ip_index = .u1_type };3336 pub const @"u1": Type = .{ .ip_index = .u1_type };
3411 pub const @"u8": Type = .{ .ip_index = .u8_type };3337 pub const @"u8": Type = .{ .ip_index = .u8_type };
3412 pub const @"u16": Type = .{ .ip_index = .u16_type };3338 pub const @"u16": Type = .{ .ip_index = .u16_type };
...@@ -3464,80 +3390,6 @@ pub const Type = struct {...@@ -3464,80 +3390,6 @@ pub const Type = struct {
34643390
3465 pub const err_int = Type.u16;3391 pub const err_int = Type.u16;
34663392
3467 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
3468 // TODO: update callsites of this function to directly call mod.ptrType
3469 // and then delete this function.
3470 _ = arena;
3471
3472 var d = data;
3473
3474 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
3475 // type, we change it to 0 here. If this causes an assertion trip because the
3476 // pointee type needs to be resolved more, that needs to be done before calling
3477 // this ptr() function.
3478 if (d.@"align" != 0) canonicalize: {
3479 if (!d.pointee_type.layoutIsResolved(mod)) break :canonicalize;
3480 if (d.@"align" == d.pointee_type.abiAlignment(mod)) {
3481 d.@"align" = 0;
3482 }
3483 }
3484
3485 // Canonicalize host_size. If it matches the bit size of the pointee type,
3486 // we change it to 0 here. If this causes an assertion trip, the pointee type
3487 // needs to be resolved before calling this ptr() function.
3488 if (d.host_size != 0) {
3489 assert(d.bit_offset < d.host_size * 8);
3490 if (d.host_size * 8 == d.pointee_type.bitSize(mod)) {
3491 assert(d.bit_offset == 0);
3492 d.host_size = 0;
3493 }
3494 }
3495
3496 return mod.ptrType(.{
3497 .child = d.pointee_type.ip_index,
3498 .sentinel = if (d.sentinel) |s| s.ip_index else .none,
3499 .flags = .{
3500 .alignment = InternPool.Alignment.fromByteUnits(d.@"align"),
3501 .vector_index = d.vector_index,
3502 .size = d.size,
3503 .is_const = !d.mutable,
3504 .is_volatile = d.@"volatile",
3505 .is_allowzero = d.@"allowzero",
3506 .address_space = d.@"addrspace",
3507 },
3508 .packed_offset = .{
3509 .host_size = d.host_size,
3510 .bit_offset = d.bit_offset,
3511 },
3512 });
3513 }
3514
3515 pub fn array(
3516 arena: Allocator,
3517 len: u64,
3518 sent: ?Value,
3519 elem_type: Type,
3520 mod: *Module,
3521 ) Allocator.Error!Type {
3522 // TODO: update callsites of this function to directly call mod.arrayType
3523 // and then delete this function.
3524 _ = arena;
3525
3526 return mod.arrayType(.{
3527 .len = len,
3528 .child = elem_type.ip_index,
3529 .sentinel = if (sent) |s| s.ip_index else .none,
3530 });
3531 }
3532
3533 pub fn optional(arena: Allocator, child_type: Type, mod: *Module) Allocator.Error!Type {
3534 // TODO: update callsites of this function to directly call
3535 // mod.optionalType and then delete this function.
3536 _ = arena;
3537
3538 return mod.optionalType(child_type.ip_index);
3539 }
3540
3541 pub fn smallestUnsignedBits(max: u64) u16 {3393 pub fn smallestUnsignedBits(max: u64) u16 {
3542 if (max == 0) return 0;3394 if (max == 0) return 0;
3543 const base = std.math.log2(max);3395 const base = std.math.log2(max);
src/value.zig+5-34
...@@ -1823,7 +1823,7 @@ pub const Value = struct {...@@ -1823,7 +1823,7 @@ pub const Value = struct {
1823 }1823 }
18241824
1825 pub fn isRuntimeValue(val: Value, mod: *Module) bool {1825 pub fn isRuntimeValue(val: Value, mod: *Module) bool {
1826 return mod.intern_pool.indexToKey(val.toIntern()) == .runtime_value;1826 return mod.intern_pool.isRuntimeValue(val.toIntern());
1827 }1827 }
18281828
1829 /// Returns true if a Value is backed by a variable1829 /// Returns true if a Value is backed by a variable
...@@ -1851,33 +1851,9 @@ pub const Value = struct {...@@ -1851,33 +1851,9 @@ pub const Value = struct {
1851 }1851 }
18521852
1853 pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool {1853 pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool {
1854 return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {1854 const backing_decl = mod.intern_pool.getBackingDecl(val.toIntern()).unwrap() orelse return false;
1855 .variable => false,1855 const variable = mod.declPtr(backing_decl).getOwnedVariable(mod) orelse return false;
1856 else => val.isPtrToThreadLocalInner(mod),1856 return variable.is_threadlocal;
1857 };
1858 }
1859
1860 pub fn isPtrToThreadLocalInner(val: Value, mod: *Module) bool {
1861 return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {
1862 .variable => |variable| variable.is_threadlocal,
1863 .ptr => |ptr| switch (ptr.addr) {
1864 .decl => |decl_index| {
1865 const decl = mod.declPtr(decl_index);
1866 assert(decl.has_tv);
1867 return decl.val.isPtrToThreadLocalInner(mod);
1868 },
1869 .mut_decl => |mut_decl| {
1870 const decl = mod.declPtr(mut_decl.decl);
1871 assert(decl.has_tv);
1872 return decl.val.isPtrToThreadLocalInner(mod);
1873 },
1874 .int => false,
1875 .eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocalInner(mod),
1876 .comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocalInner(mod),
1877 .elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocalInner(mod),
1878 },
1879 else => false,
1880 };
1881 }1857 }
18821858
1883 // Asserts that the provided start/end are in-bounds.1859 // Asserts that the provided start/end are in-bounds.
...@@ -2015,12 +1991,7 @@ pub const Value = struct {...@@ -2015,12 +1991,7 @@ pub const Value = struct {
2015 }1991 }
20161992
2017 pub fn isUndef(val: Value, mod: *Module) bool {1993 pub fn isUndef(val: Value, mod: *Module) bool {
2018 if (val.ip_index == .none) return false;1994 return val.ip_index != .none and mod.intern_pool.isUndef(val.toIntern());
2019 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
2020 .undef => true,
2021 .simple_value => |v| v == .undefined,
2022 else => false,
2023 };
2024 }1995 }
20251996
2026 /// TODO: check for cases such as array that is not marked undef but all the element1997 /// TODO: check for cases such as array that is not marked undef but all the element