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 {
850850 pub const Index = u32;
851851
852852 pub const Ref = enum(u32) {
853 u0_type = @intFromEnum(InternPool.Index.u0_type),
854 i0_type = @intFromEnum(InternPool.Index.i0_type),
853855 u1_type = @intFromEnum(InternPool.Index.u1_type),
854856 u8_type = @intFromEnum(InternPool.Index.u8_type),
855857 i8_type = @intFromEnum(InternPool.Index.i8_type),
......@@ -909,6 +911,7 @@ pub const Inst = struct {
909911 single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),
910912 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
911913 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),
912915 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
913916 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
914917 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),
......@@ -1182,7 +1185,7 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {
11821185 return air.extra[extra.end..][0..extra.data.body_len];
11831186}
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 {
11861189 const ref_int = @intFromEnum(inst);
11871190 if (ref_int < InternPool.static_keys.len) {
11881191 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 {
11901193 return air.typeOfIndex(ref_int - ref_start_index, ip);
11911194}
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 {
11941197 const datas = air.instructions.items(.data);
11951198 switch (air.instructions.items(.tag)[inst]) {
11961199 .add,
......@@ -1403,7 +1406,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: *const InternPool) Type {
14031406
14041407 .call, .call_always_tail, .call_never_tail, .call_never_inline => {
14051408 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();
14071410 },
14081411
14091412 .slice_elem_val, .ptr_elem_val, .array_elem_val => {
src/InternPool.zig+111-10
......@@ -620,6 +620,8 @@ pub const Key = union(enum) {
620620 len: Index = .none,
621621
622622 pub const Addr = union(enum) {
623 const Tag = @typeInfo(Addr).Union.tag_type.?;
624
623625 decl: Module.Decl.Index,
624626 mut_decl: MutDecl,
625627 comptime_field: Index,
......@@ -1241,11 +1243,13 @@ pub const Item = struct {
12411243/// When adding a tag to this enum, consider adding a corresponding entry to
12421244/// `primitives` in AstGen.zig.
12431245pub const Index = enum(u32) {
1244 pub const first_type: Index = .u1_type;
1246 pub const first_type: Index = .u0_type;
12451247 pub const last_type: Index = .empty_struct_type;
12461248 pub const first_value: Index = .undef;
12471249 pub const last_value: Index = .empty_struct;
12481250
1251 u0_type,
1252 i0_type,
12491253 u1_type,
12501254 u8_type,
12511255 i8_type,
......@@ -1305,6 +1309,7 @@ pub const Index = enum(u32) {
13051309 single_const_pointer_to_comptime_int_type,
13061310 slice_const_u8_type,
13071311 slice_const_u8_sentinel_0_type,
1312 optional_noreturn_type,
13081313 anyerror_void_error_union_type,
13091314 generic_poison_type,
13101315 /// `@TypeOf(.{})`
......@@ -1531,6 +1536,16 @@ pub const Index = enum(u32) {
15311536};
15321537
15331538pub 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
15341549 .{ .int_type = .{
15351550 .signedness = .unsigned,
15361551 .bits = 1,
......@@ -1637,6 +1652,7 @@ pub const static_keys = [_]Key{
16371652 .{ .simple_type = .extern_options },
16381653 .{ .simple_type = .type_info },
16391654
1655 // [*]u8
16401656 .{ .ptr_type = .{
16411657 .child = .u8_type,
16421658 .flags = .{
......@@ -1644,7 +1660,7 @@ pub const static_keys = [_]Key{
16441660 },
16451661 } },
16461662
1647 // manyptr_const_u8_type
1663 // [*]const u8
16481664 .{ .ptr_type = .{
16491665 .child = .u8_type,
16501666 .flags = .{
......@@ -1653,7 +1669,7 @@ pub const static_keys = [_]Key{
16531669 },
16541670 } },
16551671
1656 // manyptr_const_u8_sentinel_0_type
1672 // [*:0]const u8
16571673 .{ .ptr_type = .{
16581674 .child = .u8_type,
16591675 .sentinel = .zero_u8,
......@@ -1663,6 +1679,7 @@ pub const static_keys = [_]Key{
16631679 },
16641680 } },
16651681
1682 // comptime_int
16661683 .{ .ptr_type = .{
16671684 .child = .comptime_int_type,
16681685 .flags = .{
......@@ -1671,7 +1688,7 @@ pub const static_keys = [_]Key{
16711688 },
16721689 } },
16731690
1674 // slice_const_u8_type
1691 // []const u8
16751692 .{ .ptr_type = .{
16761693 .child = .u8_type,
16771694 .flags = .{
......@@ -1680,7 +1697,7 @@ pub const static_keys = [_]Key{
16801697 },
16811698 } },
16821699
1683 // slice_const_u8_sentinel_0_type
1700 // [:0]const u8
16841701 .{ .ptr_type = .{
16851702 .child = .u8_type,
16861703 .sentinel = .zero_u8,
......@@ -1690,7 +1707,10 @@ pub const static_keys = [_]Key{
16901707 },
16911708 } },
16921709
1693 // anyerror_void_error_union_type
1710 // ?noreturn
1711 .{ .opt_type = .noreturn_type },
1712
1713 // anyerror!void
16941714 .{ .error_union_type = .{
16951715 .error_set_type = .anyerror_type,
16961716 .payload_type = .void_type,
......@@ -2279,8 +2299,9 @@ pub const Alignment = enum(u6) {
22792299 return fromByteUnits(n);
22802300 }
22812301
2282 pub fn min(a: Alignment, b: Alignment) Alignment {
2283 return @enumFromInt(Alignment, @min(@intFromEnum(a), @intFromEnum(b)));
2302 pub fn order(lhs: Alignment, rhs: Alignment) std.math.Order {
2303 assert(lhs != .none and rhs != .none);
2304 return std.math.order(@intFromEnum(lhs), @intFromEnum(rhs));
22842305 }
22852306};
22862307
......@@ -5463,6 +5484,8 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
54635484 // An alternative would be to topological sort the static keys, but this would
54645485 // mean that the range of type indices would not be dense.
54655486 return switch (index) {
5487 .u0_type,
5488 .i0_type,
54665489 .u1_type,
54675490 .u8_type,
54685491 .i8_type,
......@@ -5522,6 +5545,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
55225545 .single_const_pointer_to_comptime_int_type,
55235546 .slice_const_u8_type,
55245547 .slice_const_u8_sentinel_0_type,
5548 .optional_noreturn_type,
55255549 .anyerror_void_error_union_type,
55265550 .generic_poison_type,
55275551 .empty_struct_type,
......@@ -5669,20 +5693,96 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
56695693 };
56705694}
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
56725711pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
56735712 return switch (ty) {
56745713 .noreturn_type => true,
5675 else => switch (ip.indexToKey(ty)) {
5676 .error_set_type => |error_set_type| error_set_type.names.len == 0,
5714 else => switch (ip.items.items(.tag)[@intFromEnum(ty)]) {
5715 .type_error_set => ip.extra.items[ip.items.items(.data)[@intFromEnum(ty)] + std.meta.fieldIndex(ErrorSet, "names_len").?] == 0,
56775716 else => false,
56785717 },
56795718 };
56805719}
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
56825780/// This is a particularly hot function, so we operate directly on encodings
56835781/// rather than the more straightforward implementation of calling `indexToKey`.
56845782pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPoison}!std.builtin.TypeId {
56855783 return switch (index) {
5784 .u0_type,
5785 .i0_type,
56865786 .u1_type,
56875787 .u8_type,
56885788 .i8_type,
......@@ -5754,6 +5854,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
57545854 .slice_const_u8_sentinel_0_type,
57555855 => .Pointer,
57565856
5857 .optional_noreturn_type => .Optional,
57575858 .anyerror_void_error_union_type => .ErrorUnion,
57585859 .empty_struct_type => .Struct,
57595860
src/Module.zig+25-44
......@@ -33,6 +33,7 @@ const Liveness = @import("Liveness.zig");
3333const isUpDir = @import("introspect.zig").isUpDir;
3434const clang = @import("clang.zig");
3535const InternPool = @import("InternPool.zig");
36const Alignment = InternPool.Alignment;
3637
3738comptime {
3839 @setEvalBranchQuota(4000);
......@@ -241,7 +242,7 @@ pub const MonomorphedFuncsAdaptedContext = struct {
241242};
242243
243244pub const SetAlignStack = struct {
244 alignment: u32,
245 alignment: Alignment,
245246 /// TODO: This needs to store a non-lazy source location for the case of an inline function
246247 /// which does `@setAlignStack` (applying it to the caller).
247248 src: LazySrcLoc,
......@@ -432,7 +433,7 @@ pub const Decl = struct {
432433 /// Populated when `has_tv`.
433434 @"linksection": InternPool.OptionalNullTerminatedString,
434435 /// Populated when `has_tv`.
435 @"align": u32,
436 alignment: Alignment,
436437 /// Populated when `has_tv`.
437438 @"addrspace": std.builtin.AddressSpace,
438439 /// The direct parent namespace of the Decl.
......@@ -863,13 +864,7 @@ pub const Decl = struct {
863864
864865 pub fn getAlignment(decl: Decl, mod: *Module) u32 {
865866 assert(decl.has_tv);
866 if (decl.@"align" != 0) {
867 // Explicit alignment.
868 return decl.@"align";
869 } else {
870 // Natural alignment.
871 return decl.ty.abiAlignment(mod);
872 }
867 return @intCast(u32, decl.alignment.toByteUnitsOptional() orelse decl.ty.abiAlignment(mod));
873868 }
874869
875870 pub fn intern(decl: *Decl, mod: *Module) Allocator.Error!void {
......@@ -955,7 +950,7 @@ pub const Struct = struct {
955950 /// Uses `none` to indicate no default.
956951 default_val: InternPool.Index,
957952 /// Zero means to use the ABI alignment of the type.
958 abi_align: u32,
953 abi_align: Alignment,
959954 /// undefined until `status` is `have_layout`.
960955 offset: u32,
961956 /// If true then `default_val` is the comptime field value.
......@@ -967,9 +962,9 @@ pub const Struct = struct {
967962 mod: *Module,
968963 layout: std.builtin.Type.ContainerLayout,
969964 ) u32 {
970 if (field.abi_align != 0) {
965 if (field.abi_align.toByteUnitsOptional()) |abi_align| {
971966 assert(layout != .Packed);
972 return field.abi_align;
967 return @intCast(u32, abi_align);
973968 }
974969
975970 const target = mod.getTarget();
......@@ -1150,17 +1145,13 @@ pub const Union = struct {
11501145 /// undefined until `status` is `have_field_types` or `have_layout`.
11511146 ty: Type,
11521147 /// 0 means the ABI alignment of the type.
1153 abi_align: u32,
1148 abi_align: Alignment,
11541149
11551150 /// Returns the field alignment, assuming the union is not packed.
11561151 /// Keep implementation in sync with `Sema.unionFieldAlignment`.
11571152 /// Prefer to call that function instead of this one during Sema.
11581153 pub fn normalAlignment(field: Field, mod: *Module) u32 {
1159 if (field.abi_align == 0) {
1160 return field.ty.abiAlignment(mod);
1161 } else {
1162 return field.abi_align;
1163 }
1154 return @intCast(u32, field.abi_align.toByteUnitsOptional() orelse field.ty.abiAlignment(mod));
11641155 }
11651156 };
11661157
......@@ -1272,20 +1263,14 @@ pub const Union = struct {
12721263 for (fields, 0..) |field, i| {
12731264 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
12741265
1275 const field_align = a: {
1276 if (field.abi_align == 0) {
1277 break :a field.ty.abiAlignment(mod);
1278 } else {
1279 break :a field.abi_align;
1280 }
1281 };
1266 const field_align = field.abi_align.toByteUnitsOptional() orelse field.ty.abiAlignment(mod);
12821267 const field_size = field.ty.abiSize(mod);
12831268 if (field_size > payload_size) {
12841269 payload_size = field_size;
12851270 biggest_field = @intCast(u32, i);
12861271 }
12871272 if (field_align > payload_align) {
1288 payload_align = field_align;
1273 payload_align = @intCast(u32, field_align);
12891274 most_aligned_field = @intCast(u32, i);
12901275 most_aligned_field_size = field_size;
12911276 }
......@@ -4394,7 +4379,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
43944379 new_decl.has_linksection_or_addrspace = false;
43954380 new_decl.ty = Type.type;
43964381 new_decl.val = struct_ty.toValue();
4397 new_decl.@"align" = 0;
4382 new_decl.alignment = .none;
43984383 new_decl.@"linksection" = .none;
43994384 new_decl.has_tv = true;
44004385 new_decl.owns_tv = true;
......@@ -4584,7 +4569,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45844569
45854570 decl.ty = InternPool.Index.type_type.toType();
45864571 decl.val = ty.toValue();
4587 decl.@"align" = 0;
4572 decl.alignment = .none;
45884573 decl.@"linksection" = .none;
45894574 decl.has_tv = true;
45904575 decl.owns_tv = false;
......@@ -4665,9 +4650,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
46654650
46664651 decl.ty = decl_tv.ty;
46674652 decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();
4668 decl.@"align" = blk: {
4653 decl.alignment = blk: {
46694654 const align_ref = decl.zirAlignRef(mod);
4670 if (align_ref == .none) break :blk 0;
4655 if (align_ref == .none) break :blk .none;
46714656 break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);
46724657 };
46734658 decl.@"linksection" = blk: {
......@@ -5758,7 +5743,7 @@ pub fn allocateNewDecl(
57585743 .owns_tv = false,
57595744 .ty = undefined,
57605745 .val = undefined,
5761 .@"align" = undefined,
5746 .alignment = undefined,
57625747 .@"linksection" = .none,
57635748 .@"addrspace" = .generic,
57645749 .analysis = .unreferenced,
......@@ -5830,7 +5815,7 @@ pub fn initNewAnonDecl(
58305815 new_decl.src_line = src_line;
58315816 new_decl.ty = typed_value.ty;
58325817 new_decl.val = typed_value.val;
5833 new_decl.@"align" = 0;
5818 new_decl.alignment = .none;
58345819 new_decl.@"linksection" = .none;
58355820 new_decl.has_tv = true;
58365821 new_decl.analysis = .complete;
......@@ -6773,13 +6758,9 @@ pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
67736758}
67746759
67756760pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
6776 const info = Type.ptrInfoIp(&mod.intern_pool, ptr_ty.toIntern());
6777 return mod.ptrType(.{
6778 .child = new_child.toIntern(),
6779 .sentinel = info.sentinel,
6780 .flags = info.flags,
6781 .packed_offset = info.packed_offset,
6782 });
6761 var info = ptr_ty.ptrInfo(mod);
6762 info.child = new_child.toIntern();
6763 return mod.ptrType(info);
67836764}
67846765
67856766pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type {
......@@ -7018,7 +6999,7 @@ pub fn atomicPtrAlignment(
70186999 mod: *Module,
70197000 ty: Type,
70207001 diags: *AtomicPtrAlignmentDiagnostics,
7021) AtomicPtrAlignmentError!u32 {
7002) AtomicPtrAlignmentError!Alignment {
70227003 const target = mod.getTarget();
70237004 const max_atomic_bits: u16 = switch (target.cpu.arch) {
70247005 .avr,
......@@ -7104,11 +7085,11 @@ pub fn atomicPtrAlignment(
71047085 };
71057086 return error.FloatTooBig;
71067087 }
7107 return 0;
7088 return .none;
71087089 },
7109 .Bool => return 0,
7090 .Bool => return .none,
71107091 else => {
7111 if (ty.isPtrAtRuntime(mod)) return 0;
7092 if (ty.isPtrAtRuntime(mod)) return .none;
71127093 return error.BadType;
71137094 },
71147095 };
......@@ -7122,7 +7103,7 @@ pub fn atomicPtrAlignment(
71227103 return error.IntTooBig;
71237104 }
71247105
7125 return 0;
7106 return .none;
71267107}
71277108
71287109pub 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");
126126const build_options = @import("build_options");
127127const Compilation = @import("Compilation.zig");
128128const InternPool = @import("InternPool.zig");
129const Alignment = InternPool.Alignment;
129130
130131pub const default_branch_quota = 1000;
131132pub const default_reference_trace_len = 2;
......@@ -708,7 +709,7 @@ pub const Block = struct {
708709 }
709710
710711 /// `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 {
712713 const sema = wad.block.sema;
713714 // Do this ahead of time because `createAnonymousDecl` depends on calling
714715 // `type.hasRuntimeBits()`.
......@@ -718,8 +719,7 @@ pub const Block = struct {
718719 .val = val,
719720 });
720721 const new_decl = sema.mod.declPtr(new_decl_index);
721 // TODO: migrate Decl alignment to use `InternPool.Alignment`
722 new_decl.@"align" = @intCast(u32, alignment);
722 new_decl.alignment = alignment;
723723 errdefer sema.mod.abortAnonDecl(new_decl_index);
724724 wad.finished = true;
725725 try sema.mod.finalizeAnonDecl(new_decl_index);
......@@ -1847,7 +1847,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
18471847
18481848 // var addrs: [err_return_trace_addr_count]usize = undefined;
18491849 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 });
18511854 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));
18521855
18531856 // var st: StackTrace = undefined;
......@@ -1898,13 +1901,10 @@ fn resolveConstMaybeUndefVal(
18981901 reason: []const u8,
18991902) CompileError!Value {
19001903 if (try sema.resolveMaybeUndefValAllowVariables(inst)) |val| {
1901 switch (val.toIntern()) {
1902 .generic_poison => return error.GenericPoison,
1903 else => switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {
1904 .variable => return sema.failWithNeededComptime(block, src, reason),
1905 else => return val,
1906 },
1907 }
1904 if (val.isGenericPoison()) return error.GenericPoison;
1905 if (sema.mod.intern_pool.isVariable(val.toIntern()))
1906 return sema.failWithNeededComptime(block, src, reason);
1907 return val;
19081908 }
19091909 return sema.failWithNeededComptime(block, src, reason);
19101910}
......@@ -1919,15 +1919,11 @@ fn resolveConstValue(
19191919 reason: []const u8,
19201920) CompileError!Value {
19211921 if (try sema.resolveMaybeUndefValAllowVariables(air_ref)) |val| {
1922 switch (val.toIntern()) {
1923 .generic_poison => return error.GenericPoison,
1924 .undef => return sema.failWithUseOfUndef(block, src),
1925 else => switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {
1926 .undef => return sema.failWithUseOfUndef(block, src),
1927 .variable => return sema.failWithNeededComptime(block, src, reason),
1928 else => return val,
1929 },
1930 }
1922 if (val.isGenericPoison()) return error.GenericPoison;
1923 if (val.isUndef(sema.mod)) return sema.failWithUseOfUndef(block, src);
1924 if (sema.mod.intern_pool.isVariable(val.toIntern()))
1925 return sema.failWithNeededComptime(block, src, reason);
1926 return val;
19311927 }
19321928 return sema.failWithNeededComptime(block, src, reason);
19331929}
......@@ -1971,14 +1967,9 @@ fn resolveMaybeUndefVal(
19711967 inst: Air.Inst.Ref,
19721968) CompileError!?Value {
19731969 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
1974 switch (val.ip_index) {
1975 .generic_poison => return error.GenericPoison,
1976 .none => return val,
1977 else => switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {
1978 .variable => return null,
1979 else => return val,
1980 },
1981 }
1970 if (val.isGenericPoison()) return error.GenericPoison;
1971 if (val.ip_index != .none and sema.mod.intern_pool.isVariable(val.toIntern())) return null;
1972 return val;
19821973}
19831974
19841975/// Value Tag `variable` causes this function to return `null`.
......@@ -2002,20 +1993,13 @@ fn resolveMaybeUndefValIntable(
20021993 inst: Air.Inst.Ref,
20031994) CompileError!?Value {
20041995 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
2005 var check = val;
2006 while (true) switch (check.ip_index) {
2007 .generic_poison => return error.GenericPoison,
2008 .none => break,
2009 else => switch (sema.mod.intern_pool.indexToKey(check.toIntern())) {
2010 .variable => return null,
2011 .ptr => |ptr| switch (ptr.addr) {
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 },
1996 if (val.isGenericPoison()) return error.GenericPoison;
1997 if (val.ip_index == .none) return val;
1998 if (sema.mod.intern_pool.isVariable(val.toIntern())) return null;
1999 if (sema.mod.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) {
2000 .decl, .mut_decl, .comptime_field => return null,
2001 .int => {},
2002 .eu_payload, .opt_payload, .elem, .field => unreachable,
20192003 };
20202004 return try sema.resolveLazyValue(val);
20212005}
......@@ -2211,9 +2195,9 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.
22112195 .Array => return ip.stringEqlSlice(field_name, "len"),
22122196 .Pointer => {
22132197 const ptr_info = ty.ptrInfo(mod);
2214 if (ptr_info.size == .Slice) {
2198 if (ptr_info.flags.size == .Slice) {
22152199 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) {
22172201 return ip.stringEqlSlice(field_name, "len");
22182202 } else return false;
22192203 },
......@@ -2427,11 +2411,11 @@ fn analyzeAsAlign(
24272411 block: *Block,
24282412 src: LazySrcLoc,
24292413 air_ref: Air.Inst.Ref,
2430) !u32 {
2414) !Alignment {
24312415 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.
24332417 try sema.validateAlign(block, src, alignment);
2434 return alignment;
2418 return Alignment.fromNonzeroByteUnits(alignment);
24352419}
24362420
24372421fn validateAlign(
......@@ -2453,7 +2437,7 @@ pub fn resolveAlign(
24532437 block: *Block,
24542438 src: LazySrcLoc,
24552439 zir_ref: Zir.Inst.Ref,
2456) !u32 {
2440) !Alignment {
24572441 const air_ref = try sema.resolveInst(zir_ref);
24582442 return sema.analyzeAsAlign(block, src, air_ref);
24592443}
......@@ -2569,7 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
25692553 const decl_index = try anon_decl.finish(
25702554 pointee_ty,
25712555 (try mod.intern(.{ .undef = pointee_ty.toIntern() })).toValue(),
2572 alignment.toByteUnits(0),
2556 alignment,
25732557 );
25742558 sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index;
25752559 if (alignment != .none) {
......@@ -2645,9 +2629,9 @@ fn coerceResultPtr(
26452629 }
26462630 }
26472631
2648 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
2649 .pointee_type = pointee_ty,
2650 .@"addrspace" = addr_space,
2632 const ptr_ty = try mod.ptrType(.{
2633 .child = pointee_ty.toIntern(),
2634 .flags = .{ .address_space = addr_space },
26512635 });
26522636
26532637 var new_ptr = ptr;
......@@ -2675,9 +2659,9 @@ fn coerceResultPtr(
26752659 // Array coerced to Vector where element size is not equal but coercible.
26762660 .aggregate_init => {
26772661 const ty_pl = air_datas[trash_inst].ty_pl;
2678 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{
2679 .pointee_type = try sema.analyzeAsType(block, src, ty_pl.ty),
2680 .@"addrspace" = addr_space,
2662 const ptr_operand_ty = try mod.ptrType(.{
2663 .child = (try sema.analyzeAsType(block, src, ty_pl.ty)).toIntern(),
2664 .flags = .{ .address_space = addr_space },
26812665 });
26822666
26832667 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
......@@ -2689,9 +2673,9 @@ fn coerceResultPtr(
26892673 .bitcast => {
26902674 const ty_op = air_datas[trash_inst].ty_op;
26912675 const operand_ty = sema.typeOf(ty_op.operand);
2692 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{
2693 .pointee_type = operand_ty,
2694 .@"addrspace" = addr_space,
2676 const ptr_operand_ty = try mod.ptrType(.{
2677 .child = operand_ty.toIntern(),
2678 .flags = .{ .address_space = addr_space },
26952679 });
26962680 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
26972681 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 {
34013385
34023386 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
34033387 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);
34053389 }
34063390
34073391 const target = sema.mod.getTarget();
3408 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
3409 .pointee_type = sema.fn_ret_ty,
3410 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
3392 const ptr_type = try sema.mod.ptrType(.{
3393 .child = sema.fn_ret_ty.toIntern(),
3394 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
34113395 });
34123396
34133397 if (block.inlining != null) {
......@@ -3579,12 +3563,12 @@ fn zirAllocExtended(
35793563 break :blk try sema.resolveType(block, ty_src, type_ref);
35803564 } else undefined;
35813565
3582 const alignment: u32 = if (small.has_align) blk: {
3566 const alignment = if (small.has_align) blk: {
35833567 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);
35843568 extra_index += 1;
35853569 const alignment = try sema.resolveAlign(block, align_src, align_ref);
35863570 break :blk alignment;
3587 } else 0;
3571 } else .none;
35883572
35893573 if (block.is_comptime or small.is_comptime) {
35903574 if (small.has_type) {
......@@ -3594,7 +3578,7 @@ fn zirAllocExtended(
35943578 .tag = .inferred_alloc_comptime,
35953579 .data = .{ .inferred_alloc_comptime = .{
35963580 .decl_index = undefined,
3597 .alignment = InternPool.Alignment.fromByteUnits(alignment),
3581 .alignment = alignment,
35983582 .is_const = small.is_const,
35993583 } },
36003584 });
......@@ -3608,10 +3592,12 @@ fn zirAllocExtended(
36083592 }
36093593 const target = sema.mod.getTarget();
36103594 try sema.resolveTypeLayout(var_ty);
3611 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
3612 .pointee_type = var_ty,
3613 .@"align" = alignment,
3614 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
3595 const ptr_type = try sema.mod.ptrType(.{
3596 .child = var_ty.toIntern(),
3597 .flags = .{
3598 .alignment = alignment,
3599 .address_space = target_util.defaultAddressSpace(target, .local),
3600 },
36153601 });
36163602 return block.addTy(.alloc, ptr_type);
36173603 }
......@@ -3619,7 +3605,7 @@ fn zirAllocExtended(
36193605 const result_index = try block.addInstAsIndex(.{
36203606 .tag = .inferred_alloc,
36213607 .data = .{ .inferred_alloc = .{
3622 .alignment = InternPool.Alignment.fromByteUnits(alignment),
3608 .alignment = alignment,
36233609 .is_const = small.is_const,
36243610 } },
36253611 });
......@@ -3634,7 +3620,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
36343620 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
36353621 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
36363622 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);
36383624}
36393625
36403626fn 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
36443630 const alloc_ty = sema.typeOf(alloc);
36453631
36463632 var ptr_info = alloc_ty.ptrInfo(mod);
3647 const elem_ty = ptr_info.pointee_type;
3633 const elem_ty = ptr_info.child.toType();
36483634
36493635 // Detect if all stores to an `.alloc` were comptime-known.
36503636 ct: {
......@@ -3688,11 +3674,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
36883674
36893675 var anon_decl = try block.startAnonDecl();
36903676 defer anon_decl.deinit();
3691 return sema.analyzeDeclRef(try anon_decl.finish(
3692 elem_ty,
3693 store_val,
3694 ptr_info.@"align",
3695 ));
3677 return sema.analyzeDeclRef(try anon_decl.finish(elem_ty, store_val, ptr_info.flags.alignment));
36963678 }
36973679
36983680 return sema.makePtrConst(block, alloc);
......@@ -3703,8 +3685,8 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
37033685 const alloc_ty = sema.typeOf(alloc);
37043686
37053687 var ptr_info = alloc_ty.ptrInfo(mod);
3706 ptr_info.mutable = false;
3707 const const_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
3688 ptr_info.flags.is_const = true;
3689 const const_ptr_ty = try mod.ptrType(ptr_info);
37083690
37093691 // Detect if a comptime value simply needs to have its type changed.
37103692 if (try sema.resolveMaybeUndefVal(alloc)) |val| {
......@@ -3743,12 +3725,12 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
37433725 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
37443726 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
37453727 if (block.is_comptime) {
3746 return sema.analyzeComptimeAlloc(block, var_ty, 0);
3728 return sema.analyzeComptimeAlloc(block, var_ty, .none);
37473729 }
37483730 const target = sema.mod.getTarget();
3749 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
3750 .pointee_type = var_ty,
3751 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
3731 const ptr_type = try sema.mod.ptrType(.{
3732 .child = var_ty.toIntern(),
3733 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
37523734 });
37533735 try sema.queueFullTypeResolution(var_ty);
37543736 return block.addTy(.alloc, ptr_type);
......@@ -3762,13 +3744,13 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
37623744 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
37633745 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
37643746 if (block.is_comptime) {
3765 return sema.analyzeComptimeAlloc(block, var_ty, 0);
3747 return sema.analyzeComptimeAlloc(block, var_ty, .none);
37663748 }
37673749 try sema.validateVarType(block, ty_src, var_ty, false);
37683750 const target = sema.mod.getTarget();
3769 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
3770 .pointee_type = var_ty,
3771 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
3751 const ptr_type = try sema.mod.ptrType(.{
3752 .child = var_ty.toIntern(),
3753 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
37723754 });
37733755 try sema.queueFullTypeResolution(var_ty);
37743756 return block.addTy(.alloc, ptr_type);
......@@ -3934,11 +3916,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
39343916 const new_decl_index = d: {
39353917 var anon_decl = try block.startAnonDecl();
39363918 defer anon_decl.deinit();
3937 const new_decl_index = try anon_decl.finish(
3938 final_elem_ty,
3939 store_val,
3940 ia1.alignment.toByteUnits(0),
3941 );
3919 const new_decl_index = try anon_decl.finish(final_elem_ty, store_val, ia1.alignment);
39423920 break :d new_decl_index;
39433921 };
39443922 try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index);
......@@ -5162,11 +5140,7 @@ fn storeToInferredAllocComptime(
51625140 if (operand_val.getVariable(sema.mod) != null) break :store;
51635141 var anon_decl = try block.startAnonDecl();
51645142 defer anon_decl.deinit();
5165 iac.decl_index = try anon_decl.finish(
5166 operand_ty,
5167 operand_val,
5168 iac.alignment.toByteUnits(0),
5169 );
5143 iac.decl_index = try anon_decl.finish(operand_ty, operand_val, iac.alignment);
51705144 try sema.comptime_mutable_decls.append(iac.decl_index);
51715145 return;
51725146 }
......@@ -5247,8 +5221,8 @@ fn addStrLit(sema: *Sema, block: *Block, bytes: []const u8) CompileError!Air.Ins
52475221 const duped_bytes = try sema.arena.dupe(u8, bytes);
52485222 const ty = try mod.arrayType(.{
52495223 .len = bytes.len,
5250 .child = .u8_type,
52515224 .sentinel = .zero_u8,
5225 .child = .u8_type,
52525226 });
52535227 const val = try mod.intern(.{ .aggregate = .{
52545228 .ty = ty.toIntern(),
......@@ -5859,11 +5833,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
58595833 const decl_index = if (operand.val.getFunction(sema.mod)) |function| function.owner_decl else blk: {
58605834 var anon_decl = try block.startAnonDecl();
58615835 defer anon_decl.deinit();
5862 break :blk try anon_decl.finish(
5863 operand.ty,
5864 operand.val,
5865 0,
5866 );
5836 break :blk try anon_decl.finish(operand.ty, operand.val, .none);
58675837 };
58685838 try sema.analyzeExport(block, src, options, decl_index);
58695839}
......@@ -5948,9 +5918,9 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
59485918 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
59495919 const src = LazySrcLoc.nodeOffset(extra.node);
59505920 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
5951 if (alignment > 256) {
5921 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
59525922 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
5953 alignment,
5923 alignment.toByteUnitsOptional().?,
59545924 });
59555925 }
59565926 const func_index = sema.func_index.unwrap() orelse
......@@ -6585,8 +6555,8 @@ fn checkCallArgumentCount(
65856555 .Fn => break :func_ty callee_ty,
65866556 .Pointer => {
65876557 const ptr_info = callee_ty.ptrInfo(mod);
6588 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {
6589 break :func_ty ptr_info.pointee_type;
6558 if (ptr_info.flags.size == .One and ptr_info.child.toType().zigTypeTag(mod) == .Fn) {
6559 break :func_ty ptr_info.child.toType();
65906560 }
65916561 },
65926562 .Optional => {
......@@ -6657,8 +6627,8 @@ fn callBuiltin(
66576627 .Fn => break :func_ty callee_ty,
66586628 .Pointer => {
66596629 const ptr_info = callee_ty.ptrInfo(mod);
6660 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {
6661 break :func_ty ptr_info.pointee_type;
6630 if (ptr_info.flags.size == .One and ptr_info.child.toType().zigTypeTag(mod) == .Fn) {
6631 break :func_ty ptr_info.child.toType();
66626632 }
66636633 },
66646634 else => {},
......@@ -7896,7 +7866,7 @@ fn resolveGenericInstantiationType(
78967866 .ty = new_decl.ty.toIntern(),
78977867 .index = new_func,
78987868 } })).toValue();
7899 new_decl.@"align" = 0;
7869 new_decl.alignment = .none;
79007870 new_decl.has_tv = true;
79017871 new_decl.owns_tv = true;
79027872 new_decl.analysis = .complete;
......@@ -7971,7 +7941,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
79717941 } else if (child_type.zigTypeTag(mod) == .Null) {
79727942 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)});
79737943 }
7974 const opt_type = try Type.optional(sema.arena, child_type, mod);
7944 const opt_type = try mod.optionalType(child_type.toIntern());
79757945
79767946 return sema.addType(opt_type);
79777947}
......@@ -8017,7 +7987,10 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
80177987 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime-known");
80187988 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
80197989 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
80227995 return sema.addType(array_ty);
80237996}
......@@ -8037,7 +8010,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
80378010 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);
80388011 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
80398012 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
80428019 return sema.addType(array_ty);
80438020}
......@@ -8412,10 +8389,12 @@ fn analyzeOptionalPayloadPtr(
84128389 }
84138390
84148391 const child_type = opt_type.optionalChild(mod);
8415 const child_pointer = try Type.ptr(sema.arena, mod, .{
8416 .pointee_type = child_type,
8417 .mutable = !optional_ptr_ty.isConstPtr(mod),
8418 .@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod),
8392 const child_pointer = try mod.ptrType(.{
8393 .child = child_type.toIntern(),
8394 .flags = .{
8395 .is_const = optional_ptr_ty.isConstPtr(mod),
8396 .address_space = optional_ptr_ty.ptrAddressSpace(mod),
8397 },
84198398 });
84208399
84218400 if (try sema.resolveDefinedValue(block, src, optional_ptr)) |ptr_val| {
......@@ -8479,14 +8458,15 @@ fn zirOptionalPayload(
84798458 // TODO https://github.com/ziglang/zig/issues/6597
84808459 if (true) break :t operand_ty;
84818460 const ptr_info = operand_ty.ptrInfo(mod);
8482 break :t try Type.ptr(sema.arena, mod, .{
8483 .pointee_type = ptr_info.pointee_type,
8484 .@"align" = ptr_info.@"align",
8485 .@"addrspace" = ptr_info.@"addrspace",
8486 .mutable = ptr_info.mutable,
8487 .@"allowzero" = ptr_info.@"allowzero",
8488 .@"volatile" = ptr_info.@"volatile",
8489 .size = .One,
8461 break :t try mod.ptrType(.{
8462 .child = ptr_info.child,
8463 .flags = .{
8464 .alignment = ptr_info.flags.alignment,
8465 .is_const = ptr_info.flags.is_const,
8466 .is_volatile = ptr_info.flags.is_volatile,
8467 .is_allowzero = ptr_info.flags.is_allowzero,
8468 .address_space = ptr_info.flags.address_space,
8469 },
84908470 });
84918471 },
84928472 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),
......@@ -8599,10 +8579,12 @@ fn analyzeErrUnionPayloadPtr(
85998579
86008580 const err_union_ty = operand_ty.childType(mod);
86018581 const payload_ty = err_union_ty.errorUnionPayload(mod);
8602 const operand_pointer_ty = try Type.ptr(sema.arena, mod, .{
8603 .pointee_type = payload_ty,
8604 .mutable = !operand_ty.isConstPtr(mod),
8605 .@"addrspace" = operand_ty.ptrAddressSpace(mod),
8582 const operand_pointer_ty = try mod.ptrType(.{
8583 .child = payload_ty.toIntern(),
8584 .flags = .{
8585 .is_const = operand_ty.isConstPtr(mod),
8586 .address_space = operand_ty.ptrAddressSpace(mod),
8587 },
86068588 });
86078589
86088590 if (try sema.resolveDefinedValue(block, src, operand)) |ptr_val| {
......@@ -8769,7 +8751,7 @@ fn zirFunc(
87698751 block,
87708752 inst_data.src_node,
87718753 inst,
8772 0,
8754 .none,
87738755 target_util.defaultAddressSpace(target, .function),
87748756 FuncLinkSection.default,
87758757 cc,
......@@ -8898,7 +8880,7 @@ fn funcCommon(
88988880 src_node_offset: i32,
88998881 func_inst: Zir.Inst.Index,
89008882 /// null means generic poison
8901 alignment: ?u32,
8883 alignment: ?Alignment,
89028884 /// null means generic poison
89038885 address_space: ?std.builtin.AddressSpace,
89048886 /// outer null means generic poison; inner null means default link section
......@@ -9147,7 +9129,7 @@ fn funcCommon(
91479129 .return_type = return_type.toIntern(),
91489130 .cc = cc_resolved,
91499131 .cc_is_generic = cc == null,
9150 .alignment = if (alignment) |a| InternPool.Alignment.fromByteUnits(a) else .none,
9132 .alignment = alignment orelse .none,
91519133 .align_is_generic = alignment == null,
91529134 .section_is_generic = section == .generic,
91539135 .addrspace_is_generic = address_space == null,
......@@ -9162,7 +9144,7 @@ fn funcCommon(
91629144 .default => .none,
91639145 .explicit => |section_name| section_name.toOptional(),
91649146 };
9165 sema.owner_decl.@"align" = alignment orelse 0;
9147 sema.owner_decl.alignment = alignment orelse .none;
91669148 sema.owner_decl.@"addrspace" = address_space orelse .generic;
91679149
91689150 if (is_extern) {
......@@ -10294,11 +10276,13 @@ const SwitchProngAnalysis = struct {
1029410276 const union_obj = mod.typeToUnion(operand_ty).?;
1029510277 const field_ty = union_obj.fields.values()[field_index].ty;
1029610278 if (capture_byref) {
10297 const ptr_field_ty = try Type.ptr(sema.arena, mod, .{
10298 .pointee_type = field_ty,
10299 .mutable = operand_ptr_ty.ptrIsMutable(mod),
10300 .@"volatile" = operand_ptr_ty.isVolatilePtr(mod),
10301 .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod),
10279 const ptr_field_ty = try mod.ptrType(.{
10280 .child = field_ty.toIntern(),
10281 .flags = .{
10282 .is_const = !operand_ptr_ty.ptrIsMutable(mod),
10283 .is_volatile = operand_ptr_ty.isVolatilePtr(mod),
10284 .address_space = operand_ptr_ty.ptrAddressSpace(mod),
10285 },
1030210286 });
1030310287 if (try sema.resolveDefinedValue(block, sema.src, spa.operand_ptr)) |union_ptr| {
1030410288 return sema.addConstant(
......@@ -10401,24 +10385,28 @@ const SwitchProngAnalysis = struct {
1040110385 // By-reference captures have some further restrictions which make them easier to emit
1040210386 if (capture_byref) {
1040310387 const operand_ptr_info = operand_ptr_ty.ptrInfo(mod);
10404 const capture_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
10405 .pointee_type = capture_ty,
10406 .@"addrspace" = operand_ptr_info.@"addrspace",
10407 .mutable = operand_ptr_info.mutable,
10408 .@"volatile" = operand_ptr_info.@"volatile",
10409 // TODO: alignment!
10388 const capture_ptr_ty = try mod.ptrType(.{
10389 .child = capture_ty.toIntern(),
10390 .flags = .{
10391 // TODO: alignment!
10392 .is_const = operand_ptr_info.flags.is_const,
10393 .is_volatile = operand_ptr_info.flags.is_volatile,
10394 .address_space = operand_ptr_info.flags.address_space,
10395 },
1041010396 });
1041110397
1041210398 // By-ref captures of hetereogeneous types are only allowed if each field
1041310399 // pointer type is in-memory coercible to the capture pointer type.
1041410400 if (!same_types) {
1041510401 for (field_tys, 0..) |field_ty, i| {
10416 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
10417 .pointee_type = field_ty,
10418 .@"addrspace" = operand_ptr_info.@"addrspace",
10419 .mutable = operand_ptr_info.mutable,
10420 .@"volatile" = operand_ptr_info.@"volatile",
10421 // TODO: alignment!
10402 const field_ptr_ty = try mod.ptrType(.{
10403 .child = field_ty.toIntern(),
10404 .flags = .{
10405 // TODO: alignment!
10406 .is_const = operand_ptr_info.flags.is_const,
10407 .is_volatile = operand_ptr_info.flags.is_volatile,
10408 .address_space = operand_ptr_info.flags.address_space,
10409 },
1042210410 });
1042310411 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ptr_ty, field_ptr_ty, false, sema.mod.getTarget(), .unneeded, .unneeded)) {
1042410412 const multi_idx = raw_capture_src.multi_capture;
......@@ -12675,8 +12663,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1267512663 // - When a Decl is destroyed, it can free the `*Module.EmbedFile`.
1267612664 const ty = try mod.arrayType(.{
1267712665 .len = embed_file.bytes.len,
12678 .child = .u8_type,
1267912666 .sentinel = .zero_u8,
12667 .child = .u8_type,
1268012668 });
1268112669 embed_file.owner_decl = try anon_decl.finish(
1268212670 ty,
......@@ -12684,7 +12672,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1268412672 .ty = ty.toIntern(),
1268512673 .storage = .{ .bytes = embed_file.bytes },
1268612674 } })).toValue(),
12687 0, // default alignment
12675 .none, // default alignment
1268812676 );
1268912677
1269012678 return sema.analyzeDeclRef(embed_file.owner_decl);
......@@ -13308,7 +13296,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1330813296 ),
1330913297 };
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 });
1331213304 const ptr_addrspace = p: {
1331313305 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod);
1331413306 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
1336713359 try sema.requireRuntimeBlock(block, src, runtime_src);
1336813360
1336913361 if (ptr_addrspace) |ptr_as| {
13370 const alloc_ty = try Type.ptr(sema.arena, mod, .{
13371 .pointee_type = result_ty,
13372 .@"addrspace" = ptr_as,
13362 const alloc_ty = try mod.ptrType(.{
13363 .child = result_ty.toIntern(),
13364 .flags = .{ .address_space = ptr_as },
1337313365 });
1337413366 const alloc = try block.addTy(.alloc, alloc_ty);
13375 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
13376 .pointee_type = resolved_elem_ty,
13377 .@"addrspace" = ptr_as,
13367 const elem_ptr_ty = try mod.ptrType(.{
13368 .child = resolved_elem_ty.toIntern(),
13369 .flags = .{ .address_space = ptr_as },
1337813370 });
1337913371
1338013372 var elem_i: usize = 0;
......@@ -13426,21 +13418,24 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1342613418 .Array => return operand_ty.arrayInfo(mod),
1342713419 .Pointer => {
1342813420 const ptr_info = operand_ty.ptrInfo(mod);
13429 switch (ptr_info.size) {
13421 switch (ptr_info.flags.size) {
1343013422 // TODO: in the Many case here this should only work if the type
1343113423 // has a sentinel, and this code should compute the length based
1343213424 // on the sentinel value.
1343313425 .Slice, .Many => {
1343413426 const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime-known");
1343513427 return Type.ArrayInfo{
13436 .elem_type = ptr_info.pointee_type,
13437 .sentinel = ptr_info.sentinel,
13428 .elem_type = ptr_info.child.toType(),
13429 .sentinel = switch (ptr_info.sentinel) {
13430 .none => null,
13431 else => ptr_info.sentinel.toValue(),
13432 },
1343813433 .len = val.sliceLen(mod),
1343913434 };
1344013435 },
1344113436 .One => {
13442 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
13443 return ptr_info.pointee_type.arrayInfo(mod);
13437 if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
13438 return ptr_info.child.toType().arrayInfo(mod);
1344413439 }
1344513440 },
1344613441 .C => {},
......@@ -13576,7 +13571,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1357613571 return sema.fail(block, rhs_src, "operation results in overflow", .{});
1357713572 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
1358113580 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;
1358213581 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
1361913618 try sema.requireRuntimeBlock(block, src, lhs_src);
1362013619
1362113620 if (ptr_addrspace) |ptr_as| {
13622 const alloc_ty = try Type.ptr(sema.arena, mod, .{
13623 .pointee_type = result_ty,
13624 .@"addrspace" = ptr_as,
13621 const alloc_ty = try mod.ptrType(.{
13622 .child = result_ty.toIntern(),
13623 .flags = .{ .address_space = ptr_as },
1362513624 });
1362613625 const alloc = try block.addTy(.alloc, alloc_ty);
13627 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
13628 .pointee_type = lhs_info.elem_type,
13629 .@"addrspace" = ptr_as,
13626 const elem_ptr_ty = try mod.ptrType(.{
13627 .child = lhs_info.elem_type.toIntern(),
13628 .flags = .{ .address_space = ptr_as },
1363013629 });
1363113630
1363213631 var elem_i: usize = 0;
......@@ -15582,18 +15581,18 @@ fn analyzePtrArithmetic(
1558215581 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
1558315582 const ptr_ty = sema.typeOf(ptr);
1558415583 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
1558715586 const new_ptr_ty = t: {
1558815587 // Calculate the new pointer alignment.
1558915588 // This code is duplicated in `elemPtrType`.
15590 if (ptr_info.@"align" == 0) {
15589 if (ptr_info.flags.alignment == .none) {
1559115590 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
1559215591 break :t ptr_ty;
1559315592 }
1559415593 // If the addend is not a comptime-known value we can still count on
1559515594 // 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);
1559715596 const addend = if (opt_off_val) |off_val| a: {
1559815597 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod));
1559915598 break :a elem_size * off_int;
......@@ -15602,17 +15601,23 @@ fn analyzePtrArithmetic(
1560215601 // The resulting pointer is aligned to the lcd between the offset (an
1560315602 // arbitrary number) and the alignment factor (always a power of two,
1560415603 // 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, .{
15608 .pointee_type = ptr_info.pointee_type,
15610 break :t try mod.ptrType(.{
15611 .child = ptr_info.child,
1560915612 .sentinel = ptr_info.sentinel,
15610 .@"align" = new_align,
15611 .@"addrspace" = ptr_info.@"addrspace",
15612 .mutable = ptr_info.mutable,
15613 .@"allowzero" = ptr_info.@"allowzero",
15614 .@"volatile" = ptr_info.@"volatile",
15615 .size = ptr_info.size,
15613 .flags = .{
15614 .size = ptr_info.flags.size,
15615 .alignment = new_align,
15616 .is_const = ptr_info.flags.is_const,
15617 .is_volatile = ptr_info.flags.is_volatile,
15618 .is_allowzero = ptr_info.flags.is_allowzero,
15619 .address_space = ptr_info.flags.address_space,
15620 },
1561615621 });
1561715622 };
1561815623
......@@ -15624,7 +15629,7 @@ fn analyzePtrArithmetic(
1562415629 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));
1562515630 if (offset_int == 0) return ptr;
1562615631 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);
1562815633 const new_addr = switch (air_tag) {
1562915634 .ptr_add => addr + elem_size * offset_int,
1563015635 .ptr_sub => addr - elem_size * offset_int,
......@@ -16363,8 +16368,8 @@ fn zirBuiltinSrc(
1636316368 const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));
1636416369 const new_decl_ty = try mod.arrayType(.{
1636516370 .len = name.len,
16366 .child = .u8_type,
1636716371 .sentinel = .zero_u8,
16372 .child = .u8_type,
1636816373 });
1636916374 const new_decl = try anon_decl.finish(
1637016375 new_decl_ty,
......@@ -16372,7 +16377,7 @@ fn zirBuiltinSrc(
1637216377 .ty = new_decl_ty.toIntern(),
1637316378 .storage = .{ .bytes = name },
1637416379 } })).toValue(),
16375 0, // default alignment
16380 .none, // default alignment
1637616381 );
1637716382 break :blk try mod.intern(.{ .ptr = .{
1637816383 .ty = .slice_const_u8_sentinel_0_type,
......@@ -16388,8 +16393,8 @@ fn zirBuiltinSrc(
1638816393 const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
1638916394 const new_decl_ty = try mod.arrayType(.{
1639016395 .len = name.len,
16391 .child = .u8_type,
1639216396 .sentinel = .zero_u8,
16397 .child = .u8_type,
1639316398 });
1639416399 const new_decl = try anon_decl.finish(
1639516400 new_decl_ty,
......@@ -16397,7 +16402,7 @@ fn zirBuiltinSrc(
1639716402 .ty = new_decl_ty.toIntern(),
1639816403 .storage = .{ .bytes = name },
1639916404 } })).toValue(),
16400 0, // default alignment
16405 .none, // default alignment
1640116406 );
1640216407 break :blk try mod.intern(.{ .ptr = .{
1640316408 .ty = .slice_const_u8_sentinel_0_type,
......@@ -16518,7 +16523,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1651816523 .ty = new_decl_ty.toIntern(),
1651916524 .storage = .{ .elems = param_vals },
1652016525 } })).toValue(),
16521 0, // default alignment
16526 .none, // default alignment
1652216527 );
1652316528 break :v try mod.intern(.{ .ptr = .{
1652416529 .ty = (try mod.ptrType(.{
......@@ -16620,10 +16625,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1662016625 },
1662116626 .Pointer => {
1662216627 const info = ty.ptrInfo(mod);
16623 const alignment = if (info.@"align" != 0)
16624 try mod.intValue(Type.comptime_int, info.@"align")
16628 const alignment = if (info.flags.alignment.toByteUnitsOptional()) |alignment|
16629 try mod.intValue(Type.comptime_int, alignment)
1662516630 else
16626 try info.pointee_type.lazyAbiAlignment(mod);
16631 try info.child.toType().lazyAbiAlignment(mod);
1662716632
1662816633 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
1662916634 const pointer_ty = t: {
......@@ -16653,21 +16658,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1665316658
1665416659 const field_values = .{
1665516660 // 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),
1665716662 // is_const: bool,
16658 Value.makeBool(!info.mutable).toIntern(),
16663 Value.makeBool(info.flags.is_const).toIntern(),
1665916664 // is_volatile: bool,
16660 Value.makeBool(info.@"volatile").toIntern(),
16665 Value.makeBool(info.flags.is_volatile).toIntern(),
1666116666 // alignment: comptime_int,
1666216667 alignment.toIntern(),
1666316668 // 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),
1666516670 // child: type,
16666 info.pointee_type.toIntern(),
16671 info.child,
1666716672 // is_allowzero: bool,
16668 Value.makeBool(info.@"allowzero").toIntern(),
16673 Value.makeBool(info.flags.is_allowzero).toIntern(),
1666916674 // 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(),
1667116679 };
1667216680 return sema.addConstant(type_info_ty, (try mod.intern(.{ .un = .{
1667316681 .ty = type_info_ty.toIntern(),
......@@ -16811,7 +16819,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1681116819 .ty = new_decl_ty.toIntern(),
1681216820 .storage = .{ .bytes = name },
1681316821 } })).toValue(),
16814 0, // default alignment
16822 .none, // default alignment
1681516823 );
1681616824 break :v try mod.intern(.{ .ptr = .{
1681716825 .ty = .slice_const_u8_type,
......@@ -16846,7 +16854,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1684616854 const array_errors_ty = try mod.arrayType(.{
1684716855 .len = vals.len,
1684816856 .child = error_field_ty.toIntern(),
16849 .sentinel = .none,
1685016857 });
1685116858 const new_decl = try fields_anon_decl.finish(
1685216859 array_errors_ty,
......@@ -16854,7 +16861,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1685416861 .ty = array_errors_ty.toIntern(),
1685516862 .storage = .{ .elems = vals },
1685616863 } })).toValue(),
16857 0, // default alignment
16864 .none, // default alignment
1685816865 );
1685916866 break :v try mod.intern(.{ .ptr = .{
1686016867 .ty = slice_errors_ty.toIntern(),
......@@ -16948,7 +16955,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1694816955 .ty = new_decl_ty.toIntern(),
1694916956 .storage = .{ .bytes = name },
1695016957 } })).toValue(),
16951 0, // default alignment
16958 .none, // default alignment
1695216959 );
1695316960 break :v try mod.intern(.{ .ptr = .{
1695416961 .ty = .slice_const_u8_type,
......@@ -16973,7 +16980,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1697316980 const fields_array_ty = try mod.arrayType(.{
1697416981 .len = enum_field_vals.len,
1697516982 .child = enum_field_ty.toIntern(),
16976 .sentinel = .none,
1697716983 });
1697816984 const new_decl = try fields_anon_decl.finish(
1697916985 fields_array_ty,
......@@ -16981,7 +16987,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1698116987 .ty = fields_array_ty.toIntern(),
1698216988 .storage = .{ .elems = enum_field_vals },
1698316989 } })).toValue(),
16984 0, // default alignment
16990 .none, // default alignment
1698516991 );
1698616992 break :v try mod.intern(.{ .ptr = .{
1698716993 .ty = (try mod.ptrType(.{
......@@ -17087,7 +17093,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1708717093 .ty = new_decl_ty.toIntern(),
1708817094 .storage = .{ .bytes = name },
1708917095 } })).toValue(),
17090 0, // default alignment
17096 .none, // default alignment
1709117097 );
1709217098 break :v try mod.intern(.{ .ptr = .{
1709317099 .ty = .slice_const_u8_type,
......@@ -17119,7 +17125,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1711917125 const array_fields_ty = try mod.arrayType(.{
1712017126 .len = union_field_vals.len,
1712117127 .child = union_field_ty.toIntern(),
17122 .sentinel = .none,
1712317128 });
1712417129 const new_decl = try fields_anon_decl.finish(
1712517130 array_fields_ty,
......@@ -17127,7 +17132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1712717132 .ty = array_fields_ty.toIntern(),
1712817133 .storage = .{ .elems = union_field_vals },
1712917134 } })).toValue(),
17130 0, // default alignment
17135 .none, // default alignment
1713117136 );
1713217137 break :v try mod.intern(.{ .ptr = .{
1713317138 .ty = (try mod.ptrType(.{
......@@ -17247,7 +17252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1724717252 .ty = new_decl_ty.toIntern(),
1724817253 .storage = .{ .bytes = bytes },
1724917254 } })).toValue(),
17250 0, // default alignment
17255 .none, // default alignment
1725117256 );
1725217257 break :v try mod.intern(.{ .ptr = .{
1725317258 .ty = .slice_const_u8_type,
......@@ -17304,7 +17309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1730417309 .ty = new_decl_ty.toIntern(),
1730517310 .storage = .{ .bytes = name },
1730617311 } })).toValue(),
17307 0, // default alignment
17312 .none, // default alignment
1730817313 );
1730917314 break :v try mod.intern(.{ .ptr = .{
1731017315 .ty = .slice_const_u8_type,
......@@ -17343,7 +17348,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1734317348 const array_fields_ty = try mod.arrayType(.{
1734417349 .len = struct_field_vals.len,
1734517350 .child = struct_field_ty.toIntern(),
17346 .sentinel = .none,
1734717351 });
1734817352 const new_decl = try fields_anon_decl.finish(
1734917353 array_fields_ty,
......@@ -17351,7 +17355,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1735117355 .ty = array_fields_ty.toIntern(),
1735217356 .storage = .{ .elems = struct_field_vals },
1735317357 } })).toValue(),
17354 0, // default alignment
17358 .none, // default alignment
1735517359 );
1735617360 break :v try mod.intern(.{ .ptr = .{
1735717361 .ty = (try mod.ptrType(.{
......@@ -17490,7 +17494,6 @@ fn typeInfoDecls(
1749017494 const array_decl_ty = try mod.arrayType(.{
1749117495 .len = decl_vals.items.len,
1749217496 .child = declaration_ty.toIntern(),
17493 .sentinel = .none,
1749417497 });
1749517498 const new_decl = try decls_anon_decl.finish(
1749617499 array_decl_ty,
......@@ -17498,7 +17501,7 @@ fn typeInfoDecls(
1749817501 .ty = array_decl_ty.toIntern(),
1749917502 .storage = .{ .elems = decl_vals.items },
1750017503 } })).toValue(),
17501 0, // default alignment
17504 .none, // default alignment
1750217505 );
1750317506 return try mod.intern(.{ .ptr = .{
1750417507 .ty = (try mod.ptrType(.{
......@@ -17551,7 +17554,7 @@ fn typeInfoNamespaceDecls(
1755117554 .ty = new_decl_ty.toIntern(),
1755217555 .storage = .{ .bytes = name },
1755317556 } })).toValue(),
17554 0, // default alignment
17557 .none, // default alignment
1755517558 );
1755617559 break :v try mod.intern(.{ .ptr = .{
1755717560 .ty = .slice_const_u8_type,
......@@ -18076,12 +18079,14 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1807618079
1807718080 const operand_ty = sema.typeOf(operand);
1807818081 const ptr_info = operand_ty.ptrInfo(mod);
18079 const res_ty = try Type.ptr(sema.arena, mod, .{
18080 .pointee_type = err_union_ty.errorUnionPayload(mod),
18081 .@"addrspace" = ptr_info.@"addrspace",
18082 .mutable = ptr_info.mutable,
18083 .@"allowzero" = ptr_info.@"allowzero",
18084 .@"volatile" = ptr_info.@"volatile",
18082 const res_ty = try mod.ptrType(.{
18083 .child = err_union_ty.errorUnionPayload(mod).toIntern(),
18084 .flags = .{
18085 .is_const = ptr_info.flags.is_const,
18086 .is_volatile = ptr_info.flags.is_volatile,
18087 .is_allowzero = ptr_info.flags.is_allowzero,
18088 .address_space = ptr_info.flags.address_space,
18089 },
1808518090 });
1808618091 const res_ty_ref = try sema.addType(res_ty);
1808718092 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
1850118506 break :blk val.toIntern();
1850218507 } 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: {
1850518510 const ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_i]);
1850618511 extra_i += 1;
1850718512 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
1851718522 }
1851818523 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);
1851918524 try sema.validateAlign(block, align_src, abi_align);
18520 break :blk InternPool.Alignment.fromByteUnits(abi_align);
18525 break :blk Alignment.fromByteUnits(abi_align);
1852118526 } else .none;
1852218527
1852318528 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {
......@@ -18794,9 +18799,9 @@ fn zirStructInit(
1879418799
1879518800 if (is_ref) {
1879618801 const target = mod.getTarget();
18797 const alloc_ty = try Type.ptr(sema.arena, mod, .{
18798 .pointee_type = resolved_ty,
18799 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
18802 const alloc_ty = try mod.ptrType(.{
18803 .child = resolved_ty.toIntern(),
18804 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1880018805 });
1880118806 const alloc = try block.addTy(.alloc, alloc_ty);
1880218807 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty, true);
......@@ -18917,9 +18922,9 @@ fn finishStructInit(
1891718922 if (is_ref) {
1891818923 try sema.resolveStructLayout(struct_ty);
1891918924 const target = sema.mod.getTarget();
18920 const alloc_ty = try Type.ptr(sema.arena, mod, .{
18921 .pointee_type = struct_ty,
18922 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
18925 const alloc_ty = try mod.ptrType(.{
18926 .child = struct_ty.toIntern(),
18927 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1892318928 });
1892418929 const alloc = try block.addTy(.alloc, alloc_ty);
1892518930 for (field_inits, 0..) |field_init, i_usize| {
......@@ -19038,9 +19043,9 @@ fn zirStructInitAnon(
1903819043
1903919044 if (is_ref) {
1904019045 const target = mod.getTarget();
19041 const alloc_ty = try Type.ptr(sema.arena, mod, .{
19042 .pointee_type = tuple_ty.toType(),
19043 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19046 const alloc_ty = try mod.ptrType(.{
19047 .child = tuple_ty,
19048 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1904419049 });
1904519050 const alloc = try block.addTy(.alloc, alloc_ty);
1904619051 var extra_index = extra.end;
......@@ -19049,10 +19054,9 @@ fn zirStructInitAnon(
1904919054 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);
1905019055 extra_index = item.end;
1905119056
19052 const field_ptr_ty = try Type.ptr(sema.arena, mod, .{
19053 .mutable = true,
19054 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19055 .pointee_type = field_ty.toType(),
19057 const field_ptr_ty = try mod.ptrType(.{
19058 .child = field_ty,
19059 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1905619060 });
1905719061 if (values[i] == .none) {
1905819062 const init = try sema.resolveInst(item.data.init);
......@@ -19150,18 +19154,17 @@ fn zirArrayInit(
1915019154
1915119155 if (is_ref) {
1915219156 const target = mod.getTarget();
19153 const alloc_ty = try Type.ptr(sema.arena, mod, .{
19154 .pointee_type = array_ty,
19155 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19157 const alloc_ty = try mod.ptrType(.{
19158 .child = array_ty.toIntern(),
19159 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1915619160 });
1915719161 const alloc = try block.addTy(.alloc, alloc_ty);
1915819162
1915919163 if (array_ty.isTuple(mod)) {
1916019164 for (resolved_args, 0..) |arg, i| {
19161 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
19162 .mutable = true,
19163 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19164 .pointee_type = array_ty.structFieldType(i, mod),
19165 const elem_ptr_ty = try mod.ptrType(.{
19166 .child = array_ty.structFieldType(i, mod).toIntern(),
19167 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1916519168 });
1916619169 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1916719170
......@@ -19172,10 +19175,9 @@ fn zirArrayInit(
1917219175 return sema.makePtrConst(block, alloc);
1917319176 }
1917419177
19175 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
19176 .mutable = true,
19177 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19178 .pointee_type = array_ty.elemType2(mod),
19178 const elem_ptr_ty = try mod.ptrType(.{
19179 .child = array_ty.elemType2(mod).toIntern(),
19180 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1917919181 });
1918019182 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1918119183
......@@ -19249,17 +19251,16 @@ fn zirArrayInitAnon(
1924919251
1925019252 if (is_ref) {
1925119253 const target = sema.mod.getTarget();
19252 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
19253 .pointee_type = tuple_ty.toType(),
19254 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19254 const alloc_ty = try mod.ptrType(.{
19255 .child = tuple_ty,
19256 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1925519257 });
1925619258 const alloc = try block.addTy(.alloc, alloc_ty);
1925719259 for (operands, 0..) |operand, i_usize| {
1925819260 const i = @intCast(u32, i_usize);
19259 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
19260 .mutable = true,
19261 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19262 .pointee_type = types[i].toType(),
19261 const field_ptr_ty = try mod.ptrType(.{
19262 .child = types[i],
19263 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1926319264 });
1926419265 if (values[i] == .none) {
1926519266 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);
......@@ -19292,7 +19293,7 @@ fn addConstantMaybeRef(
1929219293 const decl = try anon_decl.finish(
1929319294 ty,
1929419295 val,
19295 0, // default alignment
19296 .none, // default alignment
1929619297 );
1929719298 return sema.analyzeDeclRef(decl);
1929819299}
......@@ -19387,7 +19388,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
1938719388 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
1938819389 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
1938919390 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
1939219393 if (sema.owner_func != null and
1939319394 sema.owner_func.?.calls_or_awaits_errorable_fn and
......@@ -19707,7 +19708,7 @@ fn zirReify(
1970719708 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
1970819709 }
1970919710
19710 const abi_align = InternPool.Alignment.fromByteUnits(
19711 const abi_align = Alignment.fromByteUnits(
1971119712 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,
1971219713 );
1971319714
......@@ -19728,10 +19729,7 @@ fn zirReify(
1972819729 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
1972919730 }
1973019731 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;
19731 const ptr_ty = try Type.ptr(sema.arena, mod, .{
19732 .@"addrspace" = .generic,
19733 .pointee_type = elem_ty,
19734 });
19732 const ptr_ty = try mod.singleMutPtrType(elem_ty);
1973519733 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
1973619734 break :s sent_val.toIntern();
1973719735 }
......@@ -19800,14 +19798,15 @@ fn zirReify(
1980019798 const len = len_val.toUnsignedInt(mod);
1980119799 const child_ty = child_val.toType();
1980219800 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
19803 const ptr_ty = try Type.ptr(sema.arena, mod, .{
19804 .@"addrspace" = .generic,
19805 .pointee_type = child_ty,
19806 });
19801 const ptr_ty = try mod.singleMutPtrType(child_ty);
1980719802 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;
1980819803 } 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 });
1981119810 return sema.addType(ty);
1981219811 },
1981319812 .Optional => {
......@@ -19818,7 +19817,7 @@ fn zirReify(
1981819817
1981919818 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());
1982219821 return sema.addType(ty);
1982319822 },
1982419823 .ErrorUnion => {
......@@ -20199,7 +20198,7 @@ fn zirReify(
2019920198 const field_ty = type_val.toType();
2020020199 gop.value_ptr.* = .{
2020120200 .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)).?),
2020320202 };
2020420203
2020520204 if (field_ty.zigTypeTag(mod) == .Opaque) {
......@@ -20306,7 +20305,7 @@ fn zirReify(
2030620305 if (alignment == target_util.defaultFunctionAlignment(target)) {
2030720306 break :alignment .none;
2030820307 } else {
20309 break :alignment InternPool.Alignment.fromByteUnits(alignment);
20308 break :alignment Alignment.fromByteUnits(alignment);
2031020309 }
2031120310 };
2031220311 const return_type = return_type_val.optionalValue(mod) orelse
......@@ -20455,7 +20454,7 @@ fn reifyStruct(
2045520454 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
2045620455 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
2045720456 }
20458 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?);
20457 const abi_align = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
2045920458
2046020459 if (layout == .Packed) {
2046120460 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(
2050220501
2050320502 gop.value_ptr.* = .{
2050420503 .ty = field_ty,
20505 .abi_align = abi_align,
20504 .abi_align = Alignment.fromByteUnits(abi_align),
2050620505 .default_val = default_val,
2050720506 .is_comptime = is_comptime_val.toBool(),
2050820507 .offset = undefined,
......@@ -20604,7 +20603,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2060420603 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
2060520604
2060620605 var ptr_info = ptr_ty.ptrInfo(mod);
20607 const src_addrspace = ptr_info.@"addrspace";
20606 const src_addrspace = ptr_info.flags.address_space;
2060820607 if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) {
2060920608 const msg = msg: {
2061020609 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
2061520614 return sema.failWithOwnedErrorMsg(msg);
2061620615 }
2061720616
20618 ptr_info.@"addrspace" = dest_addrspace;
20619 const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
20617 ptr_info.flags.address_space = dest_addrspace;
20618 const dest_ptr_ty = try mod.ptrType(ptr_info);
2062020619 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())
2062220621 else
2062320622 dest_ptr_ty;
2062420623
......@@ -20636,11 +20635,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2063620635
2063720636fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
2063820637 const va_list_ty = try sema.getBuiltinType("VaList");
20639 const va_list_ptr = try Type.ptr(sema.arena, sema.mod, .{
20640 .pointee_type = va_list_ty,
20641 .mutable = true,
20642 .@"addrspace" = .generic,
20643 });
20638 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);
2064420639
2064520640 const inst = try sema.resolveInst(zir_ref);
2064620641 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
2071720712 var anon_decl = try block.startAnonDecl();
2071820713 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
2072220719 const decl_ty = try mod.arrayType(.{
20723 .len = bytes.len,
20724 .child = .u8_type,
20720 .len = bytes.items.len,
2072520721 .sentinel = .zero_u8,
20722 .child = .u8_type,
2072620723 });
2072720724 const new_decl = try anon_decl.finish(
2072820725 decl_ty,
2072920726 (try mod.intern(.{ .aggregate = .{
2073020727 .ty = decl_ty.toIntern(),
20731 .storage = .{ .bytes = bytes },
20728 .storage = .{ .bytes = bytes.items },
2073220729 } })).toValue(),
20733 0, // default alignment
20730 .none, // default alignment
2073420731 );
2073520732
2073620733 return sema.analyzeDeclRef(new_decl);
......@@ -20981,7 +20978,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2098120978
2098220979 const operand_info = operand_ty.ptrInfo(mod);
2098320980 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) {
2098520982 const msg = msg: {
2098620983 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});
2098720984 errdefer msg.destroy(sema.gpa);
......@@ -20991,7 +20988,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2099120988 };
2099220989 return sema.failWithOwnedErrorMsg(msg);
2099320990 }
20994 if (operand_info.@"volatile" and !dest_info.@"volatile") {
20991 if (operand_info.flags.is_volatile and !dest_info.flags.is_volatile) {
2099520992 const msg = msg: {
2099620993 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});
2099720994 errdefer msg.destroy(sema.gpa);
......@@ -21001,7 +20998,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2100120998 };
2100220999 return sema.failWithOwnedErrorMsg(msg);
2100321000 }
21004 if (operand_info.@"addrspace" != dest_info.@"addrspace") {
21001 if (operand_info.flags.address_space != dest_info.flags.address_space) {
2100521002 const msg = msg: {
2100621003 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
2100721004 errdefer msg.destroy(sema.gpa);
......@@ -21033,14 +21030,12 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2103321030 // If the destination is less aligned than the source, preserve the source alignment
2103421031 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
2103521032 // 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);
2103621035 if (dest_ty.zigTypeTag(mod) == .Optional) {
21037 var dest_ptr_info = dest_ty.optionalChild(mod).ptrInfo(mod);
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);
21036 break :blk try mod.optionalType((try mod.ptrType(dest_ptr_info)).toIntern());
2104021037 } else {
21041 var dest_ptr_info = dest_ty.ptrInfo(mod);
21042 dest_ptr_info.@"align" = operand_align;
21043 break :blk try Type.ptr(sema.arena, mod, dest_ptr_info);
21038 break :blk try mod.ptrType(dest_ptr_info);
2104421039 }
2104521040 };
2104621041
......@@ -21107,8 +21102,8 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2110721102 try sema.checkPtrOperand(block, operand_src, operand_ty);
2110821103
2110921104 var ptr_info = operand_ty.ptrInfo(mod);
21110 ptr_info.mutable = true;
21111 const dest_ty = try Type.ptr(sema.arena, mod, ptr_info);
21105 ptr_info.flags.is_const = false;
21106 const dest_ty = try mod.ptrType(ptr_info);
2111221107
2111321108 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
2111421109 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
2112821123 try sema.checkPtrOperand(block, operand_src, operand_ty);
2112921124
2113021125 var ptr_info = operand_ty.ptrInfo(mod);
21131 ptr_info.@"volatile" = false;
21132 const dest_ty = try Type.ptr(sema.arena, mod, ptr_info);
21126 ptr_info.flags.is_volatile = false;
21127 const dest_ty = try mod.ptrType(ptr_info);
2113321128
2113421129 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
2113521130 return sema.addConstant(dest_ty, operand_val);
......@@ -21238,28 +21233,29 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2123821233 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
2123921234
2124021235 var ptr_info = ptr_ty.ptrInfo(mod);
21241 ptr_info.@"align" = dest_align;
21242 var dest_ty = try Type.ptr(sema.arena, mod, ptr_info);
21236 ptr_info.flags.alignment = dest_align;
21237 var dest_ty = try mod.ptrType(ptr_info);
2124321238 if (ptr_ty.zigTypeTag(mod) == .Optional) {
2124421239 dest_ty = try mod.optionalType(dest_ty.toIntern());
2124521240 }
2124621241
2124721242 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {
2124821243 if (try val.getUnsignedIntAdvanced(mod, null)) |addr| {
21249 if (addr % dest_align != 0) {
21250 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });
21244 const dest_align_bytes = dest_align.toByteUnitsOptional().?;
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 });
2125121247 }
2125221248 }
2125321249 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
2125421250 }
2125521251
2125621252 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
21257 if (block.wantSafety() and dest_align > 1 and
21258 try sema.typeHasRuntimeBits(ptr_info.pointee_type))
21253 if (block.wantSafety() and dest_align.order(Alignment.fromNonzeroByteUnits(1)).compare(.gt) and
21254 try sema.typeHasRuntimeBits(ptr_info.child.toType()))
2125921255 {
2126021256 const align_minus_1 = try sema.addConstant(
2126121257 Type.usize,
21262 try mod.intValue(Type.usize, dest_align - 1),
21258 try mod.intValue(Type.usize, dest_align.toByteUnitsOptional().? - 1),
2126321259 );
2126421260 const actual_ptr = if (ptr_ty.isSlice(mod))
2126521261 try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)
......@@ -21704,28 +21700,29 @@ fn checkAtomicPtrOperand(
2170421700 ),
2170521701 };
2170621702
21707 var wanted_ptr_data: Type.Payload.Pointer.Data = .{
21708 .pointee_type = elem_ty,
21709 .@"align" = alignment,
21710 .@"addrspace" = .generic,
21711 .mutable = !ptr_const,
21703 var wanted_ptr_data: InternPool.Key.PtrType = .{
21704 .child = elem_ty.toIntern(),
21705 .flags = .{
21706 .alignment = alignment,
21707 .is_const = ptr_const,
21708 },
2171221709 };
2171321710
2171421711 const ptr_ty = sema.typeOf(ptr);
2171521712 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
2171621713 .Pointer => ptr_ty.ptrInfo(mod),
2171721714 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);
2171921716 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2172021717 unreachable;
2172121718 },
2172221719 };
2172321720
21724 wanted_ptr_data.@"addrspace" = ptr_data.@"addrspace";
21725 wanted_ptr_data.@"allowzero" = ptr_data.@"allowzero";
21726 wanted_ptr_data.@"volatile" = ptr_data.@"volatile";
21721 wanted_ptr_data.flags.address_space = ptr_data.flags.address_space;
21722 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
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);
2172921726 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2173021727
2173121728 return casted_ptr;
......@@ -22078,7 +22075,7 @@ fn zirCmpxchg(
2207822075 return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{});
2207922076 }
2208022077
22081 const result_ty = try Type.optional(sema.arena, elem_ty, mod);
22078 const result_ty = try mod.optionalType(elem_ty.toIntern());
2208222079
2208322080 // special case zero bit types
2208422081 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {
......@@ -22844,31 +22841,33 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2284422841 try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);
2284522842 const field_ptr_ty_info = field_ptr_ty.ptrInfo(mod);
2284622843
22847 var ptr_ty_data: Type.Payload.Pointer.Data = .{
22848 .pointee_type = parent_ty.structFieldType(field_index, mod),
22849 .mutable = field_ptr_ty_info.mutable,
22850 .@"addrspace" = field_ptr_ty_info.@"addrspace",
22844 var ptr_ty_data: InternPool.Key.PtrType = .{
22845 .child = parent_ty.structFieldType(field_index, mod).toIntern(),
22846 .flags = .{
22847 .address_space = field_ptr_ty_info.flags.address_space,
22848 .is_const = field_ptr_ty_info.flags.is_const,
22849 },
2285122850 };
2285222851
2285322852 if (parent_ty.containerLayout(mod) == .Packed) {
2285422853 return sema.fail(block, src, "TODO handle packed structs/unions with @fieldParentPtr", .{});
2285522854 } else {
22856 ptr_ty_data.@"align" = blk: {
22855 ptr_ty_data.flags.alignment = blk: {
2285722856 if (mod.typeToStruct(parent_ty)) |struct_obj| {
2285822857 break :blk struct_obj.fields.values()[field_index].abi_align;
2285922858 } else if (mod.typeToUnion(parent_ty)) |union_obj| {
2286022859 break :blk union_obj.fields.values()[field_index].abi_align;
2286122860 } else {
22862 break :blk 0;
22861 break :blk .none;
2286322862 }
2286422863 };
2286522864 }
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);
2286822867 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;
22871 const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
22869 ptr_ty_data.child = parent_ty.toIntern();
22870 const result_ptr = try mod.ptrType(ptr_ty_data);
2287222871
2287322872 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
2287422873 const field = switch (ip.indexToKey(field_ptr_val.toIntern())) {
......@@ -23191,21 +23190,25 @@ fn analyzeMinMax(
2319123190fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {
2319223191 const mod = sema.mod;
2319323192 const info = sema.typeOf(ptr).ptrInfo(mod);
23194 if (info.size == .One) {
23193 if (info.flags.size == .One) {
2319523194 // Already an array pointer.
2319623195 return ptr;
2319723196 }
23198 const new_ty = try Type.ptr(sema.arena, mod, .{
23199 .pointee_type = try Type.array(sema.arena, len, info.sentinel, info.pointee_type, mod),
23200 .sentinel = null,
23201 .@"align" = info.@"align",
23202 .@"addrspace" = info.@"addrspace",
23203 .mutable = info.mutable,
23204 .@"allowzero" = info.@"allowzero",
23205 .@"volatile" = info.@"volatile",
23206 .size = .One,
23197 const new_ty = try mod.ptrType(.{
23198 .child = (try mod.arrayType(.{
23199 .len = len,
23200 .sentinel = info.sentinel,
23201 .child = info.child,
23202 })).toIntern(),
23203 .flags = .{
23204 .alignment = info.flags.alignment,
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 },
2320723210 });
23208 if (info.size == .Slice) {
23211 if (info.flags.size == .Slice) {
2320923212 return block.addTyOp(.slice_ptr, new_ty, ptr);
2321023213 }
2321123214 return block.addBitCast(new_ty, ptr);
......@@ -23623,7 +23626,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2362323626 return sema.fail(block, align_src, "target does not support function alignment", .{});
2362423627 }
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: {
2362723630 const body_len = sema.code.extra[extra_index];
2362823631 extra_index += 1;
2362923632 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
2363623639 const alignment = @intCast(u32, val.toUnsignedInt(mod));
2363723640 try sema.validateAlign(block, align_src, alignment);
2363823641 if (alignment == target_util.defaultFunctionAlignment(target)) {
23639 break :blk 0;
23642 break :blk .none;
2364023643 } else {
23641 break :blk alignment;
23644 break :blk Alignment.fromNonzeroByteUnits(alignment);
2364223645 }
2364323646 } else if (extra.data.bits.has_align_ref) blk: {
2364423647 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
2365223655 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod));
2365323656 try sema.validateAlign(block, align_src, alignment);
2365423657 if (alignment == target_util.defaultFunctionAlignment(target)) {
23655 break :blk 0;
23658 break :blk .none;
2365623659 } else {
23657 break :blk alignment;
23660 break :blk Alignment.fromNonzeroByteUnits(alignment);
2365823661 }
23659 } else 0;
23662 } else .none;
2366023663
2366123664 const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: {
2366223665 const body_len = sema.code.extra[extra_index];
......@@ -24051,7 +24054,7 @@ fn zirBuiltinExtern(
2405124054 };
2405224055
2405324056 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {
24054 ty = try Type.optional(sema.arena, ty, mod);
24057 ty = try mod.optionalType(ty.toIntern());
2405524058 }
2405624059
2405724060 // TODO check duplicate extern
......@@ -24077,7 +24080,7 @@ fn zirBuiltinExtern(
2407724080 // below, so this type doesn't matter
2407824081 new_decl.ty = ty;
2407924082 new_decl.val = new_var.toValue();
24080 new_decl.@"align" = 0;
24083 new_decl.alignment = .none;
2408124084 new_decl.@"linksection" = .none;
2408224085 new_decl.has_tv = true;
2408324086 new_decl.analysis = .complete;
......@@ -24967,18 +24970,19 @@ fn fieldVal(
2496724970 );
2496824971 } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {
2496924972 const ptr_info = object_ty.ptrInfo(mod);
24970 const result_ty = try Type.ptr(sema.arena, mod, .{
24971 .pointee_type = ptr_info.pointee_type.childType(mod),
24973 const result_ty = try mod.ptrType(.{
24974 .child = ptr_info.child.toType().childType(mod).toIntern(),
2497224975 .sentinel = ptr_info.sentinel,
24973 .@"align" = ptr_info.@"align",
24974 .@"addrspace" = ptr_info.@"addrspace",
24975 .bit_offset = ptr_info.bit_offset,
24976 .host_size = ptr_info.host_size,
24977 .vector_index = ptr_info.vector_index,
24978 .@"allowzero" = ptr_info.@"allowzero",
24979 .mutable = ptr_info.mutable,
24980 .@"volatile" = ptr_info.@"volatile",
24981 .size = .Many,
24976 .flags = .{
24977 .size = .Many,
24978 .alignment = ptr_info.flags.alignment,
24979 .is_const = ptr_info.flags.is_const,
24980 .is_volatile = ptr_info.flags.is_volatile,
24981 .is_allowzero = ptr_info.flags.is_allowzero,
24982 .address_space = ptr_info.flags.address_space,
24983 .vector_index = ptr_info.flags.vector_index,
24984 },
24985 .packed_offset = ptr_info.packed_offset,
2498224986 });
2498324987 return sema.coerce(block, result_ty, object, src);
2498424988 } else {
......@@ -24992,7 +24996,7 @@ fn fieldVal(
2499224996 },
2499324997 .Pointer => {
2499424998 const ptr_info = inner_ty.ptrInfo(mod);
24995 if (ptr_info.size == .Slice) {
24999 if (ptr_info.flags.size == .Slice) {
2499625000 if (ip.stringEqlSlice(field_name, "ptr")) {
2499725001 const slice = if (is_pointer_to)
2499825002 try sema.analyzeLoad(block, src, object, object_src)
......@@ -25166,7 +25170,7 @@ fn fieldPtr(
2516625170 return sema.analyzeDeclRef(try anon_decl.finish(
2516725171 Type.usize,
2516825172 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
25169 0, // default alignment
25173 .none, // default alignment
2517025174 ));
2517125175 } else {
2517225176 return sema.fail(
......@@ -25188,11 +25192,13 @@ fn fieldPtr(
2518825192 if (ip.stringEqlSlice(field_name, "ptr")) {
2518925193 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2519025194
25191 const result_ty = try Type.ptr(sema.arena, mod, .{
25192 .pointee_type = slice_ptr_ty,
25193 .mutable = attr_ptr_ty.ptrIsMutable(mod),
25194 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),
25195 .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),
25195 const result_ty = try mod.ptrType(.{
25196 .child = slice_ptr_ty.toIntern(),
25197 .flags = .{
25198 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
25199 .is_volatile = attr_ptr_ty.isVolatilePtr(mod),
25200 .address_space = attr_ptr_ty.ptrAddressSpace(mod),
25201 },
2519625202 });
2519725203
2519825204 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
......@@ -25208,11 +25214,13 @@ fn fieldPtr(
2520825214
2520925215 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
2521025216 } else if (ip.stringEqlSlice(field_name, "len")) {
25211 const result_ty = try Type.ptr(sema.arena, mod, .{
25212 .pointee_type = Type.usize,
25213 .mutable = attr_ptr_ty.ptrIsMutable(mod),
25214 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),
25215 .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),
25217 const result_ty = try mod.ptrType(.{
25218 .child = .usize_type,
25219 .flags = .{
25220 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
25221 .is_volatile = attr_ptr_ty.isVolatilePtr(mod),
25222 .address_space = attr_ptr_ty.ptrAddressSpace(mod),
25223 },
2521625224 });
2521725225
2521825226 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
......@@ -25280,7 +25288,7 @@ fn fieldPtr(
2528025288 .ty = error_set_type.toIntern(),
2528125289 .name = field_name,
2528225290 } })).toValue(),
25283 0, // default alignment
25291 .none, // default alignment
2528425292 ));
2528525293 },
2528625294 .Union => {
......@@ -25298,7 +25306,7 @@ fn fieldPtr(
2529825306 return sema.analyzeDeclRef(try anon_decl.finish(
2529925307 enum_ty,
2530025308 try mod.enumValueFieldIndex(enum_ty, field_index_u32),
25301 0, // default alignment
25309 .none, // default alignment
2530225310 ));
2530325311 }
2530425312 }
......@@ -25319,7 +25327,7 @@ fn fieldPtr(
2531925327 return sema.analyzeDeclRef(try anon_decl.finish(
2532025328 child_type,
2532125329 try mod.enumValueFieldIndex(child_type, field_index_u32),
25322 0, // default alignment
25330 .none, // default alignment
2532325331 ));
2532425332 },
2532525333 .Struct, .Opaque => {
......@@ -25533,11 +25541,12 @@ fn finishFieldCallBind(
2553325541 object_ptr: Air.Inst.Ref,
2553425542) CompileError!ResolvedFieldCallee {
2553525543 const mod = sema.mod;
25536 const arena = sema.arena;
25537 const ptr_field_ty = try Type.ptr(arena, mod, .{
25538 .pointee_type = field_ty,
25539 .mutable = ptr_ty.ptrIsMutable(mod),
25540 .@"addrspace" = ptr_ty.ptrAddressSpace(mod),
25544 const ptr_field_ty = try mod.ptrType(.{
25545 .child = field_ty.toIntern(),
25546 .flags = .{
25547 .is_const = !ptr_ty.ptrIsMutable(mod),
25548 .address_space = ptr_ty.ptrAddressSpace(mod),
25549 },
2554125550 });
2554225551
2554325552 const container_ty = ptr_ty.childType(mod);
......@@ -25670,11 +25679,13 @@ fn structFieldPtrByIndex(
2567025679 const struct_ptr_ty = sema.typeOf(struct_ptr);
2567125680 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);
2567225681
25673 var ptr_ty_data: Type.Payload.Pointer.Data = .{
25674 .pointee_type = field.ty,
25675 .mutable = struct_ptr_ty_info.mutable,
25676 .@"volatile" = struct_ptr_ty_info.@"volatile",
25677 .@"addrspace" = struct_ptr_ty_info.@"addrspace",
25682 var ptr_ty_data: InternPool.Key.PtrType = .{
25683 .child = field.ty.toIntern(),
25684 .flags = .{
25685 .is_const = struct_ptr_ty_info.flags.is_const,
25686 .is_volatile = struct_ptr_ty_info.flags.is_volatile,
25687 .address_space = struct_ptr_ty_info.flags.address_space,
25688 },
2567825689 };
2567925690
2568025691 const target = mod.getTarget();
......@@ -25687,24 +25698,22 @@ fn structFieldPtrByIndex(
2568725698 if (!(try sema.typeHasRuntimeBits(f.ty))) continue;
2568825699
2568925700 if (i == field_index) {
25690 ptr_ty_data.bit_offset = running_bits;
25701 ptr_ty_data.packed_offset.bit_offset = running_bits;
2569125702 }
2569225703 running_bits += @intCast(u16, f.ty.bitSize(mod));
2569325704 }
25694 ptr_ty_data.host_size = (running_bits + 7) / 8;
25705 ptr_ty_data.packed_offset.host_size = (running_bits + 7) / 8;
2569525706
2569625707 // If this is a packed struct embedded in another one, we need to offset
2569725708 // the bits against each other.
25698 if (struct_ptr_ty_info.host_size != 0) {
25699 ptr_ty_data.host_size = struct_ptr_ty_info.host_size;
25700 ptr_ty_data.bit_offset += struct_ptr_ty_info.bit_offset;
25709 if (struct_ptr_ty_info.packed_offset.host_size != 0) {
25710 ptr_ty_data.packed_offset.host_size = struct_ptr_ty_info.packed_offset.host_size;
25711 ptr_ty_data.packed_offset.bit_offset += struct_ptr_ty_info.packed_offset.bit_offset;
2570125712 }
2570225713
25703 const parent_align = if (struct_ptr_ty_info.@"align" != 0)
25704 struct_ptr_ty_info.@"align"
25705 else
25706 struct_ptr_ty_info.pointee_type.abiAlignment(mod);
25707 ptr_ty_data.@"align" = parent_align;
25714 const parent_align = struct_ptr_ty_info.flags.alignment.toByteUnitsOptional() orelse
25715 struct_ptr_ty_info.child.toType().abiAlignment(mod);
25716 ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align);
2570825717
2570925718 // If the field happens to be byte-aligned, simplify the pointer type.
2571025719 // The pointee type bit size must match its ABI byte size so that loads and stores
......@@ -25714,24 +25723,24 @@ fn structFieldPtrByIndex(
2571425723 // targets before adding the necessary complications to this code. This will not
2571525724 // cause miscompilations; it only means the field pointer uses bit masking when it
2571625725 // might not be strictly necessary.
25717 if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0 and
25726 if (parent_align != 0 and ptr_ty_data.packed_offset.bit_offset % 8 == 0 and
2571825727 target.cpu.arch.endian() == .Little)
2571925728 {
25720 const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(mod);
25721 const elem_size_bits = ptr_ty_data.pointee_type.bitSize(mod);
25729 const elem_size_bytes = ptr_ty_data.child.toType().abiSize(mod);
25730 const elem_size_bits = ptr_ty_data.child.toType().bitSize(mod);
2572225731 if (elem_size_bytes * 8 == elem_size_bits) {
25723 const byte_offset = ptr_ty_data.bit_offset / 8;
25724 const new_align = @as(u32, 1) << @intCast(u5, @ctz(byte_offset | parent_align));
25725 ptr_ty_data.bit_offset = 0;
25726 ptr_ty_data.host_size = 0;
25727 ptr_ty_data.@"align" = new_align;
25732 const byte_offset = ptr_ty_data.packed_offset.bit_offset / 8;
25733 const new_align = @enumFromInt(Alignment, @ctz(byte_offset | parent_align));
25734 assert(new_align != .none);
25735 ptr_ty_data.flags.alignment = new_align;
25736 ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 };
2572825737 }
2572925738 }
2573025739 } else {
25731 ptr_ty_data.@"align" = field.abi_align;
25740 ptr_ty_data.flags.alignment = field.abi_align;
2573225741 }
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
2573625745 if (field.is_comptime) {
2573725746 const val = try mod.intern(.{ .ptr = .{
......@@ -25893,7 +25902,6 @@ fn unionFieldPtr(
2589325902 unresolved_union_ty: Type,
2589425903 initializing: bool,
2589525904) CompileError!Air.Inst.Ref {
25896 const arena = sema.arena;
2589725905 const mod = sema.mod;
2589825906 const ip = &mod.intern_pool;
2589925907
......@@ -25904,11 +25912,13 @@ fn unionFieldPtr(
2590425912 const union_obj = mod.typeToUnion(union_ty).?;
2590525913 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
2590625914 const field = union_obj.fields.values()[field_index];
25907 const ptr_field_ty = try Type.ptr(arena, mod, .{
25908 .pointee_type = field.ty,
25909 .mutable = union_ptr_ty.ptrIsMutable(mod),
25910 .@"volatile" = union_ptr_ty.isVolatilePtr(mod),
25911 .@"addrspace" = union_ptr_ty.ptrAddressSpace(mod),
25915 const ptr_field_ty = try mod.ptrType(.{
25916 .child = field.ty.toIntern(),
25917 .flags = .{
25918 .is_const = !union_ptr_ty.ptrIsMutable(mod),
25919 .is_volatile = union_ptr_ty.isVolatilePtr(mod),
25920 .address_space = union_ptr_ty.ptrAddressSpace(mod),
25921 },
2591225922 });
2591325923 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);
2591425924
......@@ -26269,11 +26279,13 @@ fn tupleFieldPtr(
2626926279 }
2627026280
2627126281 const field_ty = tuple_ty.structFieldType(field_index, mod);
26272 const ptr_field_ty = try Type.ptr(sema.arena, mod, .{
26273 .pointee_type = field_ty,
26274 .mutable = tuple_ptr_ty.ptrIsMutable(mod),
26275 .@"volatile" = tuple_ptr_ty.isVolatilePtr(mod),
26276 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod),
26282 const ptr_field_ty = try mod.ptrType(.{
26283 .child = field_ty.toIntern(),
26284 .flags = .{
26285 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),
26286 .is_volatile = tuple_ptr_ty.isVolatilePtr(mod),
26287 .address_space = tuple_ptr_ty.ptrAddressSpace(mod),
26288 },
2627726289 });
2627826290
2627926291 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
......@@ -26724,15 +26736,15 @@ fn coerceExtra(
2672426736
2672526737 // *T to *[1]T
2672626738 single_item: {
26727 if (dest_info.size != .One) break :single_item;
26739 if (dest_info.flags.size != .One) break :single_item;
2672826740 if (!inst_ty.isSinglePointer(mod)) break :single_item;
2672926741 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2673026742 const ptr_elem_ty = inst_ty.childType(mod);
26731 const array_ty = dest_info.pointee_type;
26743 const array_ty = dest_info.child.toType();
2673226744 if (array_ty.zigTypeTag(mod) != .Array) break :single_item;
2673326745 const array_elem_ty = array_ty.childType(mod);
2673426746 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;
2673626748 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
2673726749 .ok => {},
2673826750 else => break :single_item,
......@@ -26747,9 +26759,9 @@ fn coerceExtra(
2674726759 const array_ty = inst_ty.childType(mod);
2674826760 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
2674926761 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();
2675326765 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src);
2675426766 switch (elem_res) {
2675526767 .ok => {},
......@@ -26763,12 +26775,12 @@ fn coerceExtra(
2676326775 },
2676426776 }
2676526777
26766 if (dest_info.sentinel) |dest_sent| {
26778 if (dest_info.sentinel != .none) {
2676726779 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()) {
2676926781 in_memory_result = .{ .ptr_sentinel = .{
2677026782 .actual = inst_sent,
26771 .wanted = dest_sent,
26783 .wanted = dest_info.sentinel.toValue(),
2677226784 .ty = dst_elem_type,
2677326785 } };
2677426786 break :src_array_ptr;
......@@ -26776,14 +26788,14 @@ fn coerceExtra(
2677626788 } else {
2677726789 in_memory_result = .{ .ptr_sentinel = .{
2677826790 .actual = Value.@"unreachable",
26779 .wanted = dest_sent,
26791 .wanted = dest_info.sentinel.toValue(),
2678026792 .ty = dst_elem_type,
2678126793 } };
2678226794 break :src_array_ptr;
2678326795 }
2678426796 }
2678526797
26786 switch (dest_info.size) {
26798 switch (dest_info.flags.size) {
2678726799 .Slice => {
2678826800 // *[N]T to []T
2678926801 return sema.coerceArrayPtrToSlice(block, dest_ty, inst, inst_src);
......@@ -26806,8 +26818,8 @@ fn coerceExtra(
2680626818 // In this case we must add a safety check because the C pointer
2680726819 // could be null.
2680826820 const src_elem_ty = inst_ty.childType(mod);
26809 const dest_is_mut = dest_info.mutable;
26810 const dst_elem_type = dest_info.pointee_type;
26821 const dest_is_mut = !dest_info.flags.is_const;
26822 const dst_elem_type = dest_info.child.toType();
2681126823 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
2681226824 .ok => {},
2681326825 else => break :src_c_ptr,
......@@ -26817,7 +26829,7 @@ fn coerceExtra(
2681726829
2681826830 // cast from *T and [*]T to *anyopaque
2681926831 // 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: {
2682126833 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2682226834 const elem_ty = inst_ty.elemType2(mod);
2682326835 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
......@@ -26838,7 +26850,7 @@ fn coerceExtra(
2683826850 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
2683926851 }
2684026852
26841 switch (dest_info.size) {
26853 switch (dest_info.flags.size) {
2684226854 // coercion to C pointer
2684326855 .C => switch (inst_ty.zigTypeTag(mod)) {
2684426856 .Null => {
......@@ -26871,9 +26883,9 @@ fn coerceExtra(
2687126883 const inst_info = inst_ty.ptrInfo(mod);
2687226884 switch (try sema.coerceInMemoryAllowed(
2687326885 block,
26874 dest_info.pointee_type,
26875 inst_info.pointee_type,
26876 dest_info.mutable,
26886 dest_info.child.toType(),
26887 inst_info.child.toType(),
26888 !dest_info.flags.is_const,
2687726889 target,
2687826890 dest_ty_src,
2687926891 inst_src,
......@@ -26881,10 +26893,10 @@ fn coerceExtra(
2688126893 .ok => {},
2688226894 else => break :p,
2688326895 }
26884 if (inst_info.size == .Slice) {
26885 assert(dest_info.sentinel == null);
26886 if (inst_info.sentinel == null or
26887 !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, mod))
26896 if (inst_info.flags.size == .Slice) {
26897 assert(dest_info.sentinel == .none);
26898 if (inst_info.sentinel == .none or
26899 inst_info.sentinel != (try mod.intValue(inst_info.child.toType(), 0)).toIntern())
2688826900 break :p;
2688926901
2689026902 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -26894,7 +26906,7 @@ fn coerceExtra(
2689426906 },
2689526907 else => {},
2689626908 },
26897 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
26909 .One => switch (dest_info.child.toType().zigTypeTag(mod)) {
2689826910 .Union => {
2689926911 // pointer to anonymous struct to pointer to union
2690026912 if (inst_ty.isSinglePointer(mod) and
......@@ -26948,16 +26960,16 @@ fn coerceExtra(
2694826960 // we use a dummy pointer value with the required alignment.
2694926961 return sema.addConstant(dest_ty, (try mod.intern(.{ .ptr = .{
2695026962 .ty = dest_ty.toIntern(),
26951 .addr = .{ .int = (if (dest_info.@"align" != 0)
26952 try mod.intValue(Type.usize, dest_info.@"align")
26963 .addr = .{ .int = (if (dest_info.flags.alignment != .none)
26964 try mod.intValue(Type.usize, dest_info.flags.alignment.toByteUnitsOptional().?)
2695326965 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() },
2695526967 .len = (try mod.intValue(Type.usize, 0)).toIntern(),
2695626968 } })).toValue());
2695726969 }
2695826970
2695926971 // pointer to tuple to slice
26960 if (dest_info.mutable) {
26972 if (!dest_info.flags.is_const) {
2696126973 const err_msg = err_msg: {
2696226974 const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)});
2696326975 errdefer err_msg.deinit(sema.gpa);
......@@ -26975,9 +26987,9 @@ fn coerceExtra(
2697526987
2697626988 switch (try sema.coerceInMemoryAllowed(
2697726989 block,
26978 dest_info.pointee_type,
26979 inst_info.pointee_type,
26980 dest_info.mutable,
26990 dest_info.child.toType(),
26991 inst_info.child.toType(),
26992 !dest_info.flags.is_const,
2698126993 target,
2698226994 dest_ty_src,
2698326995 inst_src,
......@@ -26986,12 +26998,9 @@ fn coerceExtra(
2698626998 else => break :p,
2698726999 }
2698827000
26989 if (dest_info.sentinel == null or inst_info.sentinel == null or
26990 !dest_info.sentinel.?.eql(
26991 try mod.getCoerced(inst_info.sentinel.?, dest_info.pointee_type),
26992 dest_info.pointee_type,
26993 mod,
26994 ))
27001 if (dest_info.sentinel == .none or inst_info.sentinel == .none or
27002 dest_info.sentinel !=
27003 try mod.intern_pool.getCoerced(sema.gpa, inst_info.sentinel, dest_info.child))
2699527004 break :p;
2699627005
2699727006 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -28117,41 +28126,41 @@ fn coerceInMemoryAllowedPtrs(
2811728126 const dest_info = dest_ptr_ty.ptrInfo(mod);
2811828127 const src_info = src_ptr_ty.ptrInfo(mod);
2811928128
28120 const ok_ptr_size = src_info.size == dest_info.size or
28121 src_info.size == .C or dest_info.size == .C;
28129 const ok_ptr_size = src_info.flags.size == dest_info.flags.size or
28130 src_info.flags.size == .C or dest_info.flags.size == .C;
2812228131 if (!ok_ptr_size) {
2812328132 return InMemoryCoercionResult{ .ptr_size = .{
28124 .actual = src_info.size,
28125 .wanted = dest_info.size,
28133 .actual = src_info.flags.size,
28134 .wanted = dest_info.flags.size,
2812628135 } };
2812728136 }
2812828137
2812928138 const ok_cv_qualifiers =
28130 (src_info.mutable or !dest_info.mutable) and
28131 (!src_info.@"volatile" or dest_info.@"volatile");
28139 (!src_info.flags.is_const or dest_info.flags.is_const) and
28140 (!src_info.flags.is_volatile or dest_info.flags.is_volatile);
2813228141
2813328142 if (!ok_cv_qualifiers) {
2813428143 return InMemoryCoercionResult{ .ptr_qualifiers = .{
28135 .actual_const = !src_info.mutable,
28136 .wanted_const = !dest_info.mutable,
28137 .actual_volatile = src_info.@"volatile",
28138 .wanted_volatile = dest_info.@"volatile",
28144 .actual_const = src_info.flags.is_const,
28145 .wanted_const = dest_info.flags.is_const,
28146 .actual_volatile = src_info.flags.is_volatile,
28147 .wanted_volatile = dest_info.flags.is_volatile,
2813928148 } };
2814028149 }
2814128150
28142 if (dest_info.@"addrspace" != src_info.@"addrspace") {
28151 if (dest_info.flags.address_space != src_info.flags.address_space) {
2814328152 return InMemoryCoercionResult{ .ptr_addrspace = .{
28144 .actual = src_info.@"addrspace",
28145 .wanted = dest_info.@"addrspace",
28153 .actual = src_info.flags.address_space,
28154 .wanted = dest_info.flags.address_space,
2814628155 } };
2814728156 }
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);
2815028159 if (child != .ok) {
2815128160 return InMemoryCoercionResult{ .ptr_child = .{
2815228161 .child = try child.dupe(sema.arena),
28153 .actual = src_info.pointee_type,
28154 .wanted = dest_info.pointee_type,
28162 .actual = src_info.child.toType(),
28163 .wanted = dest_info.child.toType(),
2815528164 } };
2815628165 }
2815728166
......@@ -28168,28 +28177,31 @@ fn coerceInMemoryAllowedPtrs(
2816828177 } };
2816928178 }
2817028179
28171 if (src_info.host_size != dest_info.host_size or
28172 src_info.bit_offset != dest_info.bit_offset)
28180 if (src_info.packed_offset.host_size != dest_info.packed_offset.host_size or
28181 src_info.packed_offset.bit_offset != dest_info.packed_offset.bit_offset)
2817328182 {
2817428183 return InMemoryCoercionResult{ .ptr_bit_range = .{
28175 .actual_host = src_info.host_size,
28176 .wanted_host = dest_info.host_size,
28177 .actual_offset = src_info.bit_offset,
28178 .wanted_offset = dest_info.bit_offset,
28184 .actual_host = src_info.packed_offset.host_size,
28185 .wanted_host = dest_info.packed_offset.host_size,
28186 .actual_offset = src_info.packed_offset.bit_offset,
28187 .wanted_offset = dest_info.packed_offset.bit_offset,
2817928188 } };
2818028189 }
2818128190
28182 const ok_sent = dest_info.sentinel == null or src_info.size == .C or
28183 (src_info.sentinel != null and dest_info.sentinel.?.eql(
28184 try mod.getCoerced(src_info.sentinel.?, dest_info.pointee_type),
28185 dest_info.pointee_type,
28186 sema.mod,
28187 ));
28191 const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or
28192 (src_info.sentinel != .none and
28193 dest_info.sentinel == try mod.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child));
2818828194 if (!ok_sent) {
2818928195 return InMemoryCoercionResult{ .ptr_sentinel = .{
28190 .actual = src_info.sentinel orelse Value.@"unreachable",
28191 .wanted = dest_info.sentinel orelse Value.@"unreachable",
28192 .ty = dest_info.pointee_type,
28196 .actual = switch (src_info.sentinel) {
28197 .none => Value.@"unreachable",
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(),
2819328205 } };
2819428206 }
2819528207
......@@ -28197,22 +28209,14 @@ fn coerceInMemoryAllowedPtrs(
2819728209 // In this case, if they share the same child type, no need to resolve
2819828210 // pointee type alignment. Otherwise both pointee types must have their alignment
2819928211 // resolved and we compare the alignment numerically.
28200 alignment: {
28201 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and
28202 dest_info.pointee_type.eql(src_info.pointee_type, sema.mod))
28203 {
28204 break :alignment;
28205 }
28206
28207 const src_align = if (src_info.@"align" != 0)
28208 src_info.@"align"
28209 else
28210 src_info.pointee_type.abiAlignment(mod);
28212 if (src_info.flags.alignment != .none or dest_info.flags.alignment != .none or
28213 dest_info.child != src_info.child)
28214 {
28215 const src_align = src_info.flags.alignment.toByteUnitsOptional() orelse
28216 src_info.child.toType().abiAlignment(mod);
2821128217
28212 const dest_align = if (dest_info.@"align" != 0)
28213 dest_info.@"align"
28214 else
28215 dest_info.pointee_type.abiAlignment(mod);
28218 const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse
28219 dest_info.child.toType().abiAlignment(mod);
2821628220
2821728221 if (dest_align > src_align) {
2821828222 return InMemoryCoercionResult{ .ptr_alignment = .{
......@@ -28220,8 +28224,6 @@ fn coerceInMemoryAllowedPtrs(
2822028224 .wanted = dest_align,
2822128225 } };
2822228226 }
28223
28224 break :alignment;
2822528227 }
2822628228
2822728229 return .ok;
......@@ -28386,7 +28388,7 @@ fn storePtr2(
2838628388 try sema.requireRuntimeBlock(block, src, runtime_src);
2838728389 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) {
2839028392 const ptr_inst = Air.refToIndex(ptr).?;
2839128393 const air_tags = sema.air_instructions.items(.tag);
2839228394 if (air_tags[ptr_inst] == .ptr_elem_ptr) {
......@@ -29238,11 +29240,14 @@ fn beginComptimePtrLoad(
2923829240 // It's possible that we're loading a [N]T, in which case we'd like to slice
2923929241 // the pointee array directly from our parent array.
2924029242 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));
2924229244 const elem_idx = try sema.usizeCast(block, src, elem_ptr.index);
29243 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
29244 .ty = try Type.array(sema.arena, N, null, elem_ty, mod),
29245 .val = try array_tv.val.sliceArray(mod, sema.arena, elem_idx, elem_idx + N),
29245 deref.pointee = if (elem_ptr.index + len <= check_len) TypedValue{
29246 .ty = try mod.arrayType(.{
29247 .len = len,
29248 .child = elem_ty.toIntern(),
29249 }),
29250 .val = try array_tv.val.sliceArray(mod, sema.arena, elem_idx, elem_idx + len),
2924629251 } else null;
2924729252 break :blk deref;
2924829253 }
......@@ -29429,42 +29434,38 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul
2942929434 const mod = sema.mod;
2943029435 const dest_info = dest_ty.ptrInfo(mod);
2943129436 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 or
29433 (inst_info.pointee_type.arrayLen(mod) == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or
29434 (inst_info.pointee_type.isTuple(mod) and inst_info.pointee_type.structFieldCount(mod) == 0);
29437 const len0 = (inst_info.child.toType().zigTypeTag(mod) == .Array and (inst_info.child.toType().arrayLenIncludingSentinel(mod) == 0 or
29438 (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
29439 (inst_info.child.toType().isTuple(mod) and inst_info.child.toType().structFieldCount(mod) == 0);
2943529440
2943629441 const ok_cv_qualifiers =
29437 ((inst_info.mutable or !dest_info.mutable) or len0) and
29438 (!inst_info.@"volatile" or dest_info.@"volatile");
29442 ((!inst_info.flags.is_const or dest_info.flags.is_const) or len0) and
29443 (!inst_info.flags.is_volatile or dest_info.flags.is_volatile);
2943929444
2944029445 if (!ok_cv_qualifiers) {
2944129446 in_memory_result.* = .{ .ptr_qualifiers = .{
29442 .actual_const = !inst_info.mutable,
29443 .wanted_const = !dest_info.mutable,
29444 .actual_volatile = inst_info.@"volatile",
29445 .wanted_volatile = dest_info.@"volatile",
29447 .actual_const = inst_info.flags.is_const,
29448 .wanted_const = dest_info.flags.is_const,
29449 .actual_volatile = inst_info.flags.is_volatile,
29450 .wanted_volatile = dest_info.flags.is_volatile,
2944629451 } };
2944729452 return false;
2944829453 }
29449 if (dest_info.@"addrspace" != inst_info.@"addrspace") {
29454 if (dest_info.flags.address_space != inst_info.flags.address_space) {
2945029455 in_memory_result.* = .{ .ptr_addrspace = .{
29451 .actual = inst_info.@"addrspace",
29452 .wanted = dest_info.@"addrspace",
29456 .actual = inst_info.flags.address_space,
29457 .wanted = dest_info.flags.address_space,
2945329458 } };
2945429459 return false;
2945529460 }
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;
2945729462 if (len0) return true;
2945829463
29459 const inst_align = if (inst_info.@"align" != 0)
29460 inst_info.@"align"
29461 else
29462 inst_info.pointee_type.abiAlignment(mod);
29464 const inst_align = inst_info.flags.alignment.toByteUnitsOptional() orelse
29465 inst_info.child.toType().abiAlignment(mod);
2946329466
29464 const dest_align = if (dest_info.@"align" != 0)
29465 dest_info.@"align"
29466 else
29467 dest_info.pointee_type.abiAlignment(mod);
29467 const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse
29468 dest_info.child.toType().abiAlignment(mod);
2946829469
2946929470 if (dest_align > inst_align) {
2947029471 in_memory_result.* = .{ .ptr_alignment = .{
......@@ -29901,9 +29902,13 @@ fn coerceTupleToSlicePtrs(
2990129902 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);
2990229903 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
2990329904 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 });
2990529910 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) {
2990729912 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
2990829913 }
2990929914 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst);
......@@ -29922,9 +29927,9 @@ fn coerceTupleToArrayPtrs(
2992229927 const mod = sema.mod;
2992329928 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
2992429929 const ptr_info = ptr_array_ty.ptrInfo(mod);
29925 const array_ty = ptr_info.pointee_type;
29930 const array_ty = ptr_info.child.toType();
2992629931 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) {
2992829933 return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});
2992929934 }
2993029935 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 {
3026330268 const decl = try anon_decl.finish(
3026430269 ty,
3026530270 val,
30266 0, // default alignment
30271 .none, // default alignment
3026730272 );
3026830273 try sema.maybeQueueFuncBodyAnalysis(decl);
3026930274 try mod.declareDeclDependency(sema.owner_decl_index, decl);
......@@ -30304,7 +30309,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo
3030430309 const ptr_ty = try mod.ptrType(.{
3030530310 .child = decl_tv.ty.toIntern(),
3030630311 .flags = .{
30307 .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"),
30312 .alignment = decl.alignment,
3030830313 .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true,
3030930314 .address_space = decl.@"addrspace",
3031030315 },
......@@ -30334,12 +30339,13 @@ fn analyzeRef(
3033430339 src: LazySrcLoc,
3033530340 operand: Air.Inst.Ref,
3033630341) CompileError!Air.Inst.Ref {
30342 const mod = sema.mod;
3033730343 const operand_ty = sema.typeOf(operand);
3033830344
3033930345 if (try sema.resolveMaybeUndefVal(operand)) |val| {
30340 switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {
30346 switch (mod.intern_pool.indexToKey(val.toIntern())) {
3034130347 .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),
3034330349 else => {},
3034430350 }
3034530351 var anon_decl = try block.startAnonDecl();
......@@ -30347,20 +30353,22 @@ fn analyzeRef(
3034730353 return sema.analyzeDeclRef(try anon_decl.finish(
3034830354 operand_ty,
3034930355 val,
30350 0, // default alignment
30356 .none, // default alignment
3035130357 ));
3035230358 }
3035330359
3035430360 try sema.requireRuntimeBlock(block, src, null);
30355 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);
30356 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
30357 .pointee_type = operand_ty,
30358 .mutable = false,
30359 .@"addrspace" = address_space,
30361 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);
30362 const ptr_type = try mod.ptrType(.{
30363 .child = operand_ty.toIntern(),
30364 .flags = .{
30365 .is_const = true,
30366 .address_space = address_space,
30367 },
3036030368 });
30361 const mut_ptr_type = try Type.ptr(sema.arena, sema.mod, .{
30362 .pointee_type = operand_ty,
30363 .@"addrspace" = address_space,
30369 const mut_ptr_type = try mod.ptrType(.{
30370 .child = operand_ty.toIntern(),
30371 .flags = .{ .address_space = address_space },
3036430372 });
3036530373 const alloc = try block.addTy(.alloc, mut_ptr_type);
3036630374 try sema.storePtr(block, src, alloc, operand);
......@@ -30393,7 +30401,7 @@ fn analyzeLoad(
3039330401 }
3039430402 }
3039530403
30396 if (ptr_ty.ptrInfo(mod).vector_index == .runtime) {
30404 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
3039730405 const ptr_inst = Air.refToIndex(ptr).?;
3039830406 const air_tags = sema.air_instructions.items(.tag);
3039930407 if (air_tags[ptr_inst] == .ptr_elem_ptr) {
......@@ -30919,20 +30927,24 @@ fn analyzeSlice(
3091930927 const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len);
3092030928
3092130929 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
3092430932 if (opt_new_len_val) |new_len_val| {
3092530933 const new_len_int = new_len_val.toUnsignedInt(mod);
3092630934
30927 const return_ty = try Type.ptr(sema.arena, mod, .{
30928 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod),
30929 .sentinel = null,
30930 .@"align" = new_ptr_ty_info.@"align",
30931 .@"addrspace" = new_ptr_ty_info.@"addrspace",
30932 .mutable = new_ptr_ty_info.mutable,
30933 .@"allowzero" = new_allowzero,
30934 .@"volatile" = new_ptr_ty_info.@"volatile",
30935 .size = .One,
30935 const return_ty = try mod.ptrType(.{
30936 .child = (try mod.arrayType(.{
30937 .len = new_len_int,
30938 .sentinel = if (sentinel) |s| s.toIntern() else .none,
30939 .child = elem_ty.toIntern(),
30940 })).toIntern(),
30941 .flags = .{
30942 .alignment = new_ptr_ty_info.flags.alignment,
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 },
3093630948 });
3093730949
3093830950 const opt_new_ptr_val = try sema.resolveMaybeUndefVal(new_ptr);
......@@ -30981,15 +30993,17 @@ fn analyzeSlice(
3098130993 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
3098230994 }
3098330995
30984 const return_ty = try Type.ptr(sema.arena, mod, .{
30985 .pointee_type = elem_ty,
30986 .sentinel = sentinel,
30987 .@"align" = new_ptr_ty_info.@"align",
30988 .@"addrspace" = new_ptr_ty_info.@"addrspace",
30989 .mutable = new_ptr_ty_info.mutable,
30990 .@"allowzero" = new_allowzero,
30991 .@"volatile" = new_ptr_ty_info.@"volatile",
30992 .size = .Slice,
30996 const return_ty = try mod.ptrType(.{
30997 .child = elem_ty.toIntern(),
30998 .sentinel = if (sentinel) |s| s.toIntern() else .none,
30999 .flags = .{
31000 .size = .Slice,
31001 .alignment = new_ptr_ty_info.flags.alignment,
31002 .is_const = new_ptr_ty_info.flags.is_const,
31003 .is_volatile = new_ptr_ty_info.flags.is_volatile,
31004 .is_allowzero = new_allowzero,
31005 .address_space = new_ptr_ty_info.flags.address_space,
31006 },
3099331007 });
3099431008
3099531009 try sema.requireRuntimeBlock(block, src, runtime_src.?);
......@@ -31735,7 +31749,7 @@ const PeerResolveStrategy = enum {
3173531749 .Int => .fixed_int,
3173631750 .ComptimeFloat => .comptime_float,
3173731751 .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,
3173931753 .Array => .array,
3174031754 .Vector => .vector,
3174131755 .Optional => .optional,
......@@ -32160,7 +32174,7 @@ fn resolvePeerTypesInner(
3216032174 },
3216132175
3216232176 .c_ptr => {
32163 var opt_ptr_info: ?Type.Payload.Pointer.Data = null;
32177 var opt_ptr_info: ?InternPool.Key.PtrType = null;
3216432178 var first_idx: usize = undefined;
3216532179 for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| {
3216632180 const ty = opt_ty orelse continue;
......@@ -32191,42 +32205,47 @@ fn resolvePeerTypesInner(
3219132205
3219232206 var ptr_info = opt_ptr_info orelse {
3219332207 opt_ptr_info = peer_info;
32194 opt_ptr_info.?.size = .C;
32208 opt_ptr_info.?.flags.size = .C;
3219532209 first_idx = i;
3219632210 continue;
3219732211 };
3219832212
3219932213 // 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 {
3220132215 return .{ .conflict = .{
3220232216 .peer_idx_a = first_idx,
3220332217 .peer_idx_b = i,
3220432218 } };
32205 };
32219 }).toIntern();
3220632220
32207 if (ptr_info.sentinel != null and peer_info.sentinel != null) {
32208 const peer_sent = try mod.getCoerced(ptr_info.sentinel.?, ptr_info.pointee_type);
32209 const ptr_sent = try mod.getCoerced(peer_info.sentinel.?, ptr_info.pointee_type);
32210 if (ptr_sent.eql(peer_sent, ptr_info.pointee_type, mod)) {
32221 if (ptr_info.sentinel != .none and peer_info.sentinel != .none) {
32222 const peer_sent = try mod.intern_pool.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child);
32223 const ptr_sent = try mod.intern_pool.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child);
32224 if (ptr_sent == peer_sent) {
3221132225 ptr_info.sentinel = ptr_sent;
3221232226 } else {
32213 ptr_info.sentinel = null;
32227 ptr_info.sentinel = .none;
3221432228 }
3221532229 } else {
32216 ptr_info.sentinel = null;
32230 ptr_info.sentinel = .none;
3221732231 }
3221832232
32219 // Note that the align can be always non-zero; Type.ptr will canonicalize it
32220 ptr_info.@"align" = @min(ptr_info.alignment(mod), peer_info.alignment(mod));
32221 if (ptr_info.@"addrspace" != peer_info.@"addrspace") {
32233 // Note that the align can be always non-zero; Module.ptrType will canonicalize it
32234 ptr_info.flags.alignment = Alignment.fromByteUnits(@min(
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) {
3222232241 return .{ .conflict = .{
3222332242 .peer_idx_a = first_idx,
3222432243 .peer_idx_b = i,
3222532244 } };
3222632245 }
3222732246
32228 if (ptr_info.bit_offset != peer_info.bit_offset or
32229 ptr_info.host_size != peer_info.host_size)
32247 if (ptr_info.packed_offset.bit_offset != peer_info.packed_offset.bit_offset or
32248 ptr_info.packed_offset.host_size != peer_info.packed_offset.host_size)
3223032249 {
3223132250 return .{ .conflict = .{
3223232251 .peer_idx_a = first_idx,
......@@ -32234,12 +32253,12 @@ fn resolvePeerTypesInner(
3223432253 } };
3223532254 }
3223632255
32237 ptr_info.mutable = ptr_info.mutable and peer_info.mutable;
32238 ptr_info.@"volatile" = ptr_info.@"volatile" or peer_info.@"volatile";
32256 ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const;
32257 ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile;
3223932258
3224032259 opt_ptr_info = ptr_info;
3224132260 }
32242 return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) };
32261 return .{ .success = try mod.ptrType(opt_ptr_info.?) };
3224332262 },
3224432263
3224532264 .ptr => {
......@@ -32247,17 +32266,19 @@ fn resolvePeerTypesInner(
3224732266 // if there were no actual slices. Else, we want the slice index to report a conflict.
3224832267 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;
3225132270 var first_idx: usize = undefined;
3225232271 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error
3225332272
3225432273 for (peer_tys, 0..) |opt_ty, i| {
3225532274 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)) {
3225732276 .Pointer => ty.ptrInfo(mod),
3225832277 .Fn => .{
32259 .pointee_type = ty,
32260 .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant),
32278 .child = ty.toIntern(),
32279 .flags = .{
32280 .address_space = target_util.defaultAddressSpace(target, .global_constant),
32281 },
3226132282 },
3226232283 else => return .{ .conflict = .{
3226332284 .peer_idx_a = strat_reason,
......@@ -32265,7 +32286,7 @@ fn resolvePeerTypesInner(
3226532286 } },
3226632287 };
3226732288
32268 switch (peer_info.size) {
32289 switch (peer_info.flags.size) {
3226932290 .One, .Many => {},
3227032291 .Slice => opt_slice_idx = i,
3227132292 .C => return .{ .conflict = .{
......@@ -32289,51 +32310,56 @@ fn resolvePeerTypesInner(
3228932310 } };
3229032311
3229132312 // 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) {
3229532321 return generic_err;
3229632322 }
3229732323
32298 if (ptr_info.bit_offset != peer_info.bit_offset or
32299 ptr_info.host_size != peer_info.host_size)
32324 if (ptr_info.packed_offset.bit_offset != peer_info.packed_offset.bit_offset or
32325 ptr_info.packed_offset.host_size != peer_info.packed_offset.host_size)
3230032326 {
3230132327 return generic_err;
3230232328 }
3230332329
32304 ptr_info.mutable = ptr_info.mutable and peer_info.mutable;
32305 ptr_info.@"volatile" = ptr_info.@"volatile" or peer_info.@"volatile";
32330 ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const;
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) {
32308 .One => switch (peer_info.pointee_type.zigTypeTag(mod)) {
32309 .Array => peer_info.pointee_type.sentinel(mod),
32310 else => null,
32333 const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) {
32334 .One => switch (mod.intern_pool.indexToKey(peer_info.child)) {
32335 .array_type => |array_type| array_type.sentinel,
32336 else => .none,
3231132337 },
3231232338 .Many, .Slice => peer_info.sentinel,
3231332339 .C => unreachable,
3231432340 };
3231532341
32316 const cur_sentinel: ?Value = switch (ptr_info.size) {
32317 .One => switch (ptr_info.pointee_type.zigTypeTag(mod)) {
32318 .Array => ptr_info.pointee_type.sentinel(mod),
32319 else => null,
32342 const cur_sentinel: InternPool.Index = switch (ptr_info.flags.size) {
32343 .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32344 .array_type => |array_type| array_type.sentinel,
32345 else => .none,
3232032346 },
3232132347 .Many, .Slice => ptr_info.sentinel,
3232232348 .C => unreachable,
3232332349 };
3232432350
3232532351 // 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);
32327 const cur_pointee_array = sema.typeIsArrayLike(ptr_info.pointee_type);
32352 const peer_pointee_array = sema.typeIsArrayLike(peer_info.child.toType());
32353 const cur_pointee_array = sema.typeIsArrayLike(ptr_info.child.toType());
3232832354
3232932355 // This switch is just responsible for deciding the size and pointee (not including
3233032356 // single-pointer array sentinel).
3233132357 good: {
32332 switch (peer_info.size) {
32333 .One => switch (ptr_info.size) {
32358 switch (peer_info.flags.size) {
32359 .One => switch (ptr_info.flags.size) {
3233432360 .One => {
32335 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {
32336 ptr_info.pointee_type = pointee;
32361 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32362 ptr_info.child = pointee.toIntern();
3233732363 break :good;
3233832364 }
3233932365
......@@ -32343,29 +32369,29 @@ fn resolvePeerTypesInner(
3234332369 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {
3234432370 // *[n:x]T + *[n:y]T = *[n]T
3234532371 if (cur_arr.len == peer_arr.len) {
32346 ptr_info.pointee_type = try mod.arrayType(.{
32372 ptr_info.child = (try mod.arrayType(.{
3234732373 .len = cur_arr.len,
3234832374 .child = elem_ty.toIntern(),
32349 });
32375 })).toIntern();
3235032376 break :good;
3235132377 }
3235232378 // *[a]T + *[b]T = []T
32353 ptr_info.size = .Slice;
32354 ptr_info.pointee_type = elem_ty;
32379 ptr_info.flags.size = .Slice;
32380 ptr_info.child = elem_ty.toIntern();
3235532381 break :good;
3235632382 }
3235732383
3235832384 if (peer_arr.elem_ty.toIntern() == .noreturn_type) {
3235932385 // *struct{} + *[a]T = []T
32360 ptr_info.size = .Slice;
32361 ptr_info.pointee_type = cur_arr.elem_ty;
32386 ptr_info.flags.size = .Slice;
32387 ptr_info.child = cur_arr.elem_ty.toIntern();
3236232388 break :good;
3236332389 }
3236432390
3236532391 if (cur_arr.elem_ty.toIntern() == .noreturn_type) {
3236632392 // *[a]T + *struct{} = []T
32367 ptr_info.size = .Slice;
32368 ptr_info.pointee_type = peer_arr.elem_ty;
32393 ptr_info.flags.size = .Slice;
32394 ptr_info.child = peer_arr.elem_ty.toIntern();
3236932395 break :good;
3237032396 }
3237132397
......@@ -32374,8 +32400,8 @@ fn resolvePeerTypesInner(
3237432400 .Many => {
3237532401 // Only works for *[n]T + [*]T -> [*]T
3237632402 const arr = peer_pointee_array orelse return generic_err;
32377 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| {
32378 ptr_info.pointee_type = pointee;
32403 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), arr.elem_ty)) |pointee| {
32404 ptr_info.child = pointee.toIntern();
3237932405 break :good;
3238032406 }
3238132407 if (arr.elem_ty.toIntern() == .noreturn_type) {
......@@ -32387,8 +32413,8 @@ fn resolvePeerTypesInner(
3238732413 .Slice => {
3238832414 // Only works for *[n]T + []T -> []T
3238932415 const arr = peer_pointee_array orelse return generic_err;
32390 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| {
32391 ptr_info.pointee_type = pointee;
32416 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), arr.elem_ty)) |pointee| {
32417 ptr_info.child = pointee.toIntern();
3239232418 break :good;
3239332419 }
3239432420 if (arr.elem_ty.toIntern() == .noreturn_type) {
......@@ -32399,26 +32425,26 @@ fn resolvePeerTypesInner(
3239932425 },
3240032426 .C => unreachable,
3240132427 },
32402 .Many => switch (ptr_info.size) {
32428 .Many => switch (ptr_info.flags.size) {
3240332429 .One => {
3240432430 // Only works for [*]T + *[n]T -> [*]T
3240532431 const arr = cur_pointee_array orelse return generic_err;
32406 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| {
32407 ptr_info.size = .Many;
32408 ptr_info.pointee_type = pointee;
32432 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.child.toType())) |pointee| {
32433 ptr_info.flags.size = .Many;
32434 ptr_info.child = pointee.toIntern();
3240932435 break :good;
3241032436 }
3241132437 if (arr.elem_ty.toIntern() == .noreturn_type) {
3241232438 // [*]T + *struct{} -> [*]T
32413 ptr_info.size = .Many;
32414 ptr_info.pointee_type = peer_info.pointee_type;
32439 ptr_info.flags.size = .Many;
32440 ptr_info.child = peer_info.child;
3241532441 break :good;
3241632442 }
3241732443 return generic_err;
3241832444 },
3241932445 .Many => {
32420 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {
32421 ptr_info.pointee_type = pointee;
32446 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32447 ptr_info.child = pointee.toIntern();
3242232448 break :good;
3242332449 }
3242432450 return generic_err;
......@@ -32432,28 +32458,28 @@ fn resolvePeerTypesInner(
3243232458 } };
3243332459 }
3243432460 // Okay, then works for [*]T + "[]T" -> [*]T
32435 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {
32436 ptr_info.size = .Many;
32437 ptr_info.pointee_type = pointee;
32461 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32462 ptr_info.flags.size = .Many;
32463 ptr_info.child = pointee.toIntern();
3243832464 break :good;
3243932465 }
3244032466 return generic_err;
3244132467 },
3244232468 .C => unreachable,
3244332469 },
32444 .Slice => switch (ptr_info.size) {
32470 .Slice => switch (ptr_info.flags.size) {
3244532471 .One => {
3244632472 // Only works for []T + *[n]T -> []T
3244732473 const arr = cur_pointee_array orelse return generic_err;
32448 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| {
32449 ptr_info.size = .Slice;
32450 ptr_info.pointee_type = pointee;
32474 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.child.toType())) |pointee| {
32475 ptr_info.flags.size = .Slice;
32476 ptr_info.child = pointee.toIntern();
3245132477 break :good;
3245232478 }
3245332479 if (arr.elem_ty.toIntern() == .noreturn_type) {
3245432480 // []T + *struct{} -> []T
32455 ptr_info.size = .Slice;
32456 ptr_info.pointee_type = peer_info.pointee_type;
32481 ptr_info.flags.size = .Slice;
32482 ptr_info.child = peer_info.child;
3245732483 break :good;
3245832484 }
3245932485 return generic_err;
......@@ -32463,8 +32489,8 @@ fn resolvePeerTypesInner(
3246332489 return generic_err;
3246432490 },
3246532491 .Slice => {
32466 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {
32467 ptr_info.pointee_type = pointee;
32492 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| {
32493 ptr_info.child = pointee.toIntern();
3246832494 break :good;
3246932495 }
3247032496 return generic_err;
......@@ -32475,40 +32501,43 @@ fn resolvePeerTypesInner(
3247532501 }
3247632502 }
3247732503
32478 const sentinel_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Array) blk: {
32479 break :blk ptr_info.pointee_type.childType(mod);
32480 } else ptr_info.pointee_type;
32481
32482 // TODO: once InternPool is in, we need to cast the sentinels to sentinel_ty
32504 const sentinel_ty = switch (ptr_info.flags.size) {
32505 .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32506 .array_type => |array_type| array_type.child,
32507 else => ptr_info.child,
32508 },
32509 .Many, .Slice, .C => ptr_info.child,
32510 };
3248332511
3248432512 sentinel: {
3248532513 no_sentinel: {
32486 if (peer_sentinel == null) break :no_sentinel;
32487 if (cur_sentinel == null) break :no_sentinel;
32488 const peer_sent_coerced = try mod.getCoerced(peer_sentinel.?, sentinel_ty);
32489 const cur_sent_coerced = try mod.getCoerced(cur_sentinel.?, sentinel_ty);
32490 if (!peer_sent_coerced.eql(cur_sent_coerced, sentinel_ty, mod)) break :no_sentinel;
32514 if (peer_sentinel == .none) break :no_sentinel;
32515 if (cur_sentinel == .none) break :no_sentinel;
32516 const peer_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);
32517 const cur_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, cur_sentinel, sentinel_ty);
32518 if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel;
3249132519 // Sentinels match
32492 if (ptr_info.size == .One) {
32493 assert(ptr_info.pointee_type.zigTypeTag(mod) == .Array);
32494 ptr_info.pointee_type = try mod.arrayType(.{
32495 .len = ptr_info.pointee_type.arrayLen(mod),
32496 .child = ptr_info.pointee_type.childType(mod).toIntern(),
32497 .sentinel = cur_sent_coerced.toIntern(),
32498 });
32520 if (ptr_info.flags.size == .One) switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32521 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
32522 .len = array_type.len,
32523 .child = array_type.child,
32524 .sentinel = cur_sent_coerced,
32525 })).toIntern(),
32526 else => unreachable,
3249932527 } else {
3250032528 ptr_info.sentinel = cur_sent_coerced;
3250132529 }
3250232530 break :sentinel;
3250332531 }
3250432532 // Clear existing sentinel
32505 ptr_info.sentinel = null;
32506 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
32507 ptr_info.pointee_type = try mod.arrayType(.{
32508 .len = ptr_info.pointee_type.arrayLen(mod),
32509 .child = ptr_info.pointee_type.childType(mod).toIntern(),
32533 ptr_info.sentinel = .none;
32534 switch (mod.intern_pool.indexToKey(ptr_info.child)) {
32535 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
32536 .len = array_type.len,
32537 .child = array_type.child,
3251032538 .sentinel = .none,
32511 });
32539 })).toIntern(),
32540 else => {},
3251232541 }
3251332542 }
3251432543
......@@ -32519,17 +32548,22 @@ fn resolvePeerTypesInner(
3251932548 // &.{} and &.{}, we'll currently have a pointer type of `*[0]noreturn` - we wanted to
3252032549 // coerce the empty struct to a specific type, but no peer provided one. We need to
3252132550 // detect this case and emit an error.
32522 const pointee = opt_ptr_info.?.pointee_type;
32523 if (pointee.toIntern() == .noreturn_type or
32524 (pointee.zigTypeTag(mod) == .Array and pointee.childType(mod).toIntern() == .noreturn_type))
32525 {
32526 return .{ .conflict = .{
32551 const pointee = opt_ptr_info.?.child;
32552 switch (pointee) {
32553 .noreturn_type => return .{ .conflict = .{
3252732554 .peer_idx_a = first_idx,
3252832555 .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 },
3253032564 }
3253132565
32532 return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) };
32566 return .{ .success = try mod.ptrType(opt_ptr_info.?) };
3253332567 },
3253432568
3253532569 .func => {
......@@ -33749,6 +33783,8 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3374933783
3375033784 .none => unreachable,
3375133785
33786 .u0_type,
33787 .i0_type,
3375233788 .u1_type,
3375333789 .u8_type,
3375433790 .i8_type,
......@@ -33797,6 +33833,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3379733833 .single_const_pointer_to_comptime_int_type,
3379833834 .slice_const_u8_type,
3379933835 .slice_const_u8_sentinel_0_type,
33836 .optional_noreturn_type,
3380033837 .anyerror_void_error_union_type,
3380133838 .generic_poison_type,
3380233839 .empty_struct_type,
......@@ -33833,18 +33870,25 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3383333870 .call_modifier_type => return sema.getBuiltinType("CallModifier"),
3383433871 .prefetch_options_type => return sema.getBuiltinType("PrefetchOptions"),
3383533872
33836 _ => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
33837 .struct_type => |struct_type| {
33838 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return ty;
33839 try sema.resolveTypeFieldsStruct(ty, struct_obj);
33840 return ty;
33841 },
33842 .union_type => |union_type| {
33843 const union_obj = mod.unionPtr(union_type.index);
33844 try sema.resolveTypeFieldsUnion(ty, union_obj);
33845 return ty;
33873 _ => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
33874 .type_struct,
33875 .type_struct_ns,
33876 .type_union_tagged,
33877 .type_union_untagged,
33878 .type_union_safety,
33879 => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
33880 .struct_type => |struct_type| {
33881 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse 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,
3384633891 },
33847
3384833892 else => return ty,
3384933893 },
3385033894 }
......@@ -34167,7 +34211,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3416734211 }
3416834212 gop.value_ptr.* = .{
3416934213 .ty = Type.noreturn,
34170 .abi_align = 0,
34214 .abi_align = .none,
3417134215 .default_val = .none,
3417234216 .is_comptime = is_comptime,
3417334217 .offset = undefined,
......@@ -34704,7 +34748,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3470434748
3470534749 gop.value_ptr.* = .{
3470634750 .ty = field_ty,
34707 .abi_align = 0,
34751 .abi_align = .none,
3470834752 };
3470934753
3471034754 if (align_ref != .none) {
......@@ -34720,7 +34764,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3472034764 else => |e| return e,
3472134765 };
3472234766 } else {
34723 gop.value_ptr.abi_align = 0;
34767 gop.value_ptr.abi_align = .none;
3472434768 }
3472534769 }
3472634770
......@@ -34935,231 +34979,311 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
3493534979pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3493634980 const mod = sema.mod;
3493734981 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,
3493835048 .empty_struct_type => Value.empty_struct,
34939 else => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
34940 .int_type => |int_type| {
34941 if (int_type.bits == 0) {
34942 return try mod.intValue(ty, 0);
34943 } else {
34944 return null;
34945 }
34946 },
34947
34948 .ptr_type,
34949 .error_union_type,
34950 .func_type,
34951 .anyframe_type,
34952 .error_set_type,
34953 .inferred_error_set_type,
35049 // values, not types
35050 .undef,
35051 .zero,
35052 .zero_usize,
35053 .zero_u8,
35054 .one,
35055 .one_usize,
35056 .one_u8,
35057 .four_u8,
35058 .negative_one,
35059 .calling_convention_c,
35060 .calling_convention_inline,
35061 .void_value,
35062 .unreachable_value,
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,
3495435084 => null,
34955
34956 inline .array_type, .vector_type => |seq_type, seq_tag| {
34957 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
34958 if (seq_type.len + @intFromBool(has_sentinel) == 0) return (try mod.intern(.{ .aggregate = .{
34959 .ty = ty.toIntern(),
34960 .storage = .{ .elems = &.{} },
34961 } })).toValue();
34962
34963 if (try sema.typeHasOnePossibleValue(seq_type.child.toType())) |opv| {
34964 return (try mod.intern(.{ .aggregate = .{
35085 .simple_type, // handled above
35086 // values, not types
35087 .undef,
35088 .runtime_value,
35089 .simple_value,
35090 .ptr_decl,
35091 .ptr_mut_decl,
35092 .ptr_comptime_field,
35093 .ptr_int,
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 = .{
3496535154 .ty = ty.toIntern(),
34966 .storage = .{ .repeated_elem = opv.toIntern() },
35155 .storage = .{ .elems = &.{} },
3496735156 } })).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,
35018 .noreturn => Value.@"unreachable",
35019 .null => Value.null,
35020 .undefined => Value.undef,
35158 if (try sema.typeHasOnePossibleValue(seq_type.child.toType())) |opv| {
35159 return (try mod.intern(.{ .aggregate = .{
35160 .ty = ty.toIntern(),
35161 .storage = .{ .repeated_elem = opv.toIntern() },
35162 } })).toValue();
35163 }
35164 return null;
35165 },
3502135166
35022 .generic_poison => return error.GenericPoison,
35023 },
35024 .struct_type => |struct_type| {
35025 const resolved_ty = try sema.resolveTypeFields(ty);
35026 if (mod.structPtrUnwrap(struct_type.index)) |s| {
35027 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
35028 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
35029 if (field.is_comptime) {
35030 field_val.* = field.default_val;
35031 continue;
35032 }
35033 if (field.ty.eql(resolved_ty, sema.mod)) {
35034 const msg = try Module.ErrorMsg.create(
35035 sema.gpa,
35036 s.srcLoc(sema.mod),
35037 "struct '{}' depends on itself",
35038 .{ty.fmt(sema.mod)},
35039 );
35040 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
35041 return sema.failWithOwnedErrorMsg(msg);
35167 .struct_type => |struct_type| {
35168 const resolved_ty = try sema.resolveTypeFields(ty);
35169 if (mod.structPtrUnwrap(struct_type.index)) |s| {
35170 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
35171 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
35172 if (field.is_comptime) {
35173 field_val.* = field.default_val;
35174 continue;
35175 }
35176 if (field.ty.eql(resolved_ty, sema.mod)) {
35177 const msg = try Module.ErrorMsg.create(
35178 sema.gpa,
35179 s.srcLoc(sema.mod),
35180 "struct '{}' depends on itself",
35181 .{ty.fmt(sema.mod)},
35182 );
35183 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
35184 return sema.failWithOwnedErrorMsg(msg);
35185 }
35186 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {
35187 field_val.* = try field_opv.intern(field.ty, mod);
35188 } else return null;
3504235189 }
35043 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {
35044 field_val.* = try field_opv.intern(field.ty, mod);
35045 } else return null;
35190
35191 // In this case the struct has no runtime-known fields and
35192 // therefore has one possible value.
35193 return (try mod.intern(.{ .aggregate = .{
35194 .ty = ty.toIntern(),
35195 .storage = .{ .elems = field_vals },
35196 } })).toValue();
3504635197 }
3504735198
35048 // In this case the struct has no runtime-known fields and
35199 // In this case the struct has no fields at all and
3504935200 // therefore has one possible value.
3505035201 return (try mod.intern(.{ .aggregate = .{
3505135202 .ty = ty.toIntern(),
35052 .storage = .{ .elems = field_vals },
35203 .storage = .{ .elems = &.{} },
3505335204 } })).toValue();
35054 }
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 },
35205 },
3507635206
35077 .union_type => |union_type| {
35078 const resolved_ty = try sema.resolveTypeFields(ty);
35079 const union_obj = mod.unionPtr(union_type.index);
35080 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse
35081 return null;
35082 const fields = union_obj.fields.values();
35083 if (fields.len == 0) {
35084 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
35085 return only.toValue();
35086 }
35087 const only_field = fields[0];
35088 if (only_field.ty.eql(resolved_ty, sema.mod)) {
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;
35207 .anon_struct_type => |tuple| {
35208 for (tuple.values) |val| {
35209 if (val == .none) return null;
35210 }
35211 // In this case the struct has all comptime-known fields and
35212 // therefore has one possible value.
35213 // TODO: write something like getCoercedInts to avoid needing to dupe
35214 return (try mod.intern(.{ .aggregate = .{
35215 .ty = ty.toIntern(),
35216 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values) },
35217 } })).toValue();
35218 },
3511135219
35112 if (try sema.typeHasOnePossibleValue(enum_type.tag_ty.toType())) |int_opv| {
35113 const only = try mod.intern(.{ .enum_tag = .{
35114 .ty = ty.toIntern(),
35115 .int = int_opv.toIntern(),
35116 } });
35220 .union_type => |union_type| {
35221 const resolved_ty = try sema.resolveTypeFields(ty);
35222 const union_obj = mod.unionPtr(union_type.index);
35223 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse
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() });
3511735228 return only.toValue();
3511835229 }
35119
35120 return null;
35230 const only_field = fields[0];
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();
3512135249 },
35122 .auto, .explicit => {
35123 if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null;
3512435250
35125 switch (enum_type.names.len) {
35126 0 => {
35127 const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
35251 .enum_type => |enum_type| switch (enum_type.tag_mode) {
35252 .nonexhaustive => {
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 } });
3512835260 return only.toValue();
35129 },
35130 1 => return try mod.getCoerced((if (enum_type.values.len == 0)
35131 try mod.intern(.{ .int = .{
35132 .ty = enum_type.tag_ty,
35133 .storage = .{ .u64 = 0 },
35134 } })
35135 else
35136 enum_type.values[0]).toValue(), ty),
35137 else => return null,
35138 }
35261 }
35262
35263 return null;
35264 },
35265 .auto, .explicit => {
35266 if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null;
35267
35268 switch (enum_type.names.len) {
35269 0 => {
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 },
3513935283 },
35140 },
3514135284
35142 // values, not types
35143 .undef,
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,
35285 else => unreachable,
35286 },
3516335287 },
3516435288 };
3516535289}
......@@ -35264,15 +35388,19 @@ fn analyzeComptimeAlloc(
3526435388 sema: *Sema,
3526535389 block: *Block,
3526635390 var_type: Type,
35267 alignment: u32,
35391 alignment: Alignment,
3526835392) CompileError!Air.Inst.Ref {
35393 const mod = sema.mod;
35394
3526935395 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
3527035396 _ = try sema.typeHasOnePossibleValue(var_type);
3527135397
35272 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
35273 .pointee_type = var_type,
35274 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),
35275 .@"align" = alignment,
35398 const ptr_type = try mod.ptrType(.{
35399 .child = var_type.toIntern(),
35400 .flags = .{
35401 .alignment = alignment,
35402 .address_space = target_util.defaultAddressSpace(mod.getTarget(), .global_constant),
35403 },
3527635404 });
3527735405
3527835406 var anon_decl = try block.startAnonDecl();
......@@ -35283,15 +35411,15 @@ fn analyzeComptimeAlloc(
3528335411 // There will be stores before the first load, but they may be to sub-elements or
3528435412 // sub-fields. So we need to initialize with undef to allow the mechanism to expand
3528535413 // 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(),
3528735415 alignment,
3528835416 );
35289 const decl = sema.mod.declPtr(decl_index);
35290 decl.@"align" = alignment;
35417 const decl = mod.declPtr(decl_index);
35418 decl.alignment = alignment;
3529135419
3529235420 try sema.comptime_mutable_decls.append(decl_index);
35293 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
35294 return sema.addConstant(ptr_type, (try sema.mod.intern(.{ .ptr = .{
35421 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
35422 return sema.addConstant(ptr_type, (try mod.intern(.{ .ptr = .{
3529535423 .ty = ptr_type.toIntern(),
3529635424 .addr = .{ .mut_decl = .{
3529735425 .decl = decl_index,
......@@ -35676,14 +35804,10 @@ fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {
3567635804/// Not valid to call for packed unions.
3567735805/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.
3567835806fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 {
35679 const mod = sema.mod;
35680 if (field.ty.zigTypeTag(mod) == .NoReturn) {
35681 return @as(u32, 0);
35682 } else if (field.abi_align == 0) {
35683 return sema.typeAbiAlignment(field.ty);
35684 } else {
35685 return field.abi_align;
35686 }
35807 return @intCast(u32, if (field.ty.isNoReturn(sema.mod))
35808 0
35809 else
35810 field.abi_align.toByteUnitsOptional() orelse try sema.typeAbiAlignment(field.ty));
3568735811}
3568835812
3568935813/// Synchronize logic with `Type.isFnOrHasRuntimeBits`.
......@@ -36334,16 +36458,16 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3633436458 const mod = sema.mod;
3633536459 const ptr_info = ptr_ty.ptrInfo(mod);
3633636460 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;
3633836462 const parent_ty = ptr_ty.childType(mod);
3633936463
36340 const VI = Type.Payload.Pointer.Data.VectorIndex;
36464 const VI = InternPool.Key.PtrType.VectorIndex;
3634136465
3634236466 const vector_info: struct {
3634336467 host_size: u16 = 0,
3634436468 alignment: u32 = 0,
3634536469 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: {
3634736471 const elem_bits = elem_ty.bitSize(mod);
3634836472 if (elem_bits == 0) break :blk .{};
3634936473 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 {
3635136475
3635236476 break :blk .{
3635336477 .host_size = @intCast(u16, parent_ty.arrayLen(mod)),
36354 .alignment = @intCast(u16, parent_ty.abiAlignment(mod)),
36478 .alignment = @intCast(u32, parent_ty.abiAlignment(mod)),
3635536479 .vector_index = if (offset) |some| @enumFromInt(VI, some) else .runtime,
3635636480 };
3635736481 } else .{};
3635836482
36359 const alignment: u32 = a: {
36483 const alignment: Alignment = a: {
3636036484 // Calculate the new pointer alignment.
36361 if (ptr_info.@"align" == 0) {
36362 if (vector_info.alignment != 0) break :a vector_info.alignment;
36485 if (ptr_info.flags.alignment == .none) {
36486 if (vector_info.alignment != 0) break :a Alignment.fromNonzeroByteUnits(vector_info.alignment);
3636336487 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
36364 break :a 0;
36488 break :a .none;
3636536489 }
3636636490 // If the addend is not a comptime-known value we can still count on
3636736491 // it being a multiple of the type size.
......@@ -36371,18 +36495,27 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3637136495 // The resulting pointer is aligned to the lcd between the offset (an
3637236496 // arbitrary number) and the alignment factor (always a power of two,
3637336497 // 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);
3637536503 break :a new_align;
3637636504 };
36377 return try Type.ptr(sema.arena, sema.mod, .{
36378 .pointee_type = elem_ty,
36379 .mutable = ptr_info.mutable,
36380 .@"addrspace" = ptr_info.@"addrspace",
36381 .@"allowzero" = allow_zero,
36382 .@"volatile" = ptr_info.@"volatile",
36383 .@"align" = alignment,
36384 .host_size = vector_info.host_size,
36385 .vector_index = vector_info.vector_index,
36505 return mod.ptrType(.{
36506 .child = elem_ty.toIntern(),
36507 .flags = .{
36508 .alignment = alignment,
36509 .is_const = ptr_info.flags.is_const,
36510 .is_volatile = ptr_info.flags.is_volatile,
36511 .is_allowzero = is_allowzero,
36512 .address_space = ptr_info.flags.address_space,
36513 .vector_index = vector_info.vector_index,
36514 },
36515 .packed_offset = .{
36516 .host_size = vector_info.host_size,
36517 .bit_offset = 0,
36518 },
3638636519 });
3638736520}
3638836521
src/Zir.zig+3
......@@ -2005,6 +2005,8 @@ pub const Inst = struct {
20052005 /// The tag type is specified so that it is safe to bitcast between `[]u32`
20062006 /// and `[]Ref`.
20072007 pub const Ref = enum(u32) {
2008 u0_type = @intFromEnum(InternPool.Index.u0_type),
2009 i0_type = @intFromEnum(InternPool.Index.i0_type),
20082010 u1_type = @intFromEnum(InternPool.Index.u1_type),
20092011 u8_type = @intFromEnum(InternPool.Index.u8_type),
20102012 i8_type = @intFromEnum(InternPool.Index.i8_type),
......@@ -2064,6 +2066,7 @@ pub const Inst = struct {
20642066 single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),
20652067 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
20662068 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),
20672070 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
20682071 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
20692072 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
23082308 const ptr_info = ptr_ty.ptrInfo(mod);
23092309 const ty = ptr_ty.childType(mod);
23102310
2311 if (ptr_info.host_size == 0) {
2311 if (ptr_info.packed_offset.host_size == 0) {
23122312 try func.store(lhs, rhs, ty, 0);
23132313 } else {
23142314 // at this point we have a non-natural alignment, we must
23152315 // 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
23182318 if (isByRef(int_elem_ty, mod)) {
23192319 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
23202320 }
23212321
23222322 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);
23242324 mask ^= ~@as(u64, 0);
2325 const shift_val = if (ptr_info.host_size <= 4)
2326 WValue{ .imm32 = ptr_info.bit_offset }
2325 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2326 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
23272327 else
2328 WValue{ .imm64 = ptr_info.bit_offset };
2329 const mask_val = if (ptr_info.host_size <= 4)
2328 WValue{ .imm64 = ptr_info.packed_offset.bit_offset };
2329 const mask_val = if (ptr_info.packed_offset.host_size <= 4)
23302330 WValue{ .imm32 = @truncate(u32, mask) }
23312331 else
23322332 WValue{ .imm64 = mask };
......@@ -2335,7 +2335,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
23352335 const loaded = try func.load(lhs, int_elem_ty, 0);
23362336 const anded = try func.binOp(loaded, mask_val, int_elem_ty, .@"and");
23372337 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: {
23392339 break :shifted try func.binOp(extended_value, shift_val, int_elem_ty, .shl);
23402340 } else extended_value;
23412341 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 {
24682468 break :result new_local;
24692469 }
24702470
2471 if (ptr_info.host_size == 0) {
2471 if (ptr_info.packed_offset.host_size == 0) {
24722472 const stack_loaded = try func.load(operand, ty, 0);
24732473 break :result try stack_loaded.toLocal(func, ty);
24742474 }
24752475
24762476 // at this point we have a non-natural alignment, we must
24772477 // shift the value to obtain the correct bit.
2478 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);
2479 const shift_val = if (ptr_info.host_size <= 4)
2480 WValue{ .imm32 = ptr_info.bit_offset }
2481 else if (ptr_info.host_size <= 8)
2482 WValue{ .imm64 = ptr_info.bit_offset }
2478 const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
2479 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2480 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
2481 else if (ptr_info.packed_offset.host_size <= 8)
2482 WValue{ .imm64 = ptr_info.packed_offset.bit_offset }
24832483 else
24842484 return func.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{});
24852485
......@@ -3699,7 +3699,7 @@ fn structFieldPtr(
36993699 const offset = switch (struct_ty.containerLayout(mod)) {
37003700 .Packed => switch (struct_ty.zigTypeTag(mod)) {
37013701 .Struct => offset: {
3702 if (result_ty.ptrInfo(mod).host_size != 0) {
3702 if (result_ty.ptrInfo(mod).packed_offset.host_size != 0) {
37033703 break :offset @as(u32, 0);
37043704 }
37053705 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 {
3434 if (ty.structFieldCount(mod) > 1) return memory;
3535 // When the struct's alignment is non-natural
3636 const field = ty.structFields(mod).values()[0];
37 if (field.abi_align != 0) {
38 if (field.abi_align > field.ty.abiAlignment(mod)) {
37 if (field.abi_align != .none) {
38 if (field.abi_align.toByteUnitsOptional().? > field.ty.abiAlignment(mod)) {
3939 return memory;
4040 }
4141 }
src/arch/x86_64/CodeGen.zig+10-10
......@@ -694,7 +694,7 @@ pub fn generate(
694694 FrameAlloc.init(.{
695695 .size = 0,
696696 .alignment = if (mod.align_stack_fns.get(module_fn_index)) |set_align_stack|
697 set_align_stack.alignment
697 @intCast(u32, set_align_stack.alignment.toByteUnitsOptional().?)
698698 else
699699 1,
700700 }),
......@@ -5254,12 +5254,12 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn
52545254 const mod = self.bin_file.options.module.?;
52555255 const ptr_info = ptr_ty.ptrInfo(mod);
52565256
5257 const val_ty = ptr_info.pointee_type;
5257 const val_ty = ptr_info.child.toType();
52585258 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));
52595259 const limb_abi_size: u32 = @min(val_abi_size, 8);
52605260 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);
5262 const val_bit_off = ptr_info.bit_offset % limb_abi_bits;
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.packed_offset.bit_offset % limb_abi_bits;
52635263 const val_extra_bits = self.regExtraBits(val_ty);
52645264
52655265 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 {
53855385 else
53865386 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) {
53895389 try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv);
53905390 } else {
53915391 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
54005400 const ptr_info = ptr_ty.ptrInfo(mod);
54015401 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);
54045404 const limb_abi_bits = limb_abi_size * 8;
54055405
54065406 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);
5408 const src_bit_off = ptr_info.bit_offset % limb_abi_bits;
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.packed_offset.bit_offset % limb_abi_bits;
54095409
54105410 const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);
54115411 const ptr_lock = self.register_manager.lockRegAssumeUnused(ptr_reg);
......@@ -5516,7 +5516,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
55165516 const ptr_mcv = try self.resolveInst(bin_op.lhs);
55175517 const ptr_ty = self.typeOf(bin_op.lhs);
55185518 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) {
55205520 try self.packedStore(ptr_ty, ptr_mcv, src_mcv);
55215521 } else {
55225522 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
55455545 const field_offset = @intCast(i32, switch (container_ty.containerLayout(mod)) {
55465546 .Auto, .Extern => container_ty.structFieldOffset(index, mod),
55475547 .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)
55495549 container_ty.packedStructFieldByteOffset(index, mod)
55505550 else
55515551 0,
src/arch/x86_64/abi.zig+4-4
......@@ -223,8 +223,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {
223223 var byte_i: usize = 0; // out of 8
224224 const fields = ty.structFields(mod);
225225 for (fields.values()) |field| {
226 if (field.abi_align != 0) {
227 if (field.abi_align < field.ty.abiAlignment(mod)) {
226 if (field.abi_align != .none) {
227 if (field.abi_align.toByteUnitsOptional().? < field.ty.abiAlignment(mod)) {
228228 return memory_class;
229229 }
230230 }
......@@ -340,8 +340,8 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class {
340340
341341 const fields = ty.unionFields(mod);
342342 for (fields.values()) |field| {
343 if (field.abi_align != 0) {
344 if (field.abi_align < field.ty.abiAlignment(mod)) {
343 if (field.abi_align != .none) {
344 if (field.abi_align.toByteUnitsOptional().? < field.ty.abiAlignment(mod)) {
345345 return memory_class;
346346 }
347347 }
src/codegen/c.zig+33-28
......@@ -1714,7 +1714,7 @@ pub const DeclGen = struct {
17141714 ty: Type,
17151715 name: CValue,
17161716 qualifiers: CQualifiers,
1717 alignment: u32,
1717 alignment: u64,
17181718 kind: CType.Kind,
17191719 ) error{ OutOfMemory, AnalysisFail }!void {
17201720 const mod = dg.module;
......@@ -1733,10 +1733,10 @@ pub const DeclGen = struct {
17331733 const store = &dg.ctypes.set;
17341734 const mod = dg.module;
17351735
1736 switch (std.math.order(alignas.@"align", alignas.abi)) {
1737 .lt => try w.print("zig_under_align({}) ", .{alignas.getAlign()}),
1736 switch (alignas.abiOrder()) {
1737 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
17381738 .eq => {},
1739 .gt => try w.print("zig_align({}) ", .{alignas.getAlign()}),
1739 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
17401740 }
17411741
17421742 const trailing =
......@@ -1840,7 +1840,7 @@ pub const DeclGen = struct {
18401840 decl.ty,
18411841 .{ .decl = decl_index },
18421842 CQualifiers.init(.{ .@"const" = variable.is_const }),
1843 decl.@"align",
1843 @intCast(u32, decl.alignment.toByteUnits(0)),
18441844 .complete,
18451845 );
18461846 try fwd_decl_writer.writeAll(";\n");
......@@ -2314,10 +2314,10 @@ fn renderAggregateFields(
23142314 const fields = cty.fields();
23152315 for (fields) |field| {
23162316 try writer.writeByteNTimes(' ', indent + 1);
2317 switch (std.math.order(field.alignas.@"align", field.alignas.abi)) {
2318 .lt => try writer.print("zig_under_align({}) ", .{field.alignas.getAlign()}),
2317 switch (field.alignas.abiOrder()) {
2318 .lt => try writer.print("zig_under_align({}) ", .{field.alignas.toByteUnits()}),
23192319 .eq => {},
2320 .gt => try writer.print("zig_align({}) ", .{field.alignas.getAlign()}),
2320 .gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),
23212321 }
23222322 const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});
23232323 try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });
......@@ -2639,7 +2639,7 @@ pub fn genFunc(f: *Function) !void {
26392639 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
26402640 const lhs_ty = ctx.keys[lhs_index];
26412641 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);
26432643 }
26442644 };
26452645 free_locals.sort(SortContext{ .keys = free_locals.keys() });
......@@ -2690,7 +2690,7 @@ pub fn genDecl(o: *Object) !void {
26902690 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
26912691 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
26922692 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);
26942694 if (decl.@"linksection" != .none) try w.writeAll(", read, write)");
26952695 try w.writeAll(" = ");
26962696 try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);
......@@ -2701,14 +2701,14 @@ pub fn genDecl(o: *Object) !void {
27012701 const fwd_decl_writer = o.dg.fwd_decl.writer();
27022702
27032703 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);
27052705 try fwd_decl_writer.writeAll(";\n");
27062706
27072707 const w = o.writer();
27082708 if (!is_global) try w.writeAll("static ");
27092709 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
27102710 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);
27122712 if (decl.@"linksection" != .none) try w.writeAll(", read)");
27132713 try w.writeAll(" = ");
27142714 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);
......@@ -3324,7 +3324,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33243324 const ptr_ty = f.typeOf(ty_op.operand);
33253325 const ptr_scalar_ty = ptr_ty.scalarType(mod);
33263326 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
33293329 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) {
33303330 try reap(f, inst, &.{ty_op.operand});
......@@ -3335,7 +3335,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33353335
33363336 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;
33393342 const is_array = lowersToArray(src_ty, mod);
33403343 const need_memcpy = !is_aligned or is_array;
33413344
......@@ -3354,12 +3357,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33543357 try writer.writeAll(", sizeof(");
33553358 try f.renderType(writer, src_ty);
33563359 try writer.writeAll("))");
3357 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {
3358 const host_bits: u16 = ptr_info.host_size * 8;
3360 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3361 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;
33593362 const host_ty = try mod.intType(.unsigned, host_bits);
33603363
33613364 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
33643367 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 {
35933596
35943597 if (val_is_undef) {
35953598 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) {
35973600 const writer = f.object.writer();
35983601 try writer.writeAll("memset(");
35993602 try f.writeCValue(writer, ptr_val, .FunctionArgument);
36003603 try writer.writeAll(", 0xaa, sizeof(");
3601 try f.renderType(writer, ptr_info.pointee_type);
3604 try f.renderType(writer, ptr_info.child.toType());
36023605 try writer.writeAll("));\n");
36033606 }
36043607 return .none;
36053608 }
36063609
3607 const is_aligned = ptr_info.@"align" == 0 or
3608 ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(mod);
3609 const is_array = lowersToArray(ptr_info.pointee_type, mod);
3610 const is_aligned = if (ptr_info.flags.alignment.toByteUnitsOptional()) |alignment|
3611 alignment >= src_ty.abiAlignment(mod)
3612 else
3613 true;
3614 const is_array = lowersToArray(ptr_info.child.toType(), mod);
36103615 const need_memcpy = !is_aligned or is_array;
36113616
36123617 const src_val = try f.resolveInst(bin_op.rhs);
......@@ -3618,7 +3623,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
36183623 if (need_memcpy) {
36193624 // For this memcpy to safely work we need the rhs to have the same
36203625 // 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
36233628 // If the source is a constant, writeCValue will emit a brace initialization
36243629 // so work around this by initializing into new local.
......@@ -3646,12 +3651,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
36463651 if (src_val == .constant) {
36473652 try freeLocal(f, inst, array_src.new_local, 0);
36483653 }
3649 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {
3650 const host_bits = ptr_info.host_size * 8;
3654 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3655 const host_bits = ptr_info.packed_offset.host_size * 8;
36513656 const host_ty = try mod.intType(.unsigned, host_bits);
36523657
36533658 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
36563661 const src_bits = src_ty.bitSize(mod);
36573662
......@@ -3663,7 +3668,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
36633668 defer mask.deinit();
36643669
36653670 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);
36673672 try mask.bitNotWrap(&mask, .unsigned, host_bits);
36683673
36693674 const mask_val = try mod.intValue_big(host_ty, mask.toConst());
......@@ -5201,7 +5206,7 @@ fn fieldLocation(
52015206 else
52025207 .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } };
52035208 } 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)
52055210 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }
52065211 else
52075212 .begin,
src/codegen/c/type.zig+31-28
......@@ -6,6 +6,7 @@ const assert = std.debug.assert;
66const autoHash = std.hash.autoHash;
77const Target = std.Target;
88
9const Alignment = @import("../../InternPool.zig").Alignment;
910const Module = @import("../../Module.zig");
1011const Type = @import("../../type.zig").Type;
1112
......@@ -280,16 +281,15 @@ pub const CType = extern union {
280281 };
281282
282283 pub const AlignAs = struct {
283 @"align": std.math.Log2Int(u32),
284 abi: std.math.Log2Int(u32),
284 @"align": Alignment,
285 abi: Alignment,
285286
286 pub fn init(alignment: u32, abi_alignment: u32) AlignAs {
287 const actual_align = if (alignment != 0) alignment else abi_alignment;
288 assert(std.math.isPowerOfTwo(actual_align));
289 assert(std.math.isPowerOfTwo(abi_alignment));
287 pub fn init(alignment: u64, abi_alignment: u32) AlignAs {
288 const @"align" = Alignment.fromByteUnits(alignment);
289 const abi_align = Alignment.fromNonzeroByteUnits(abi_alignment);
290290 return .{
291 .@"align" = std.math.log2_int(u32, actual_align),
292 .abi = std.math.log2_int(u32, abi_alignment),
291 .@"align" = if (@"align" != .none) @"align" else abi_align,
292 .abi = abi_align,
293293 };
294294 }
295295 pub fn abiAlign(ty: Type, mod: *Module) AlignAs {
......@@ -308,8 +308,14 @@ pub const CType = extern union {
308308 return init(union_payload_align, union_payload_align);
309309 }
310310
311 pub fn getAlign(self: AlignAs) u32 {
312 return @as(u32, 1) << self.@"align";
311 pub fn order(lhs: AlignAs, rhs: AlignAs) std.math.Order {
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().?;
313319 }
314320 };
315321
......@@ -1298,7 +1304,7 @@ pub const CType = extern union {
12981304 const slice = self.storage.anon.fields[0..fields_len];
12991305 mem.sort(Field, slice, {}, struct {
13001306 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);
13021308 }
13031309 }.before);
13041310 return slice;
......@@ -1424,7 +1430,7 @@ pub const CType = extern union {
14241430
14251431 .Pointer => {
14261432 const info = ty.ptrInfo(mod);
1427 switch (info.size) {
1433 switch (info.flags.size) {
14281434 .Slice => {
14291435 if (switch (kind) {
14301436 .forward, .forward_parameter => @as(Index, undefined),
......@@ -1454,27 +1460,24 @@ pub const CType = extern union {
14541460 },
14551461
14561462 .One, .Many, .C => {
1457 const t: Tag = switch (info.@"volatile") {
1458 false => switch (info.mutable) {
1459 true => .pointer,
1460 false => .pointer_const,
1463 const t: Tag = switch (info.flags.is_volatile) {
1464 false => switch (info.flags.is_const) {
1465 false => .pointer,
1466 true => .pointer_const,
14611467 },
1462 true => switch (info.mutable) {
1463 true => .pointer_volatile,
1464 false => .pointer_const_volatile,
1468 true => switch (info.flags.is_const) {
1469 false => .pointer_volatile,
1470 true => .pointer_const_volatile,
14651471 },
14661472 };
14671473
1468 const pointee_ty = if (info.host_size > 0 and info.vector_index == .none)
1469 try mod.intType(.unsigned, info.host_size * 8)
1474 const pointee_ty = if (info.packed_offset.host_size > 0 and
1475 info.flags.vector_index == .none)
1476 try mod.intType(.unsigned, info.packed_offset.host_size * 8)
14701477 else
1471 info.pointee_type;
1478 info.child.toType();
14721479
1473 if (if (info.size == .C and pointee_ty.ip_index == .u8_type)
1474 Tag.char.toIndex()
1475 else
1476 try lookup.typeToIndex(pointee_ty, .forward)) |child_idx|
1477 {
1480 if (try lookup.typeToIndex(pointee_ty, .forward)) |child_idx| {
14781481 self.storage = .{ .child = .{
14791482 .base = .{ .tag = t },
14801483 .data = child_idx,
......@@ -1586,7 +1589,7 @@ pub const CType = extern union {
15861589 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
15871590
15881591 const field_align = AlignAs.fieldAlign(ty, field_i, mod);
1589 if (field_align.@"align" < field_align.abi) {
1592 if (field_align.abiOrder().compare(.lt)) {
15901593 is_packed = true;
15911594 if (!lookup.isMutable()) break;
15921595 }
src/codegen/llvm.zig+74-74
......@@ -885,7 +885,7 @@ pub const Object = struct {
885885 const llvm_func = try dg.resolveLlvmFunction(decl_index);
886886
887887 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().?);
889889 dg.addFnAttr(llvm_func, "noinline");
890890 } else {
891891 DeclGen.removeFnAttr(llvm_func, "alignstack");
......@@ -1063,15 +1063,12 @@ pub const Object = struct {
10631063 if (param_ty.zigTypeTag(mod) != .Optional) {
10641064 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
10651065 }
1066 if (!ptr_info.mutable) {
1066 if (ptr_info.flags.is_const) {
10671067 dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");
10681068 }
1069 if (ptr_info.@"align" != 0) {
1070 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
1071 } else {
1072 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
1073 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
1074 }
1069 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
1070 @max(ptr_info.child.toType().abiAlignment(mod), 1);
1071 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
10751072 const ptr_param = llvm_func.getParam(llvm_arg_i);
10761073 llvm_arg_i += 1;
10771074 const len_param = llvm_func.getParam(llvm_arg_i);
......@@ -1474,7 +1471,7 @@ pub const Object = struct {
14741471 .Int => {
14751472 const info = ty.intInfo(mod);
14761473 assert(info.bits != 0);
1477 const name = try ty.nameAlloc(gpa, o.module);
1474 const name = try o.allocTypeName(ty);
14781475 defer gpa.free(name);
14791476 const dwarf_encoding: c_uint = switch (info.signedness) {
14801477 .signed => DW.ATE.signed,
......@@ -1536,7 +1533,7 @@ pub const Object = struct {
15361533 const di_file = try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope);
15371534 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);
15401537 defer gpa.free(name);
15411538
15421539 const enum_di_ty = dib.createEnumerationType(
......@@ -1557,7 +1554,7 @@ pub const Object = struct {
15571554 },
15581555 .Float => {
15591556 const bits = ty.floatBits(target);
1560 const name = try ty.nameAlloc(gpa, o.module);
1557 const name = try o.allocTypeName(ty);
15611558 defer gpa.free(name);
15621559 const di_type = dib.createBasicType(name, bits, DW.ATE.float);
15631560 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
......@@ -1571,7 +1568,7 @@ pub const Object = struct {
15711568 },
15721569 .Pointer => {
15731570 // 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
15761573 if (ptr_info.sentinel != .none or
15771574 ptr_info.flags.address_space != .generic or
......@@ -1607,7 +1604,7 @@ pub const Object = struct {
16071604 const ptr_ty = ty.slicePtrFieldType(mod);
16081605 const len_ty = Type.usize;
16091606
1610 const name = try ty.nameAlloc(gpa, o.module);
1607 const name = try o.allocTypeName(ty);
16111608 defer gpa.free(name);
16121609 const di_file: ?*llvm.DIFile = null;
16131610 const line = 0;
......@@ -1683,7 +1680,7 @@ pub const Object = struct {
16831680 }
16841681
16851682 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);
16871684 defer gpa.free(name);
16881685 const ptr_di_ty = dib.createPointerType(
16891686 elem_di_ty,
......@@ -1701,7 +1698,7 @@ pub const Object = struct {
17011698 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
17021699 return di_ty;
17031700 }
1704 const name = try ty.nameAlloc(gpa, o.module);
1701 const name = try o.allocTypeName(ty);
17051702 defer gpa.free(name);
17061703 const owner_decl_index = ty.getOwnerDecl(mod);
17071704 const owner_decl = o.module.declPtr(owner_decl_index);
......@@ -1738,7 +1735,7 @@ pub const Object = struct {
17381735 .Int => blk: {
17391736 const info = elem_ty.intInfo(mod);
17401737 assert(info.bits != 0);
1741 const name = try ty.nameAlloc(gpa, o.module);
1738 const name = try o.allocTypeName(ty);
17421739 defer gpa.free(name);
17431740 const dwarf_encoding: c_uint = switch (info.signedness) {
17441741 .signed => DW.ATE.signed,
......@@ -1761,7 +1758,7 @@ pub const Object = struct {
17611758 return vector_di_ty;
17621759 },
17631760 .Optional => {
1764 const name = try ty.nameAlloc(gpa, o.module);
1761 const name = try o.allocTypeName(ty);
17651762 defer gpa.free(name);
17661763 const child_ty = ty.optionalChild(mod);
17671764 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -1857,7 +1854,7 @@ pub const Object = struct {
18571854 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(err_set_di_ty));
18581855 return err_set_di_ty;
18591856 }
1860 const name = try ty.nameAlloc(gpa, o.module);
1857 const name = try o.allocTypeName(ty);
18611858 defer gpa.free(name);
18621859 const di_file: ?*llvm.DIFile = null;
18631860 const line = 0;
......@@ -1949,7 +1946,7 @@ pub const Object = struct {
19491946 },
19501947 .Struct => {
19511948 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);
19531950 defer gpa.free(name);
19541951
19551952 if (mod.typeToStruct(ty)) |struct_obj| {
......@@ -2128,7 +2125,7 @@ pub const Object = struct {
21282125 const compile_unit_scope = o.di_compile_unit.?.toScope();
21292126 const owner_decl_index = ty.getOwnerDecl(mod);
21302127
2131 const name = try ty.nameAlloc(gpa, o.module);
2128 const name = try o.allocTypeName(ty);
21322129 defer gpa.free(name);
21332130
21342131 const fwd_decl = opt_fwd_decl orelse blk: {
......@@ -2417,6 +2414,13 @@ pub const Object = struct {
24172414 assert(stack_trace_decl.has_tv);
24182415 return stack_trace_decl.val.toType();
24192416 }
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 }
24202424};
24212425
24222426pub const DeclGen = struct {
......@@ -2792,7 +2796,7 @@ pub const DeclGen = struct {
27922796 return dg.context.structType(&fields, fields.len, .False);
27932797 }
27942798 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);
27962800 return dg.context.pointerType(llvm_addrspace);
27972801 },
27982802 .Opaque => {
......@@ -3392,7 +3396,7 @@ pub const DeclGen = struct {
33923396 .opt_payload,
33933397 .elem,
33943398 .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),
33963400 .comptime_field => unreachable,
33973401 };
33983402 switch (ptr.len) {
......@@ -4034,7 +4038,6 @@ pub const DeclGen = struct {
40344038
40354039 fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value {
40364040 const mod = dg.module;
4037 const alignment = ptr_ty.ptrInfo(mod).@"align";
40384041 // Even though we are pointing at something which has zero bits (e.g. `void`),
40394042 // Pointers are defined to have bits. So we must return something here.
40404043 // The value cannot be undefined, because we use the `nonnull` annotation
......@@ -4042,7 +4045,7 @@ pub const DeclGen = struct {
40424045 // the address will never be dereferenced.
40434046 const llvm_usize = try dg.lowerType(Type.usize);
40444047 const llvm_ptr_ty = try dg.lowerType(ptr_ty);
4045 if (alignment != 0) {
4048 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {
40464049 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);
40474050 }
40484051 // Note that these 0xaa values are appropriate even in release-optimized builds
......@@ -4163,18 +4166,15 @@ pub const DeclGen = struct {
41634166 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
41644167 }
41654168 }
4166 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.@"allowzero") {
4169 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.flags.is_allowzero) {
41674170 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
41684171 }
4169 if (!ptr_info.mutable) {
4172 if (ptr_info.flags.is_const) {
41704173 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
41714174 }
4172 if (ptr_info.@"align" != 0) {
4173 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", ptr_info.@"align");
4174 } else {
4175 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
4176 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
4177 }
4175 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
4176 @max(ptr_info.child.toType().abiAlignment(mod), 1);
4177 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
41784178 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
41794179 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
41804180 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
......@@ -4806,15 +4806,12 @@ pub const FuncGen = struct {
48064806 if (param_ty.zigTypeTag(mod) != .Optional) {
48074807 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");
48084808 }
4809 if (!ptr_info.mutable) {
4809 if (ptr_info.flags.is_const) {
48104810 self.dg.addArgAttr(call, llvm_arg_i, "readonly");
48114811 }
4812 if (ptr_info.@"align" != 0) {
4813 self.dg.addArgAttrInt(call, llvm_arg_i, "align", ptr_info.@"align");
4814 } else {
4815 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
4816 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
4817 }
4812 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
4813 @max(ptr_info.child.toType().abiAlignment(mod), 1);
4814 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
48184815 },
48194816 };
48204817 }
......@@ -5737,7 +5734,7 @@ pub const FuncGen = struct {
57375734 const rhs = try self.resolveInst(bin_op.rhs);
57385735
57395736 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
57425739 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
57435740 if (ptr_ty.isSinglePointer(mod)) {
......@@ -8062,7 +8059,7 @@ pub const FuncGen = struct {
80628059 const ptr = try fg.resolveInst(ty_op.operand);
80638060
80648061 elide: {
8065 if (!isByRef(ptr_info.pointee_type, mod)) break :elide;
8062 if (!isByRef(ptr_info.child.toType(), mod)) break :elide;
80668063 if (!canElideLoad(fg, body_tail)) break :elide;
80678064 return ptr;
80688065 }
......@@ -8235,13 +8232,14 @@ pub const FuncGen = struct {
82358232 const ptr = try self.resolveInst(atomic_load.ptr);
82368233 const ptr_ty = self.typeOf(atomic_load.ptr);
82378234 const ptr_info = ptr_ty.ptrInfo(mod);
8238 const elem_ty = ptr_info.pointee_type;
8235 const elem_ty = ptr_info.child.toType();
82398236 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
82408237 return null;
82418238 const ordering = toLlvmAtomicOrdering(atomic_load.order);
82428239 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);
8243 const ptr_alignment = ptr_info.alignment(mod);
8244 const ptr_volatile = llvm.Bool.fromBool(ptr_info.@"volatile");
8240 const ptr_alignment = @intCast(u32, ptr_info.flags.alignment.toByteUnitsOptional() orelse
8241 ptr_info.child.toType().abiAlignment(mod));
8242 const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile);
82458243 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
82468244
82478245 if (opt_abi_llvm_ty) |abi_llvm_ty| {
......@@ -9567,7 +9565,7 @@ pub const FuncGen = struct {
95679565 const result_ty = self.typeOfIndex(inst);
95689566 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) {
95719569 // From LLVM's perspective, a pointer to a packed struct and a pointer
95729570 // to a field of a packed struct are the same. The difference is in the
95739571 // Zig pointer type which provides information for how to mask and shift
......@@ -9651,16 +9649,18 @@ pub const FuncGen = struct {
96519649 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {
96529650 const mod = self.dg.module;
96539651 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);
9657 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr(mod));
9655 const ptr_alignment = @intCast(u32, info.flags.alignment.toByteUnitsOptional() orelse
9656 elem_ty.abiAlignment(mod));
9657 const ptr_volatile = llvm.Bool.fromBool(info.flags.is_volatile);
96589658
9659 assert(info.vector_index != .runtime);
9660 if (info.vector_index != .none) {
9661 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.vector_index), .False);
9662 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);
9663 const vec_ty = vec_elem_ty.vectorType(info.host_size);
9659 assert(info.flags.vector_index != .runtime);
9660 if (info.flags.vector_index != .none) {
9661 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
9662 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9663 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
96649664
96659665 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
96669666 loaded_vector.setAlignment(ptr_alignment);
......@@ -9669,29 +9669,29 @@ pub const FuncGen = struct {
96699669 return self.builder.buildExtractElement(loaded_vector, index_u32, "");
96709670 }
96719671
9672 if (info.host_size == 0) {
9673 if (isByRef(info.pointee_type, mod)) {
9674 return self.loadByRef(ptr, info.pointee_type, ptr_alignment, info.@"volatile");
9672 if (info.packed_offset.host_size == 0) {
9673 if (isByRef(elem_ty, mod)) {
9674 return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile);
96759675 }
9676 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
9676 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
96779677 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
96789678 llvm_inst.setAlignment(ptr_alignment);
96799679 llvm_inst.setVolatile(ptr_volatile);
96809680 return llvm_inst;
96819681 }
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);
96849684 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
96859685 containing_int.setAlignment(ptr_alignment);
96869686 containing_int.setVolatile(ptr_volatile);
96879687
96889688 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);
96909690 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)) {
9694 const result_align = info.pointee_type.abiAlignment(mod);
9693 if (isByRef(elem_ty, mod)) {
9694 const result_align = elem_ty.abiAlignment(mod);
96959695 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);
96969696
96979697 const same_size_int = self.context.intType(elem_bits);
......@@ -9701,13 +9701,13 @@ pub const FuncGen = struct {
97019701 return result_ptr;
97029702 }
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) {
97059705 const same_size_int = self.context.intType(elem_bits);
97069706 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
97079707 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
97089708 }
97099709
9710 if (info.pointee_type.isPtrAtRuntime(mod)) {
9710 if (elem_ty.isPtrAtRuntime(mod)) {
97119711 const same_size_int = self.context.intType(elem_bits);
97129712 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
97139713 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
......@@ -9725,18 +9725,18 @@ pub const FuncGen = struct {
97259725 ) !void {
97269726 const mod = self.dg.module;
97279727 const info = ptr_ty.ptrInfo(mod);
9728 const elem_ty = info.pointee_type;
9728 const elem_ty = info.child.toType();
97299729 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
97309730 return;
97319731 }
97329732 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);
9736 if (info.vector_index != .none) {
9737 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.vector_index), .False);
9735 assert(info.flags.vector_index != .runtime);
9736 if (info.flags.vector_index != .none) {
9737 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
97389738 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
97419741 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
97429742 loaded_vector.setAlignment(ptr_alignment);
......@@ -9751,15 +9751,15 @@ pub const FuncGen = struct {
97519751 return;
97529752 }
97539753
9754 if (info.host_size != 0) {
9755 const int_elem_ty = self.context.intType(info.host_size * 8);
9754 if (info.packed_offset.host_size != 0) {
9755 const int_elem_ty = self.context.intType(info.packed_offset.host_size * 8);
97569756 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
97579757 assert(ordering == .NotAtomic);
97589758 containing_int.setAlignment(ptr_alignment);
97599759 containing_int.setVolatile(ptr_volatile);
97609760 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));
97619761 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);
97639763 // Convert to equally-sized integer type in order to perform the bit
97649764 // operations on the value to store
97659765 const value_bits_type = self.context.intType(elem_bits);
......@@ -9799,7 +9799,7 @@ pub const FuncGen = struct {
97999799 elem,
98009800 elem_ty.abiAlignment(mod),
98019801 self.context.intType(Type.usize.intInfo(mod).bits).constInt(size_bytes, .False),
9802 info.@"volatile",
9802 info.flags.is_volatile,
98039803 );
98049804 }
98059805
src/codegen/spirv.zig+4-4
......@@ -1210,13 +1210,13 @@ pub const DeclGen = struct {
12101210 .Pointer => {
12111211 const ptr_info = ty.ptrInfo(mod);
12121212
1213 const storage_class = spvStorageClass(ptr_info.@"addrspace");
1214 const child_ty_ref = try self.resolveType(ptr_info.pointee_type, .indirect);
1213 const storage_class = spvStorageClass(ptr_info.flags.address_space);
1214 const child_ty_ref = try self.resolveType(ptr_info.child.toType(), .indirect);
12151215 const ptr_ty_ref = try self.spv.resolve(.{ .ptr_type = .{
12161216 .storage_class = storage_class,
12171217 .child_type = child_ty_ref,
12181218 } });
1219 if (ptr_info.size != .Slice) {
1219 if (ptr_info.flags.size != .Slice) {
12201220 return ptr_ty_ref;
12211221 }
12221222
......@@ -1573,7 +1573,7 @@ pub const DeclGen = struct {
15731573 init_val,
15741574 actual_storage_class,
15751575 final_storage_class == .Generic,
1576 decl.@"align",
1576 @intCast(u32, decl.alignment.toByteUnits(0)),
15771577 );
15781578 }
15791579 }
src/link/Dwarf.zig+15-31
......@@ -163,7 +163,6 @@ pub const DeclState = struct {
163163 atom_index: Atom.Index,
164164 ty: Type,
165165 ) error{OutOfMemory}!void {
166 const arena = self.abbrev_type_arena.allocator();
167166 const dbg_info_buffer = &self.dbg_info;
168167 const target = mod.getTarget();
169168 const target_endian = target.cpu.arch.endian();
......@@ -344,10 +343,8 @@ pub const DeclState = struct {
344343 .struct_type => |struct_type| s: {
345344 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse break :s;
346345 // DW.AT.name, DW.FORM.string
347 const struct_name = try ty.nameAllocArena(arena, mod);
348 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);
349 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
350 dbg_info_buffer.appendAssumeCapacity(0);
346 try ty.print(dbg_info_buffer.writer(), mod);
347 try dbg_info_buffer.append(0);
351348
352349 if (struct_obj.layout == .Packed) {
353350 log.debug("TODO implement .debug_info for packed structs", .{});
......@@ -388,10 +385,8 @@ pub const DeclState = struct {
388385 // DW.AT.byte_size, DW.FORM.udata
389386 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
390387 // DW.AT.name, DW.FORM.string
391 const enum_name = try ty.nameAllocArena(arena, mod);
392 try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);
393 dbg_info_buffer.appendSliceAssumeCapacity(enum_name);
394 dbg_info_buffer.appendAssumeCapacity(0);
388 try ty.print(dbg_info_buffer.writer(), mod);
389 try dbg_info_buffer.append(0);
395390
396391 const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
397392 for (enum_type.names, 0..) |field_name_index, field_i| {
......@@ -422,21 +417,18 @@ pub const DeclState = struct {
422417 const union_obj = mod.typeToUnion(ty).?;
423418 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;
424419 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
428420 // TODO this is temporary to match current state of unions in Zig - we don't yet have
429421 // safety checks implemented meaning the implicit tag is not yet stored and generated
430422 // for untagged unions.
423 const is_tagged = layout.tag_size > 0;
431424 if (is_tagged) {
432425 // DW.AT.structure_type
433426 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_type));
434427 // DW.AT.byte_size, DW.FORM.udata
435428 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size);
436429 // DW.AT.name, DW.FORM.string
437 try dbg_info_buffer.ensureUnusedCapacity(union_name.len + 1);
438 dbg_info_buffer.appendSliceAssumeCapacity(union_name);
439 dbg_info_buffer.appendAssumeCapacity(0);
430 try ty.print(dbg_info_buffer.writer(), mod);
431 try dbg_info_buffer.append(0);
440432
441433 // DW.AT.member
442434 try dbg_info_buffer.ensureUnusedCapacity(9);
......@@ -460,7 +452,8 @@ pub const DeclState = struct {
460452 if (is_tagged) {
461453 try dbg_info_buffer.writer().print("AnonUnion\x00", .{});
462454 } 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);
464457 }
465458
466459 const fields = ty.unionFields(mod);
......@@ -500,15 +493,7 @@ pub const DeclState = struct {
500493 try dbg_info_buffer.append(0);
501494 }
502495 },
503 .ErrorSet => {
504 try addDbgInfoErrorSet(
505 self.abbrev_type_arena.allocator(),
506 mod,
507 ty,
508 target,
509 &self.dbg_info,
510 );
511 },
496 .ErrorSet => try addDbgInfoErrorSet(mod, ty, target, &self.dbg_info),
512497 .ErrorUnion => {
513498 const error_ty = ty.errorUnionSet(mod);
514499 const payload_ty = ty.errorUnionPayload(mod);
......@@ -523,8 +508,8 @@ pub const DeclState = struct {
523508 // DW.AT.byte_size, DW.FORM.udata
524509 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
525510 // DW.AT.name, DW.FORM.string
526 const name = try ty.nameAllocArena(arena, mod);
527 try dbg_info_buffer.writer().print("{s}\x00", .{name});
511 try ty.print(dbg_info_buffer.writer(), mod);
512 try dbg_info_buffer.append(0);
528513
529514 if (!payload_ty.isNoReturn(mod)) {
530515 // DW.AT.member
......@@ -2527,7 +2512,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
25272512
25282513 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });
25292514 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
25322517 const di_atom_index = try self.createAtom(.di_atom);
25332518 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});
......@@ -2644,7 +2629,6 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {
26442629}
26452630
26462631fn addDbgInfoErrorSet(
2647 arena: Allocator,
26482632 mod: *Module,
26492633 ty: Type,
26502634 target: std.Target,
......@@ -2658,8 +2642,8 @@ fn addDbgInfoErrorSet(
26582642 const abi_size = Type.anyerror.abiSize(mod);
26592643 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
26602644 // DW.AT.name, DW.FORM.string
2661 const name = try ty.nameAllocArena(arena, mod);
2662 try dbg_info_buffer.writer().print("{s}\x00", .{name});
2645 try ty.print(dbg_info_buffer.writer(), mod);
2646 try dbg_info_buffer.append(0);
26632647
26642648 // DW.AT.enumerator
26652649 const no_error = "(no error)";
src/type.zig+36-184
......@@ -2,7 +2,6 @@ const std = @import("std");
22const builtin = @import("builtin");
33const Value = @import("value.zig").Value;
44const assert = std.debug.assert;
5const Allocator = std.mem.Allocator;
65const Target = std.Target;
76const Module = @import("Module.zig");
87const log = std.log.scoped(.Type);
......@@ -102,10 +101,10 @@ pub const Type = struct {
102101 };
103102 }
104103
105 pub fn ptrInfoIp(ip: *const InternPool, ty: InternPool.Index) InternPool.Key.PtrType {
106 return switch (ip.indexToKey(ty)) {
104 pub fn ptrInfo(ty: Type, mod: *const Module) InternPool.Key.PtrType {
105 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
107106 .ptr_type => |p| p,
108 .opt_type => |child| switch (ip.indexToKey(child)) {
107 .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) {
109108 .ptr_type => |p| p,
110109 else => unreachable,
111110 },
......@@ -113,10 +112,6 @@ pub const Type = struct {
113112 };
114113 }
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
120115 pub fn eql(a: Type, b: Type, mod: *const Module) bool {
121116 _ = mod; // TODO: remove this parameter
122117 // The InternPool data structure hashes based on Key to make interned objects
......@@ -181,15 +176,6 @@ pub const Type = struct {
181176 return writer.print("{any}", .{start_type.ip_index});
182177 }
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
193179 /// Prints a name suitable for `@typeName`.
194180 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {
195181 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
......@@ -203,42 +189,44 @@ pub const Type = struct {
203189 .ptr_type => {
204190 const info = ty.ptrInfo(mod);
205191
206 if (info.sentinel) |s| switch (info.size) {
192 if (info.sentinel != .none) switch (info.flags.size) {
207193 .One, .C => unreachable,
208 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),
209 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),
210 } else switch (info.size) {
194 .Many => try writer.print("[*:{}]", .{info.sentinel.toValue().fmtValue(info.child.toType(), mod)}),
195 .Slice => try writer.print("[:{}]", .{info.sentinel.toValue().fmtValue(info.child.toType(), mod)}),
196 } else switch (info.flags.size) {
211197 .One => try writer.writeAll("*"),
212198 .Many => try writer.writeAll("[*]"),
213199 .C => try writer.writeAll("[*c]"),
214200 .Slice => try writer.writeAll("[]"),
215201 }
216 if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) {
217 if (info.@"align" != 0) {
218 try writer.print("align({d}", .{info.@"align"});
219 } else {
220 const alignment = info.pointee_type.abiAlignment(mod);
221 try writer.print("align({d}", .{alignment});
202 if (info.flags.alignment != .none or
203 info.packed_offset.host_size != 0 or
204 info.flags.vector_index != .none)
205 {
206 const alignment = info.flags.alignment.toByteUnitsOptional() orelse
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 });
222214 }
223
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) {
215 if (info.flags.vector_index == .runtime) {
228216 try writer.writeAll(":?");
229 } else if (info.vector_index != .none) {
230 try writer.print(":{d}", .{@intFromEnum(info.vector_index)});
217 } else if (info.flags.vector_index != .none) {
218 try writer.print(":{d}", .{@intFromEnum(info.flags.vector_index)});
231219 }
232220 try writer.writeAll(") ");
233221 }
234 if (info.@"addrspace" != .generic) {
235 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
222 if (info.flags.address_space != .generic) {
223 try writer.print("addrspace(.{s}) ", .{@tagName(info.flags.address_space)});
236224 }
237 if (!info.mutable) try writer.writeAll("const ");
238 if (info.@"volatile") try writer.writeAll("volatile ");
239 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
225 if (info.flags.is_const) try writer.writeAll("const ");
226 if (info.flags.is_volatile) try writer.writeAll("volatile ");
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);
242230 return;
243231 },
244232 .array_type => |array_type| {
......@@ -1035,9 +1023,8 @@ pub const Type = struct {
10351023 else => |e| return e,
10361024 })) continue;
10371025
1038 const field_align = if (field.abi_align != 0)
1039 field.abi_align
1040 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1026 const field_align = @intCast(u32, field.abi_align.toByteUnitsOptional() orelse
1027 switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
10411028 .scalar => |a| a,
10421029 .val => switch (strat) {
10431030 .eager => unreachable, // struct layout not resolved
......@@ -1047,7 +1034,7 @@ pub const Type = struct {
10471034 .storage = .{ .lazy_align = ty.toIntern() },
10481035 } })).toValue() },
10491036 },
1050 };
1037 });
10511038 big_align = @max(big_align, field_align);
10521039
10531040 // This logic is duplicated in Module.Struct.Field.alignment.
......@@ -1242,9 +1229,8 @@ pub const Type = struct {
12421229 else => |e| return e,
12431230 })) continue;
12441231
1245 const field_align = if (field.abi_align != 0)
1246 field.abi_align
1247 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
1232 const field_align = @intCast(u32, field.abi_align.toByteUnitsOptional() orelse
1233 switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
12481234 .scalar => |a| a,
12491235 .val => switch (strat) {
12501236 .eager => unreachable, // struct layout not resolved
......@@ -1254,7 +1240,7 @@ pub const Type = struct {
12541240 .storage = .{ .lazy_align = ty.toIntern() },
12551241 } })).toValue() },
12561242 },
1257 };
1243 });
12581244 max_align = @max(max_align, field_align);
12591245 }
12601246 return AbiAlignmentAdvanced{ .scalar = max_align };
......@@ -1883,7 +1869,7 @@ pub const Type = struct {
18831869 if (ty.isPtrLikeOptional(mod)) {
18841870 return true;
18851871 }
1886 return ty.ptrInfo(mod).@"allowzero";
1872 return ty.ptrInfo(mod).flags.is_allowzero;
18871873 }
18881874
18891875 /// See also `isPtrLikeOptional`.
......@@ -2387,15 +2373,7 @@ pub const Type = struct {
23872373
23882374 /// Asserts the type is a function or a function pointer.
23892375 pub fn fnReturnType(ty: Type, mod: *Module) Type {
2390 return fnReturnTypeIp(ty, &mod.intern_pool);
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();
2376 return mod.intern_pool.funcReturnType(ty.toIntern()).toType();
23992377 }
24002378
24012379 /// Asserts the type is a function.
......@@ -3355,58 +3333,6 @@ pub const Type = struct {
33553333 };
33563334 }
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
34103336 pub const @"u1": Type = .{ .ip_index = .u1_type };
34113337 pub const @"u8": Type = .{ .ip_index = .u8_type };
34123338 pub const @"u16": Type = .{ .ip_index = .u16_type };
......@@ -3464,80 +3390,6 @@ pub const Type = struct {
34643390
34653391 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
35413393 pub fn smallestUnsignedBits(max: u64) u16 {
35423394 if (max == 0) return 0;
35433395 const base = std.math.log2(max);
src/value.zig+5-34
......@@ -1823,7 +1823,7 @@ pub const Value = struct {
18231823 }
18241824
18251825 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());
18271827 }
18281828
18291829 /// Returns true if a Value is backed by a variable
......@@ -1851,33 +1851,9 @@ pub const Value = struct {
18511851 }
18521852
18531853 pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool {
1854 return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {
1855 .variable => false,
1856 else => val.isPtrToThreadLocalInner(mod),
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 };
1854 const backing_decl = mod.intern_pool.getBackingDecl(val.toIntern()).unwrap() orelse return false;
1855 const variable = mod.declPtr(backing_decl).getOwnedVariable(mod) orelse return false;
1856 return variable.is_threadlocal;
18811857 }
18821858
18831859 // Asserts that the provided start/end are in-bounds.
......@@ -2015,12 +1991,7 @@ pub const Value = struct {
20151991 }
20161992
20171993 pub fn isUndef(val: Value, mod: *Module) bool {
2018 if (val.ip_index == .none) return false;
2019 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
2020 .undef => true,
2021 .simple_value => |v| v == .undefined,
2022 else => false,
2023 };
1994 return val.ip_index != .none and mod.intern_pool.isUndef(val.toIntern());
20241995 }
20251996
20261997 /// TODO: check for cases such as array that is not marked undef but all the element