authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-20 14:02:04-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-20 14:02:09-04:00
log96cdd51c14337b012910a36ba93121a371509cfd
tree9b75389283a2446a2fbc6450e5755faae6410851
parent52ec121469d7bf10116fb22c122cbce8ceddd028

Type: delete legacy allocation functions


13 files changed, 976 insertions(+), 1080 deletions(-)

src/InternPool.zig+3-2
......@@ -2301,8 +2301,9 @@ pub const Alignment = enum(u6) {
23012301 return fromByteUnits(n);
23022302 }
23032303
2304 pub fn min(a: Alignment, b: Alignment) Alignment {
2305 return @enumFromInt(Alignment, @min(@intFromEnum(a), @intFromEnum(b)));
2304 pub fn order(lhs: Alignment, rhs: Alignment) std.math.Order {
2305 assert(lhs != .none and rhs != .none);
2306 return std.math.order(@intFromEnum(lhs), @intFromEnum(rhs));
23062307 }
23072308};
23082309
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+725-663
......@@ -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;
......@@ -2192,9 +2195,9 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.
21922195 .Array => return ip.stringEqlSlice(field_name, "len"),
21932196 .Pointer => {
21942197 const ptr_info = ty.ptrInfo(mod);
2195 if (ptr_info.size == .Slice) {
2198 if (ptr_info.flags.size == .Slice) {
21962199 return ip.stringEqlSlice(field_name, "ptr") or ip.stringEqlSlice(field_name, "len");
2197 } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
2200 } else if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
21982201 return ip.stringEqlSlice(field_name, "len");
21992202 } else return false;
22002203 },
......@@ -2408,11 +2411,11 @@ fn analyzeAsAlign(
24082411 block: *Block,
24092412 src: LazySrcLoc,
24102413 air_ref: Air.Inst.Ref,
2411) !u32 {
2414) !Alignment {
24122415 const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, "alignment must be comptime-known");
2413 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.
24142417 try sema.validateAlign(block, src, alignment);
2415 return alignment;
2418 return Alignment.fromNonzeroByteUnits(alignment);
24162419}
24172420
24182421fn validateAlign(
......@@ -2434,7 +2437,7 @@ pub fn resolveAlign(
24342437 block: *Block,
24352438 src: LazySrcLoc,
24362439 zir_ref: Zir.Inst.Ref,
2437) !u32 {
2440) !Alignment {
24382441 const air_ref = try sema.resolveInst(zir_ref);
24392442 return sema.analyzeAsAlign(block, src, air_ref);
24402443}
......@@ -2550,7 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
25502553 const decl_index = try anon_decl.finish(
25512554 pointee_ty,
25522555 (try mod.intern(.{ .undef = pointee_ty.toIntern() })).toValue(),
2553 alignment.toByteUnits(0),
2556 alignment,
25542557 );
25552558 sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index;
25562559 if (alignment != .none) {
......@@ -2626,9 +2629,9 @@ fn coerceResultPtr(
26262629 }
26272630 }
26282631
2629 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
2630 .pointee_type = pointee_ty,
2631 .@"addrspace" = addr_space,
2632 const ptr_ty = try mod.ptrType(.{
2633 .child = pointee_ty.toIntern(),
2634 .flags = .{ .address_space = addr_space },
26322635 });
26332636
26342637 var new_ptr = ptr;
......@@ -2656,9 +2659,9 @@ fn coerceResultPtr(
26562659 // Array coerced to Vector where element size is not equal but coercible.
26572660 .aggregate_init => {
26582661 const ty_pl = air_datas[trash_inst].ty_pl;
2659 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{
2660 .pointee_type = try sema.analyzeAsType(block, src, ty_pl.ty),
2661 .@"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 },
26622665 });
26632666
26642667 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
......@@ -2670,9 +2673,9 @@ fn coerceResultPtr(
26702673 .bitcast => {
26712674 const ty_op = air_datas[trash_inst].ty_op;
26722675 const operand_ty = sema.typeOf(ty_op.operand);
2673 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{
2674 .pointee_type = operand_ty,
2675 .@"addrspace" = addr_space,
2676 const ptr_operand_ty = try mod.ptrType(.{
2677 .child = operand_ty.toIntern(),
2678 .flags = .{ .address_space = addr_space },
26762679 });
26772680 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
26782681 new_ptr = try sema.addConstant(ptr_operand_ty, try mod.getCoerced(ptr_val, ptr_operand_ty));
......@@ -3382,13 +3385,13 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
33823385
33833386 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
33843387 const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty);
3385 return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0);
3388 return sema.analyzeComptimeAlloc(block, fn_ret_ty, .none);
33863389 }
33873390
33883391 const target = sema.mod.getTarget();
3389 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
3390 .pointee_type = sema.fn_ret_ty,
3391 .@"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) },
33923395 });
33933396
33943397 if (block.inlining != null) {
......@@ -3560,12 +3563,12 @@ fn zirAllocExtended(
35603563 break :blk try sema.resolveType(block, ty_src, type_ref);
35613564 } else undefined;
35623565
3563 const alignment: u32 = if (small.has_align) blk: {
3566 const alignment = if (small.has_align) blk: {
35643567 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);
35653568 extra_index += 1;
35663569 const alignment = try sema.resolveAlign(block, align_src, align_ref);
35673570 break :blk alignment;
3568 } else 0;
3571 } else .none;
35693572
35703573 if (block.is_comptime or small.is_comptime) {
35713574 if (small.has_type) {
......@@ -3575,7 +3578,7 @@ fn zirAllocExtended(
35753578 .tag = .inferred_alloc_comptime,
35763579 .data = .{ .inferred_alloc_comptime = .{
35773580 .decl_index = undefined,
3578 .alignment = InternPool.Alignment.fromByteUnits(alignment),
3581 .alignment = alignment,
35793582 .is_const = small.is_const,
35803583 } },
35813584 });
......@@ -3589,10 +3592,12 @@ fn zirAllocExtended(
35893592 }
35903593 const target = sema.mod.getTarget();
35913594 try sema.resolveTypeLayout(var_ty);
3592 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
3593 .pointee_type = var_ty,
3594 .@"align" = alignment,
3595 .@"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 },
35963601 });
35973602 return block.addTy(.alloc, ptr_type);
35983603 }
......@@ -3600,7 +3605,7 @@ fn zirAllocExtended(
36003605 const result_index = try block.addInstAsIndex(.{
36013606 .tag = .inferred_alloc,
36023607 .data = .{ .inferred_alloc = .{
3603 .alignment = InternPool.Alignment.fromByteUnits(alignment),
3608 .alignment = alignment,
36043609 .is_const = small.is_const,
36053610 } },
36063611 });
......@@ -3615,7 +3620,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
36153620 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
36163621 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
36173622 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3618 return sema.analyzeComptimeAlloc(block, var_ty, 0);
3623 return sema.analyzeComptimeAlloc(block, var_ty, .none);
36193624}
36203625
36213626fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -3625,7 +3630,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
36253630 const alloc_ty = sema.typeOf(alloc);
36263631
36273632 var ptr_info = alloc_ty.ptrInfo(mod);
3628 const elem_ty = ptr_info.pointee_type;
3633 const elem_ty = ptr_info.child.toType();
36293634
36303635 // Detect if all stores to an `.alloc` were comptime-known.
36313636 ct: {
......@@ -3669,11 +3674,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
36693674
36703675 var anon_decl = try block.startAnonDecl();
36713676 defer anon_decl.deinit();
3672 return sema.analyzeDeclRef(try anon_decl.finish(
3673 elem_ty,
3674 store_val,
3675 ptr_info.@"align",
3676 ));
3677 return sema.analyzeDeclRef(try anon_decl.finish(elem_ty, store_val, ptr_info.flags.alignment));
36773678 }
36783679
36793680 return sema.makePtrConst(block, alloc);
......@@ -3684,8 +3685,8 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
36843685 const alloc_ty = sema.typeOf(alloc);
36853686
36863687 var ptr_info = alloc_ty.ptrInfo(mod);
3687 ptr_info.mutable = false;
3688 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);
36893690
36903691 // Detect if a comptime value simply needs to have its type changed.
36913692 if (try sema.resolveMaybeUndefVal(alloc)) |val| {
......@@ -3724,12 +3725,12 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
37243725 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
37253726 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
37263727 if (block.is_comptime) {
3727 return sema.analyzeComptimeAlloc(block, var_ty, 0);
3728 return sema.analyzeComptimeAlloc(block, var_ty, .none);
37283729 }
37293730 const target = sema.mod.getTarget();
3730 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
3731 .pointee_type = var_ty,
3732 .@"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) },
37333734 });
37343735 try sema.queueFullTypeResolution(var_ty);
37353736 return block.addTy(.alloc, ptr_type);
......@@ -3743,13 +3744,13 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
37433744 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
37443745 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
37453746 if (block.is_comptime) {
3746 return sema.analyzeComptimeAlloc(block, var_ty, 0);
3747 return sema.analyzeComptimeAlloc(block, var_ty, .none);
37473748 }
37483749 try sema.validateVarType(block, ty_src, var_ty, false);
37493750 const target = sema.mod.getTarget();
3750 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
3751 .pointee_type = var_ty,
3752 .@"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) },
37533754 });
37543755 try sema.queueFullTypeResolution(var_ty);
37553756 return block.addTy(.alloc, ptr_type);
......@@ -3915,11 +3916,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
39153916 const new_decl_index = d: {
39163917 var anon_decl = try block.startAnonDecl();
39173918 defer anon_decl.deinit();
3918 const new_decl_index = try anon_decl.finish(
3919 final_elem_ty,
3920 store_val,
3921 ia1.alignment.toByteUnits(0),
3922 );
3919 const new_decl_index = try anon_decl.finish(final_elem_ty, store_val, ia1.alignment);
39233920 break :d new_decl_index;
39243921 };
39253922 try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index);
......@@ -5143,11 +5140,7 @@ fn storeToInferredAllocComptime(
51435140 if (operand_val.getVariable(sema.mod) != null) break :store;
51445141 var anon_decl = try block.startAnonDecl();
51455142 defer anon_decl.deinit();
5146 iac.decl_index = try anon_decl.finish(
5147 operand_ty,
5148 operand_val,
5149 iac.alignment.toByteUnits(0),
5150 );
5143 iac.decl_index = try anon_decl.finish(operand_ty, operand_val, iac.alignment);
51515144 try sema.comptime_mutable_decls.append(iac.decl_index);
51525145 return;
51535146 }
......@@ -5228,8 +5221,8 @@ fn addStrLit(sema: *Sema, block: *Block, bytes: []const u8) CompileError!Air.Ins
52285221 const duped_bytes = try sema.arena.dupe(u8, bytes);
52295222 const ty = try mod.arrayType(.{
52305223 .len = bytes.len,
5231 .child = .u8_type,
52325224 .sentinel = .zero_u8,
5225 .child = .u8_type,
52335226 });
52345227 const val = try mod.intern(.{ .aggregate = .{
52355228 .ty = ty.toIntern(),
......@@ -5840,11 +5833,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
58405833 const decl_index = if (operand.val.getFunction(sema.mod)) |function| function.owner_decl else blk: {
58415834 var anon_decl = try block.startAnonDecl();
58425835 defer anon_decl.deinit();
5843 break :blk try anon_decl.finish(
5844 operand.ty,
5845 operand.val,
5846 0,
5847 );
5836 break :blk try anon_decl.finish(operand.ty, operand.val, .none);
58485837 };
58495838 try sema.analyzeExport(block, src, options, decl_index);
58505839}
......@@ -5929,9 +5918,9 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
59295918 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
59305919 const src = LazySrcLoc.nodeOffset(extra.node);
59315920 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
5932 if (alignment > 256) {
5921 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
59335922 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
5934 alignment,
5923 alignment.toByteUnitsOptional().?,
59355924 });
59365925 }
59375926 const func_index = sema.func_index.unwrap() orelse
......@@ -6566,8 +6555,8 @@ fn checkCallArgumentCount(
65666555 .Fn => break :func_ty callee_ty,
65676556 .Pointer => {
65686557 const ptr_info = callee_ty.ptrInfo(mod);
6569 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {
6570 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();
65716560 }
65726561 },
65736562 .Optional => {
......@@ -6638,8 +6627,8 @@ fn callBuiltin(
66386627 .Fn => break :func_ty callee_ty,
66396628 .Pointer => {
66406629 const ptr_info = callee_ty.ptrInfo(mod);
6641 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {
6642 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();
66436632 }
66446633 },
66456634 else => {},
......@@ -7877,7 +7866,7 @@ fn resolveGenericInstantiationType(
78777866 .ty = new_decl.ty.toIntern(),
78787867 .index = new_func,
78797868 } })).toValue();
7880 new_decl.@"align" = 0;
7869 new_decl.alignment = .none;
78817870 new_decl.has_tv = true;
78827871 new_decl.owns_tv = true;
78837872 new_decl.analysis = .complete;
......@@ -7952,7 +7941,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
79527941 } else if (child_type.zigTypeTag(mod) == .Null) {
79537942 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)});
79547943 }
7955 const opt_type = try Type.optional(sema.arena, child_type, mod);
7944 const opt_type = try mod.optionalType(child_type.toIntern());
79567945
79577946 return sema.addType(opt_type);
79587947}
......@@ -7998,7 +7987,10 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
79987987 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime-known");
79997988 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
80007989 try sema.validateArrayElemType(block, elem_type, elem_src);
8001 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 });
80027994
80037995 return sema.addType(array_ty);
80047996}
......@@ -8018,7 +8010,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
80188010 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);
80198011 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
80208012 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime-known");
8021 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 });
80228018
80238019 return sema.addType(array_ty);
80248020}
......@@ -8393,10 +8389,12 @@ fn analyzeOptionalPayloadPtr(
83938389 }
83948390
83958391 const child_type = opt_type.optionalChild(mod);
8396 const child_pointer = try Type.ptr(sema.arena, mod, .{
8397 .pointee_type = child_type,
8398 .mutable = !optional_ptr_ty.isConstPtr(mod),
8399 .@"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 },
84008398 });
84018399
84028400 if (try sema.resolveDefinedValue(block, src, optional_ptr)) |ptr_val| {
......@@ -8460,14 +8458,15 @@ fn zirOptionalPayload(
84608458 // TODO https://github.com/ziglang/zig/issues/6597
84618459 if (true) break :t operand_ty;
84628460 const ptr_info = operand_ty.ptrInfo(mod);
8463 break :t try Type.ptr(sema.arena, mod, .{
8464 .pointee_type = ptr_info.pointee_type,
8465 .@"align" = ptr_info.@"align",
8466 .@"addrspace" = ptr_info.@"addrspace",
8467 .mutable = ptr_info.mutable,
8468 .@"allowzero" = ptr_info.@"allowzero",
8469 .@"volatile" = ptr_info.@"volatile",
8470 .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 },
84718470 });
84728471 },
84738472 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),
......@@ -8580,10 +8579,12 @@ fn analyzeErrUnionPayloadPtr(
85808579
85818580 const err_union_ty = operand_ty.childType(mod);
85828581 const payload_ty = err_union_ty.errorUnionPayload(mod);
8583 const operand_pointer_ty = try Type.ptr(sema.arena, mod, .{
8584 .pointee_type = payload_ty,
8585 .mutable = !operand_ty.isConstPtr(mod),
8586 .@"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 },
85878588 });
85888589
85898590 if (try sema.resolveDefinedValue(block, src, operand)) |ptr_val| {
......@@ -8750,7 +8751,7 @@ fn zirFunc(
87508751 block,
87518752 inst_data.src_node,
87528753 inst,
8753 0,
8754 .none,
87548755 target_util.defaultAddressSpace(target, .function),
87558756 FuncLinkSection.default,
87568757 cc,
......@@ -8879,7 +8880,7 @@ fn funcCommon(
88798880 src_node_offset: i32,
88808881 func_inst: Zir.Inst.Index,
88818882 /// null means generic poison
8882 alignment: ?u32,
8883 alignment: ?Alignment,
88838884 /// null means generic poison
88848885 address_space: ?std.builtin.AddressSpace,
88858886 /// outer null means generic poison; inner null means default link section
......@@ -9128,7 +9129,7 @@ fn funcCommon(
91289129 .return_type = return_type.toIntern(),
91299130 .cc = cc_resolved,
91309131 .cc_is_generic = cc == null,
9131 .alignment = if (alignment) |a| InternPool.Alignment.fromByteUnits(a) else .none,
9132 .alignment = alignment orelse .none,
91329133 .align_is_generic = alignment == null,
91339134 .section_is_generic = section == .generic,
91349135 .addrspace_is_generic = address_space == null,
......@@ -9143,7 +9144,7 @@ fn funcCommon(
91439144 .default => .none,
91449145 .explicit => |section_name| section_name.toOptional(),
91459146 };
9146 sema.owner_decl.@"align" = alignment orelse 0;
9147 sema.owner_decl.alignment = alignment orelse .none;
91479148 sema.owner_decl.@"addrspace" = address_space orelse .generic;
91489149
91499150 if (is_extern) {
......@@ -10275,11 +10276,13 @@ const SwitchProngAnalysis = struct {
1027510276 const union_obj = mod.typeToUnion(operand_ty).?;
1027610277 const field_ty = union_obj.fields.values()[field_index].ty;
1027710278 if (capture_byref) {
10278 const ptr_field_ty = try Type.ptr(sema.arena, mod, .{
10279 .pointee_type = field_ty,
10280 .mutable = operand_ptr_ty.ptrIsMutable(mod),
10281 .@"volatile" = operand_ptr_ty.isVolatilePtr(mod),
10282 .@"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 },
1028310286 });
1028410287 if (try sema.resolveDefinedValue(block, sema.src, spa.operand_ptr)) |union_ptr| {
1028510288 return sema.addConstant(
......@@ -10382,24 +10385,28 @@ const SwitchProngAnalysis = struct {
1038210385 // By-reference captures have some further restrictions which make them easier to emit
1038310386 if (capture_byref) {
1038410387 const operand_ptr_info = operand_ptr_ty.ptrInfo(mod);
10385 const capture_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
10386 .pointee_type = capture_ty,
10387 .@"addrspace" = operand_ptr_info.@"addrspace",
10388 .mutable = operand_ptr_info.mutable,
10389 .@"volatile" = operand_ptr_info.@"volatile",
10390 // 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 },
1039110396 });
1039210397
1039310398 // By-ref captures of hetereogeneous types are only allowed if each field
1039410399 // pointer type is in-memory coercible to the capture pointer type.
1039510400 if (!same_types) {
1039610401 for (field_tys, 0..) |field_ty, i| {
10397 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
10398 .pointee_type = field_ty,
10399 .@"addrspace" = operand_ptr_info.@"addrspace",
10400 .mutable = operand_ptr_info.mutable,
10401 .@"volatile" = operand_ptr_info.@"volatile",
10402 // 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 },
1040310410 });
1040410411 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ptr_ty, field_ptr_ty, false, sema.mod.getTarget(), .unneeded, .unneeded)) {
1040510412 const multi_idx = raw_capture_src.multi_capture;
......@@ -12656,8 +12663,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1265612663 // - When a Decl is destroyed, it can free the `*Module.EmbedFile`.
1265712664 const ty = try mod.arrayType(.{
1265812665 .len = embed_file.bytes.len,
12659 .child = .u8_type,
1266012666 .sentinel = .zero_u8,
12667 .child = .u8_type,
1266112668 });
1266212669 embed_file.owner_decl = try anon_decl.finish(
1266312670 ty,
......@@ -12665,7 +12672,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1266512672 .ty = ty.toIntern(),
1266612673 .storage = .{ .bytes = embed_file.bytes },
1266712674 } })).toValue(),
12668 0, // default alignment
12675 .none, // default alignment
1266912676 );
1267012677
1267112678 return sema.analyzeDeclRef(embed_file.owner_decl);
......@@ -13289,7 +13296,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1328913296 ),
1329013297 };
1329113298
13292 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 });
1329313304 const ptr_addrspace = p: {
1329413305 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod);
1329513306 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod);
......@@ -13348,14 +13359,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1334813359 try sema.requireRuntimeBlock(block, src, runtime_src);
1334913360
1335013361 if (ptr_addrspace) |ptr_as| {
13351 const alloc_ty = try Type.ptr(sema.arena, mod, .{
13352 .pointee_type = result_ty,
13353 .@"addrspace" = ptr_as,
13362 const alloc_ty = try mod.ptrType(.{
13363 .child = result_ty.toIntern(),
13364 .flags = .{ .address_space = ptr_as },
1335413365 });
1335513366 const alloc = try block.addTy(.alloc, alloc_ty);
13356 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
13357 .pointee_type = resolved_elem_ty,
13358 .@"addrspace" = ptr_as,
13367 const elem_ptr_ty = try mod.ptrType(.{
13368 .child = resolved_elem_ty.toIntern(),
13369 .flags = .{ .address_space = ptr_as },
1335913370 });
1336013371
1336113372 var elem_i: usize = 0;
......@@ -13407,21 +13418,24 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1340713418 .Array => return operand_ty.arrayInfo(mod),
1340813419 .Pointer => {
1340913420 const ptr_info = operand_ty.ptrInfo(mod);
13410 switch (ptr_info.size) {
13421 switch (ptr_info.flags.size) {
1341113422 // TODO: in the Many case here this should only work if the type
1341213423 // has a sentinel, and this code should compute the length based
1341313424 // on the sentinel value.
1341413425 .Slice, .Many => {
1341513426 const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime-known");
1341613427 return Type.ArrayInfo{
13417 .elem_type = ptr_info.pointee_type,
13418 .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 },
1341913433 .len = val.sliceLen(mod),
1342013434 };
1342113435 },
1342213436 .One => {
13423 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
13424 return ptr_info.pointee_type.arrayInfo(mod);
13437 if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
13438 return ptr_info.child.toType().arrayInfo(mod);
1342513439 }
1342613440 },
1342713441 .C => {},
......@@ -13557,7 +13571,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1355713571 return sema.fail(block, rhs_src, "operation results in overflow", .{});
1355813572 const result_len = try sema.usizeCast(block, src, result_len_u64);
1355913573
13560 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 });
1356113579
1356213580 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;
1356313581 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);
......@@ -13600,14 +13618,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1360013618 try sema.requireRuntimeBlock(block, src, lhs_src);
1360113619
1360213620 if (ptr_addrspace) |ptr_as| {
13603 const alloc_ty = try Type.ptr(sema.arena, mod, .{
13604 .pointee_type = result_ty,
13605 .@"addrspace" = ptr_as,
13621 const alloc_ty = try mod.ptrType(.{
13622 .child = result_ty.toIntern(),
13623 .flags = .{ .address_space = ptr_as },
1360613624 });
1360713625 const alloc = try block.addTy(.alloc, alloc_ty);
13608 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
13609 .pointee_type = lhs_info.elem_type,
13610 .@"addrspace" = ptr_as,
13626 const elem_ptr_ty = try mod.ptrType(.{
13627 .child = lhs_info.elem_type.toIntern(),
13628 .flags = .{ .address_space = ptr_as },
1361113629 });
1361213630
1361313631 var elem_i: usize = 0;
......@@ -15563,18 +15581,18 @@ fn analyzePtrArithmetic(
1556315581 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
1556415582 const ptr_ty = sema.typeOf(ptr);
1556515583 const ptr_info = ptr_ty.ptrInfo(mod);
15566 assert(ptr_info.size == .Many or ptr_info.size == .C);
15584 assert(ptr_info.flags.size == .Many or ptr_info.flags.size == .C);
1556715585
1556815586 const new_ptr_ty = t: {
1556915587 // Calculate the new pointer alignment.
1557015588 // This code is duplicated in `elemPtrType`.
15571 if (ptr_info.@"align" == 0) {
15589 if (ptr_info.flags.alignment == .none) {
1557215590 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
1557315591 break :t ptr_ty;
1557415592 }
1557515593 // If the addend is not a comptime-known value we can still count on
1557615594 // it being a multiple of the type size.
15577 const elem_size = ptr_info.pointee_type.abiSize(mod);
15595 const elem_size = ptr_info.child.toType().abiSize(mod);
1557815596 const addend = if (opt_off_val) |off_val| a: {
1557915597 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod));
1558015598 break :a elem_size * off_int;
......@@ -15583,17 +15601,23 @@ fn analyzePtrArithmetic(
1558315601 // The resulting pointer is aligned to the lcd between the offset (an
1558415602 // arbitrary number) and the alignment factor (always a power of two,
1558515603 // non zero).
15586 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);
1558715609
15588 break :t try Type.ptr(sema.arena, mod, .{
15589 .pointee_type = ptr_info.pointee_type,
15610 break :t try mod.ptrType(.{
15611 .child = ptr_info.child,
1559015612 .sentinel = ptr_info.sentinel,
15591 .@"align" = new_align,
15592 .@"addrspace" = ptr_info.@"addrspace",
15593 .mutable = ptr_info.mutable,
15594 .@"allowzero" = ptr_info.@"allowzero",
15595 .@"volatile" = ptr_info.@"volatile",
15596 .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 },
1559715621 });
1559815622 };
1559915623
......@@ -15605,7 +15629,7 @@ fn analyzePtrArithmetic(
1560515629 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));
1560615630 if (offset_int == 0) return ptr;
1560715631 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {
15608 const elem_size = ptr_info.pointee_type.abiSize(mod);
15632 const elem_size = ptr_info.child.toType().abiSize(mod);
1560915633 const new_addr = switch (air_tag) {
1561015634 .ptr_add => addr + elem_size * offset_int,
1561115635 .ptr_sub => addr - elem_size * offset_int,
......@@ -16344,8 +16368,8 @@ fn zirBuiltinSrc(
1634416368 const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));
1634516369 const new_decl_ty = try mod.arrayType(.{
1634616370 .len = name.len,
16347 .child = .u8_type,
1634816371 .sentinel = .zero_u8,
16372 .child = .u8_type,
1634916373 });
1635016374 const new_decl = try anon_decl.finish(
1635116375 new_decl_ty,
......@@ -16353,7 +16377,7 @@ fn zirBuiltinSrc(
1635316377 .ty = new_decl_ty.toIntern(),
1635416378 .storage = .{ .bytes = name },
1635516379 } })).toValue(),
16356 0, // default alignment
16380 .none, // default alignment
1635716381 );
1635816382 break :blk try mod.intern(.{ .ptr = .{
1635916383 .ty = .slice_const_u8_sentinel_0_type,
......@@ -16369,8 +16393,8 @@ fn zirBuiltinSrc(
1636916393 const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
1637016394 const new_decl_ty = try mod.arrayType(.{
1637116395 .len = name.len,
16372 .child = .u8_type,
1637316396 .sentinel = .zero_u8,
16397 .child = .u8_type,
1637416398 });
1637516399 const new_decl = try anon_decl.finish(
1637616400 new_decl_ty,
......@@ -16378,7 +16402,7 @@ fn zirBuiltinSrc(
1637816402 .ty = new_decl_ty.toIntern(),
1637916403 .storage = .{ .bytes = name },
1638016404 } })).toValue(),
16381 0, // default alignment
16405 .none, // default alignment
1638216406 );
1638316407 break :blk try mod.intern(.{ .ptr = .{
1638416408 .ty = .slice_const_u8_sentinel_0_type,
......@@ -16499,7 +16523,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1649916523 .ty = new_decl_ty.toIntern(),
1650016524 .storage = .{ .elems = param_vals },
1650116525 } })).toValue(),
16502 0, // default alignment
16526 .none, // default alignment
1650316527 );
1650416528 break :v try mod.intern(.{ .ptr = .{
1650516529 .ty = (try mod.ptrType(.{
......@@ -16601,10 +16625,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1660116625 },
1660216626 .Pointer => {
1660316627 const info = ty.ptrInfo(mod);
16604 const alignment = if (info.@"align" != 0)
16605 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)
1660616630 else
16607 try info.pointee_type.lazyAbiAlignment(mod);
16631 try info.child.toType().lazyAbiAlignment(mod);
1660816632
1660916633 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
1661016634 const pointer_ty = t: {
......@@ -16634,21 +16658,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1663416658
1663516659 const field_values = .{
1663616660 // size: Size,
16637 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),
1663816662 // is_const: bool,
16639 Value.makeBool(!info.mutable).toIntern(),
16663 Value.makeBool(info.flags.is_const).toIntern(),
1664016664 // is_volatile: bool,
16641 Value.makeBool(info.@"volatile").toIntern(),
16665 Value.makeBool(info.flags.is_volatile).toIntern(),
1664216666 // alignment: comptime_int,
1664316667 alignment.toIntern(),
1664416668 // address_space: AddressSpace
16645 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),
1664616670 // child: type,
16647 info.pointee_type.toIntern(),
16671 info.child,
1664816672 // is_allowzero: bool,
16649 Value.makeBool(info.@"allowzero").toIntern(),
16673 Value.makeBool(info.flags.is_allowzero).toIntern(),
1665016674 // sentinel: ?*const anyopaque,
16651 (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(),
1665216679 };
1665316680 return sema.addConstant(type_info_ty, (try mod.intern(.{ .un = .{
1665416681 .ty = type_info_ty.toIntern(),
......@@ -16792,7 +16819,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1679216819 .ty = new_decl_ty.toIntern(),
1679316820 .storage = .{ .bytes = name },
1679416821 } })).toValue(),
16795 0, // default alignment
16822 .none, // default alignment
1679616823 );
1679716824 break :v try mod.intern(.{ .ptr = .{
1679816825 .ty = .slice_const_u8_type,
......@@ -16827,7 +16854,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1682716854 const array_errors_ty = try mod.arrayType(.{
1682816855 .len = vals.len,
1682916856 .child = error_field_ty.toIntern(),
16830 .sentinel = .none,
1683116857 });
1683216858 const new_decl = try fields_anon_decl.finish(
1683316859 array_errors_ty,
......@@ -16835,7 +16861,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1683516861 .ty = array_errors_ty.toIntern(),
1683616862 .storage = .{ .elems = vals },
1683716863 } })).toValue(),
16838 0, // default alignment
16864 .none, // default alignment
1683916865 );
1684016866 break :v try mod.intern(.{ .ptr = .{
1684116867 .ty = slice_errors_ty.toIntern(),
......@@ -16929,7 +16955,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1692916955 .ty = new_decl_ty.toIntern(),
1693016956 .storage = .{ .bytes = name },
1693116957 } })).toValue(),
16932 0, // default alignment
16958 .none, // default alignment
1693316959 );
1693416960 break :v try mod.intern(.{ .ptr = .{
1693516961 .ty = .slice_const_u8_type,
......@@ -16954,7 +16980,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1695416980 const fields_array_ty = try mod.arrayType(.{
1695516981 .len = enum_field_vals.len,
1695616982 .child = enum_field_ty.toIntern(),
16957 .sentinel = .none,
1695816983 });
1695916984 const new_decl = try fields_anon_decl.finish(
1696016985 fields_array_ty,
......@@ -16962,7 +16987,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1696216987 .ty = fields_array_ty.toIntern(),
1696316988 .storage = .{ .elems = enum_field_vals },
1696416989 } })).toValue(),
16965 0, // default alignment
16990 .none, // default alignment
1696616991 );
1696716992 break :v try mod.intern(.{ .ptr = .{
1696816993 .ty = (try mod.ptrType(.{
......@@ -17068,7 +17093,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1706817093 .ty = new_decl_ty.toIntern(),
1706917094 .storage = .{ .bytes = name },
1707017095 } })).toValue(),
17071 0, // default alignment
17096 .none, // default alignment
1707217097 );
1707317098 break :v try mod.intern(.{ .ptr = .{
1707417099 .ty = .slice_const_u8_type,
......@@ -17100,7 +17125,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1710017125 const array_fields_ty = try mod.arrayType(.{
1710117126 .len = union_field_vals.len,
1710217127 .child = union_field_ty.toIntern(),
17103 .sentinel = .none,
1710417128 });
1710517129 const new_decl = try fields_anon_decl.finish(
1710617130 array_fields_ty,
......@@ -17108,7 +17132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1710817132 .ty = array_fields_ty.toIntern(),
1710917133 .storage = .{ .elems = union_field_vals },
1711017134 } })).toValue(),
17111 0, // default alignment
17135 .none, // default alignment
1711217136 );
1711317137 break :v try mod.intern(.{ .ptr = .{
1711417138 .ty = (try mod.ptrType(.{
......@@ -17228,7 +17252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1722817252 .ty = new_decl_ty.toIntern(),
1722917253 .storage = .{ .bytes = bytes },
1723017254 } })).toValue(),
17231 0, // default alignment
17255 .none, // default alignment
1723217256 );
1723317257 break :v try mod.intern(.{ .ptr = .{
1723417258 .ty = .slice_const_u8_type,
......@@ -17285,7 +17309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1728517309 .ty = new_decl_ty.toIntern(),
1728617310 .storage = .{ .bytes = name },
1728717311 } })).toValue(),
17288 0, // default alignment
17312 .none, // default alignment
1728917313 );
1729017314 break :v try mod.intern(.{ .ptr = .{
1729117315 .ty = .slice_const_u8_type,
......@@ -17324,7 +17348,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1732417348 const array_fields_ty = try mod.arrayType(.{
1732517349 .len = struct_field_vals.len,
1732617350 .child = struct_field_ty.toIntern(),
17327 .sentinel = .none,
1732817351 });
1732917352 const new_decl = try fields_anon_decl.finish(
1733017353 array_fields_ty,
......@@ -17332,7 +17355,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1733217355 .ty = array_fields_ty.toIntern(),
1733317356 .storage = .{ .elems = struct_field_vals },
1733417357 } })).toValue(),
17335 0, // default alignment
17358 .none, // default alignment
1733617359 );
1733717360 break :v try mod.intern(.{ .ptr = .{
1733817361 .ty = (try mod.ptrType(.{
......@@ -17471,7 +17494,6 @@ fn typeInfoDecls(
1747117494 const array_decl_ty = try mod.arrayType(.{
1747217495 .len = decl_vals.items.len,
1747317496 .child = declaration_ty.toIntern(),
17474 .sentinel = .none,
1747517497 });
1747617498 const new_decl = try decls_anon_decl.finish(
1747717499 array_decl_ty,
......@@ -17479,7 +17501,7 @@ fn typeInfoDecls(
1747917501 .ty = array_decl_ty.toIntern(),
1748017502 .storage = .{ .elems = decl_vals.items },
1748117503 } })).toValue(),
17482 0, // default alignment
17504 .none, // default alignment
1748317505 );
1748417506 return try mod.intern(.{ .ptr = .{
1748517507 .ty = (try mod.ptrType(.{
......@@ -17532,7 +17554,7 @@ fn typeInfoNamespaceDecls(
1753217554 .ty = new_decl_ty.toIntern(),
1753317555 .storage = .{ .bytes = name },
1753417556 } })).toValue(),
17535 0, // default alignment
17557 .none, // default alignment
1753617558 );
1753717559 break :v try mod.intern(.{ .ptr = .{
1753817560 .ty = .slice_const_u8_type,
......@@ -18057,12 +18079,14 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1805718079
1805818080 const operand_ty = sema.typeOf(operand);
1805918081 const ptr_info = operand_ty.ptrInfo(mod);
18060 const res_ty = try Type.ptr(sema.arena, mod, .{
18061 .pointee_type = err_union_ty.errorUnionPayload(mod),
18062 .@"addrspace" = ptr_info.@"addrspace",
18063 .mutable = ptr_info.mutable,
18064 .@"allowzero" = ptr_info.@"allowzero",
18065 .@"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 },
1806618090 });
1806718091 const res_ty_ref = try sema.addType(res_ty);
1806818092 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).Struct.fields.len +
......@@ -18482,7 +18506,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1848218506 break :blk val.toIntern();
1848318507 } else .none;
1848418508
18485 const abi_align: InternPool.Alignment = if (inst_data.flags.has_align) blk: {
18509 const abi_align: Alignment = if (inst_data.flags.has_align) blk: {
1848618510 const ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_i]);
1848718511 extra_i += 1;
1848818512 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);
......@@ -18498,7 +18522,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1849818522 }
1849918523 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);
1850018524 try sema.validateAlign(block, align_src, abi_align);
18501 break :blk InternPool.Alignment.fromByteUnits(abi_align);
18525 break :blk Alignment.fromByteUnits(abi_align);
1850218526 } else .none;
1850318527
1850418528 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {
......@@ -18775,9 +18799,9 @@ fn zirStructInit(
1877518799
1877618800 if (is_ref) {
1877718801 const target = mod.getTarget();
18778 const alloc_ty = try Type.ptr(sema.arena, mod, .{
18779 .pointee_type = resolved_ty,
18780 .@"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) },
1878118805 });
1878218806 const alloc = try block.addTy(.alloc, alloc_ty);
1878318807 const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty, true);
......@@ -18898,9 +18922,9 @@ fn finishStructInit(
1889818922 if (is_ref) {
1889918923 try sema.resolveStructLayout(struct_ty);
1890018924 const target = sema.mod.getTarget();
18901 const alloc_ty = try Type.ptr(sema.arena, mod, .{
18902 .pointee_type = struct_ty,
18903 .@"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) },
1890418928 });
1890518929 const alloc = try block.addTy(.alloc, alloc_ty);
1890618930 for (field_inits, 0..) |field_init, i_usize| {
......@@ -19019,9 +19043,9 @@ fn zirStructInitAnon(
1901919043
1902019044 if (is_ref) {
1902119045 const target = mod.getTarget();
19022 const alloc_ty = try Type.ptr(sema.arena, mod, .{
19023 .pointee_type = tuple_ty.toType(),
19024 .@"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) },
1902519049 });
1902619050 const alloc = try block.addTy(.alloc, alloc_ty);
1902719051 var extra_index = extra.end;
......@@ -19030,10 +19054,9 @@ fn zirStructInitAnon(
1903019054 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);
1903119055 extra_index = item.end;
1903219056
19033 const field_ptr_ty = try Type.ptr(sema.arena, mod, .{
19034 .mutable = true,
19035 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19036 .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) },
1903719060 });
1903819061 if (values[i] == .none) {
1903919062 const init = try sema.resolveInst(item.data.init);
......@@ -19131,18 +19154,17 @@ fn zirArrayInit(
1913119154
1913219155 if (is_ref) {
1913319156 const target = mod.getTarget();
19134 const alloc_ty = try Type.ptr(sema.arena, mod, .{
19135 .pointee_type = array_ty,
19136 .@"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) },
1913719160 });
1913819161 const alloc = try block.addTy(.alloc, alloc_ty);
1913919162
1914019163 if (array_ty.isTuple(mod)) {
1914119164 for (resolved_args, 0..) |arg, i| {
19142 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
19143 .mutable = true,
19144 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19145 .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) },
1914619168 });
1914719169 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1914819170
......@@ -19153,10 +19175,9 @@ fn zirArrayInit(
1915319175 return sema.makePtrConst(block, alloc);
1915419176 }
1915519177
19156 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
19157 .mutable = true,
19158 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19159 .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) },
1916019181 });
1916119182 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1916219183
......@@ -19230,17 +19251,16 @@ fn zirArrayInitAnon(
1923019251
1923119252 if (is_ref) {
1923219253 const target = sema.mod.getTarget();
19233 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
19234 .pointee_type = tuple_ty.toType(),
19235 .@"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) },
1923619257 });
1923719258 const alloc = try block.addTy(.alloc, alloc_ty);
1923819259 for (operands, 0..) |operand, i_usize| {
1923919260 const i = @intCast(u32, i_usize);
19240 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
19241 .mutable = true,
19242 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
19243 .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) },
1924419264 });
1924519265 if (values[i] == .none) {
1924619266 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);
......@@ -19273,7 +19293,7 @@ fn addConstantMaybeRef(
1927319293 const decl = try anon_decl.finish(
1927419294 ty,
1927519295 val,
19276 0, // default alignment
19296 .none, // default alignment
1927719297 );
1927819298 return sema.analyzeDeclRef(decl);
1927919299}
......@@ -19368,7 +19388,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
1936819388 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
1936919389 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
1937019390 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
19371 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());
1937219392
1937319393 if (sema.owner_func != null and
1937419394 sema.owner_func.?.calls_or_awaits_errorable_fn and
......@@ -19688,7 +19708,7 @@ fn zirReify(
1968819708 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
1968919709 }
1969019710
19691 const abi_align = InternPool.Alignment.fromByteUnits(
19711 const abi_align = Alignment.fromByteUnits(
1969219712 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,
1969319713 );
1969419714
......@@ -19709,10 +19729,7 @@ fn zirReify(
1970919729 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
1971019730 }
1971119731 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;
19712 const ptr_ty = try Type.ptr(sema.arena, mod, .{
19713 .@"addrspace" = .generic,
19714 .pointee_type = elem_ty,
19715 });
19732 const ptr_ty = try mod.singleMutPtrType(elem_ty);
1971619733 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
1971719734 break :s sent_val.toIntern();
1971819735 }
......@@ -19781,14 +19798,15 @@ fn zirReify(
1978119798 const len = len_val.toUnsignedInt(mod);
1978219799 const child_ty = child_val.toType();
1978319800 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
19784 const ptr_ty = try Type.ptr(sema.arena, mod, .{
19785 .@"addrspace" = .generic,
19786 .pointee_type = child_ty,
19787 });
19801 const ptr_ty = try mod.singleMutPtrType(child_ty);
1978819802 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;
1978919803 } else null;
1979019804
19791 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 });
1979219810 return sema.addType(ty);
1979319811 },
1979419812 .Optional => {
......@@ -19799,7 +19817,7 @@ fn zirReify(
1979919817
1980019818 const child_ty = child_val.toType();
1980119819
19802 const ty = try Type.optional(sema.arena, child_ty, mod);
19820 const ty = try mod.optionalType(child_ty.toIntern());
1980319821 return sema.addType(ty);
1980419822 },
1980519823 .ErrorUnion => {
......@@ -20180,7 +20198,7 @@ fn zirReify(
2018020198 const field_ty = type_val.toType();
2018120199 gop.value_ptr.* = .{
2018220200 .ty = field_ty,
20183 .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),
20201 .abi_align = Alignment.fromByteUnits((try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),
2018420202 };
2018520203
2018620204 if (field_ty.zigTypeTag(mod) == .Opaque) {
......@@ -20287,7 +20305,7 @@ fn zirReify(
2028720305 if (alignment == target_util.defaultFunctionAlignment(target)) {
2028820306 break :alignment .none;
2028920307 } else {
20290 break :alignment InternPool.Alignment.fromByteUnits(alignment);
20308 break :alignment Alignment.fromByteUnits(alignment);
2029120309 }
2029220310 };
2029320311 const return_type = return_type_val.optionalValue(mod) orelse
......@@ -20436,7 +20454,7 @@ fn reifyStruct(
2043620454 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
2043720455 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
2043820456 }
20439 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?);
20457 const abi_align = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
2044020458
2044120459 if (layout == .Packed) {
2044220460 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
......@@ -20483,7 +20501,7 @@ fn reifyStruct(
2048320501
2048420502 gop.value_ptr.* = .{
2048520503 .ty = field_ty,
20486 .abi_align = abi_align,
20504 .abi_align = Alignment.fromByteUnits(abi_align),
2048720505 .default_val = default_val,
2048820506 .is_comptime = is_comptime_val.toBool(),
2048920507 .offset = undefined,
......@@ -20585,7 +20603,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2058520603 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
2058620604
2058720605 var ptr_info = ptr_ty.ptrInfo(mod);
20588 const src_addrspace = ptr_info.@"addrspace";
20606 const src_addrspace = ptr_info.flags.address_space;
2058920607 if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) {
2059020608 const msg = msg: {
2059120609 const msg = try sema.errMsg(block, src, "invalid address space cast", .{});
......@@ -20596,10 +20614,10 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2059620614 return sema.failWithOwnedErrorMsg(msg);
2059720615 }
2059820616
20599 ptr_info.@"addrspace" = dest_addrspace;
20600 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);
2060120619 const dest_ty = if (ptr_ty.zigTypeTag(mod) == .Optional)
20602 try Type.optional(sema.arena, dest_ptr_ty, mod)
20620 try mod.optionalType(dest_ptr_ty.toIntern())
2060320621 else
2060420622 dest_ptr_ty;
2060520623
......@@ -20617,11 +20635,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2061720635
2061820636fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
2061920637 const va_list_ty = try sema.getBuiltinType("VaList");
20620 const va_list_ptr = try Type.ptr(sema.arena, sema.mod, .{
20621 .pointee_type = va_list_ty,
20622 .mutable = true,
20623 .@"addrspace" = .generic,
20624 });
20638 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);
2062520639
2062620640 const inst = try sema.resolveInst(zir_ref);
2062720641 return sema.coerce(block, va_list_ptr, inst, src);
......@@ -20698,20 +20712,22 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2069820712 var anon_decl = try block.startAnonDecl();
2069920713 defer anon_decl.deinit();
2070020714
20701 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);
2070220718
2070320719 const decl_ty = try mod.arrayType(.{
20704 .len = bytes.len,
20705 .child = .u8_type,
20720 .len = bytes.items.len,
2070620721 .sentinel = .zero_u8,
20722 .child = .u8_type,
2070720723 });
2070820724 const new_decl = try anon_decl.finish(
2070920725 decl_ty,
2071020726 (try mod.intern(.{ .aggregate = .{
2071120727 .ty = decl_ty.toIntern(),
20712 .storage = .{ .bytes = bytes },
20728 .storage = .{ .bytes = bytes.items },
2071320729 } })).toValue(),
20714 0, // default alignment
20730 .none, // default alignment
2071520731 );
2071620732
2071720733 return sema.analyzeDeclRef(new_decl);
......@@ -20962,7 +20978,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2096220978
2096320979 const operand_info = operand_ty.ptrInfo(mod);
2096420980 const dest_info = dest_ty.ptrInfo(mod);
20965 if (!operand_info.mutable and dest_info.mutable) {
20981 if (operand_info.flags.is_const and !dest_info.flags.is_const) {
2096620982 const msg = msg: {
2096720983 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});
2096820984 errdefer msg.destroy(sema.gpa);
......@@ -20972,7 +20988,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2097220988 };
2097320989 return sema.failWithOwnedErrorMsg(msg);
2097420990 }
20975 if (operand_info.@"volatile" and !dest_info.@"volatile") {
20991 if (operand_info.flags.is_volatile and !dest_info.flags.is_volatile) {
2097620992 const msg = msg: {
2097720993 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});
2097820994 errdefer msg.destroy(sema.gpa);
......@@ -20982,7 +20998,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2098220998 };
2098320999 return sema.failWithOwnedErrorMsg(msg);
2098421000 }
20985 if (operand_info.@"addrspace" != dest_info.@"addrspace") {
21001 if (operand_info.flags.address_space != dest_info.flags.address_space) {
2098621002 const msg = msg: {
2098721003 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
2098821004 errdefer msg.destroy(sema.gpa);
......@@ -21014,14 +21030,12 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2101421030 // If the destination is less aligned than the source, preserve the source alignment
2101521031 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
2101621032 // 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);
2101721035 if (dest_ty.zigTypeTag(mod) == .Optional) {
21018 var dest_ptr_info = dest_ty.optionalChild(mod).ptrInfo(mod);
21019 dest_ptr_info.@"align" = operand_align;
21020 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());
2102121037 } else {
21022 var dest_ptr_info = dest_ty.ptrInfo(mod);
21023 dest_ptr_info.@"align" = operand_align;
21024 break :blk try Type.ptr(sema.arena, mod, dest_ptr_info);
21038 break :blk try mod.ptrType(dest_ptr_info);
2102521039 }
2102621040 };
2102721041
......@@ -21088,8 +21102,8 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2108821102 try sema.checkPtrOperand(block, operand_src, operand_ty);
2108921103
2109021104 var ptr_info = operand_ty.ptrInfo(mod);
21091 ptr_info.mutable = true;
21092 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);
2109321107
2109421108 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
2109521109 return sema.addConstant(dest_ty, try mod.getCoerced(operand_val, dest_ty));
......@@ -21109,8 +21123,8 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2110921123 try sema.checkPtrOperand(block, operand_src, operand_ty);
2111021124
2111121125 var ptr_info = operand_ty.ptrInfo(mod);
21112 ptr_info.@"volatile" = false;
21113 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);
2111421128
2111521129 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
2111621130 return sema.addConstant(dest_ty, operand_val);
......@@ -21219,28 +21233,29 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2121921233 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
2122021234
2122121235 var ptr_info = ptr_ty.ptrInfo(mod);
21222 ptr_info.@"align" = dest_align;
21223 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);
2122421238 if (ptr_ty.zigTypeTag(mod) == .Optional) {
2122521239 dest_ty = try mod.optionalType(dest_ty.toIntern());
2122621240 }
2122721241
2122821242 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {
2122921243 if (try val.getUnsignedIntAdvanced(mod, null)) |addr| {
21230 if (addr % dest_align != 0) {
21231 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 });
2123221247 }
2123321248 }
2123421249 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
2123521250 }
2123621251
2123721252 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
21238 if (block.wantSafety() and dest_align > 1 and
21239 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()))
2124021255 {
2124121256 const align_minus_1 = try sema.addConstant(
2124221257 Type.usize,
21243 try mod.intValue(Type.usize, dest_align - 1),
21258 try mod.intValue(Type.usize, dest_align.toByteUnitsOptional().? - 1),
2124421259 );
2124521260 const actual_ptr = if (ptr_ty.isSlice(mod))
2124621261 try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)
......@@ -21685,28 +21700,29 @@ fn checkAtomicPtrOperand(
2168521700 ),
2168621701 };
2168721702
21688 var wanted_ptr_data: Type.Payload.Pointer.Data = .{
21689 .pointee_type = elem_ty,
21690 .@"align" = alignment,
21691 .@"addrspace" = .generic,
21692 .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 },
2169321709 };
2169421710
2169521711 const ptr_ty = sema.typeOf(ptr);
2169621712 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
2169721713 .Pointer => ptr_ty.ptrInfo(mod),
2169821714 else => {
21699 const wanted_ptr_ty = try Type.ptr(sema.arena, mod, wanted_ptr_data);
21715 const wanted_ptr_ty = try mod.ptrType(wanted_ptr_data);
2170021716 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2170121717 unreachable;
2170221718 },
2170321719 };
2170421720
21705 wanted_ptr_data.@"addrspace" = ptr_data.@"addrspace";
21706 wanted_ptr_data.@"allowzero" = ptr_data.@"allowzero";
21707 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;
2170821724
21709 const wanted_ptr_ty = try Type.ptr(sema.arena, mod, wanted_ptr_data);
21725 const wanted_ptr_ty = try mod.ptrType(wanted_ptr_data);
2171021726 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2171121727
2171221728 return casted_ptr;
......@@ -22059,7 +22075,7 @@ fn zirCmpxchg(
2205922075 return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{});
2206022076 }
2206122077
22062 const result_ty = try Type.optional(sema.arena, elem_ty, mod);
22078 const result_ty = try mod.optionalType(elem_ty.toIntern());
2206322079
2206422080 // special case zero bit types
2206522081 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {
......@@ -22825,31 +22841,33 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2282522841 try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);
2282622842 const field_ptr_ty_info = field_ptr_ty.ptrInfo(mod);
2282722843
22828 var ptr_ty_data: Type.Payload.Pointer.Data = .{
22829 .pointee_type = parent_ty.structFieldType(field_index, mod),
22830 .mutable = field_ptr_ty_info.mutable,
22831 .@"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 },
2283222850 };
2283322851
2283422852 if (parent_ty.containerLayout(mod) == .Packed) {
2283522853 return sema.fail(block, src, "TODO handle packed structs/unions with @fieldParentPtr", .{});
2283622854 } else {
22837 ptr_ty_data.@"align" = blk: {
22855 ptr_ty_data.flags.alignment = blk: {
2283822856 if (mod.typeToStruct(parent_ty)) |struct_obj| {
2283922857 break :blk struct_obj.fields.values()[field_index].abi_align;
2284022858 } else if (mod.typeToUnion(parent_ty)) |union_obj| {
2284122859 break :blk union_obj.fields.values()[field_index].abi_align;
2284222860 } else {
22843 break :blk 0;
22861 break :blk .none;
2284422862 }
2284522863 };
2284622864 }
2284722865
22848 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);
2284922867 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
2285022868
22851 ptr_ty_data.pointee_type = parent_ty;
22852 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);
2285322871
2285422872 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
2285522873 const field = switch (ip.indexToKey(field_ptr_val.toIntern())) {
......@@ -23172,21 +23190,25 @@ fn analyzeMinMax(
2317223190fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {
2317323191 const mod = sema.mod;
2317423192 const info = sema.typeOf(ptr).ptrInfo(mod);
23175 if (info.size == .One) {
23193 if (info.flags.size == .One) {
2317623194 // Already an array pointer.
2317723195 return ptr;
2317823196 }
23179 const new_ty = try Type.ptr(sema.arena, mod, .{
23180 .pointee_type = try Type.array(sema.arena, len, info.sentinel, info.pointee_type, mod),
23181 .sentinel = null,
23182 .@"align" = info.@"align",
23183 .@"addrspace" = info.@"addrspace",
23184 .mutable = info.mutable,
23185 .@"allowzero" = info.@"allowzero",
23186 .@"volatile" = info.@"volatile",
23187 .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 },
2318823210 });
23189 if (info.size == .Slice) {
23211 if (info.flags.size == .Slice) {
2319023212 return block.addTyOp(.slice_ptr, new_ty, ptr);
2319123213 }
2319223214 return block.addBitCast(new_ty, ptr);
......@@ -23604,7 +23626,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2360423626 return sema.fail(block, align_src, "target does not support function alignment", .{});
2360523627 }
2360623628
23607 const @"align": ?u32 = if (extra.data.bits.has_align_body) blk: {
23629 const @"align": ?Alignment = if (extra.data.bits.has_align_body) blk: {
2360823630 const body_len = sema.code.extra[extra_index];
2360923631 extra_index += 1;
2361023632 const body = sema.code.extra[extra_index..][0..body_len];
......@@ -23617,9 +23639,9 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2361723639 const alignment = @intCast(u32, val.toUnsignedInt(mod));
2361823640 try sema.validateAlign(block, align_src, alignment);
2361923641 if (alignment == target_util.defaultFunctionAlignment(target)) {
23620 break :blk 0;
23642 break :blk .none;
2362123643 } else {
23622 break :blk alignment;
23644 break :blk Alignment.fromNonzeroByteUnits(alignment);
2362323645 }
2362423646 } else if (extra.data.bits.has_align_ref) blk: {
2362523647 const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]);
......@@ -23633,11 +23655,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2363323655 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod));
2363423656 try sema.validateAlign(block, align_src, alignment);
2363523657 if (alignment == target_util.defaultFunctionAlignment(target)) {
23636 break :blk 0;
23658 break :blk .none;
2363723659 } else {
23638 break :blk alignment;
23660 break :blk Alignment.fromNonzeroByteUnits(alignment);
2363923661 }
23640 } else 0;
23662 } else .none;
2364123663
2364223664 const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: {
2364323665 const body_len = sema.code.extra[extra_index];
......@@ -24032,7 +24054,7 @@ fn zirBuiltinExtern(
2403224054 };
2403324055
2403424056 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {
24035 ty = try Type.optional(sema.arena, ty, mod);
24057 ty = try mod.optionalType(ty.toIntern());
2403624058 }
2403724059
2403824060 // TODO check duplicate extern
......@@ -24058,7 +24080,7 @@ fn zirBuiltinExtern(
2405824080 // below, so this type doesn't matter
2405924081 new_decl.ty = ty;
2406024082 new_decl.val = new_var.toValue();
24061 new_decl.@"align" = 0;
24083 new_decl.alignment = .none;
2406224084 new_decl.@"linksection" = .none;
2406324085 new_decl.has_tv = true;
2406424086 new_decl.analysis = .complete;
......@@ -24948,18 +24970,19 @@ fn fieldVal(
2494824970 );
2494924971 } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {
2495024972 const ptr_info = object_ty.ptrInfo(mod);
24951 const result_ty = try Type.ptr(sema.arena, mod, .{
24952 .pointee_type = ptr_info.pointee_type.childType(mod),
24973 const result_ty = try mod.ptrType(.{
24974 .child = ptr_info.child.toType().childType(mod).toIntern(),
2495324975 .sentinel = ptr_info.sentinel,
24954 .@"align" = ptr_info.@"align",
24955 .@"addrspace" = ptr_info.@"addrspace",
24956 .bit_offset = ptr_info.bit_offset,
24957 .host_size = ptr_info.host_size,
24958 .vector_index = ptr_info.vector_index,
24959 .@"allowzero" = ptr_info.@"allowzero",
24960 .mutable = ptr_info.mutable,
24961 .@"volatile" = ptr_info.@"volatile",
24962 .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,
2496324986 });
2496424987 return sema.coerce(block, result_ty, object, src);
2496524988 } else {
......@@ -24973,7 +24996,7 @@ fn fieldVal(
2497324996 },
2497424997 .Pointer => {
2497524998 const ptr_info = inner_ty.ptrInfo(mod);
24976 if (ptr_info.size == .Slice) {
24999 if (ptr_info.flags.size == .Slice) {
2497725000 if (ip.stringEqlSlice(field_name, "ptr")) {
2497825001 const slice = if (is_pointer_to)
2497925002 try sema.analyzeLoad(block, src, object, object_src)
......@@ -25147,7 +25170,7 @@ fn fieldPtr(
2514725170 return sema.analyzeDeclRef(try anon_decl.finish(
2514825171 Type.usize,
2514925172 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
25150 0, // default alignment
25173 .none, // default alignment
2515125174 ));
2515225175 } else {
2515325176 return sema.fail(
......@@ -25169,11 +25192,13 @@ fn fieldPtr(
2516925192 if (ip.stringEqlSlice(field_name, "ptr")) {
2517025193 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2517125194
25172 const result_ty = try Type.ptr(sema.arena, mod, .{
25173 .pointee_type = slice_ptr_ty,
25174 .mutable = attr_ptr_ty.ptrIsMutable(mod),
25175 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),
25176 .@"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 },
2517725202 });
2517825203
2517925204 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
......@@ -25189,11 +25214,13 @@ fn fieldPtr(
2518925214
2519025215 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
2519125216 } else if (ip.stringEqlSlice(field_name, "len")) {
25192 const result_ty = try Type.ptr(sema.arena, mod, .{
25193 .pointee_type = Type.usize,
25194 .mutable = attr_ptr_ty.ptrIsMutable(mod),
25195 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),
25196 .@"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 },
2519725224 });
2519825225
2519925226 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
......@@ -25261,7 +25288,7 @@ fn fieldPtr(
2526125288 .ty = error_set_type.toIntern(),
2526225289 .name = field_name,
2526325290 } })).toValue(),
25264 0, // default alignment
25291 .none, // default alignment
2526525292 ));
2526625293 },
2526725294 .Union => {
......@@ -25279,7 +25306,7 @@ fn fieldPtr(
2527925306 return sema.analyzeDeclRef(try anon_decl.finish(
2528025307 enum_ty,
2528125308 try mod.enumValueFieldIndex(enum_ty, field_index_u32),
25282 0, // default alignment
25309 .none, // default alignment
2528325310 ));
2528425311 }
2528525312 }
......@@ -25300,7 +25327,7 @@ fn fieldPtr(
2530025327 return sema.analyzeDeclRef(try anon_decl.finish(
2530125328 child_type,
2530225329 try mod.enumValueFieldIndex(child_type, field_index_u32),
25303 0, // default alignment
25330 .none, // default alignment
2530425331 ));
2530525332 },
2530625333 .Struct, .Opaque => {
......@@ -25514,11 +25541,12 @@ fn finishFieldCallBind(
2551425541 object_ptr: Air.Inst.Ref,
2551525542) CompileError!ResolvedFieldCallee {
2551625543 const mod = sema.mod;
25517 const arena = sema.arena;
25518 const ptr_field_ty = try Type.ptr(arena, mod, .{
25519 .pointee_type = field_ty,
25520 .mutable = ptr_ty.ptrIsMutable(mod),
25521 .@"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 },
2552225550 });
2552325551
2552425552 const container_ty = ptr_ty.childType(mod);
......@@ -25651,11 +25679,13 @@ fn structFieldPtrByIndex(
2565125679 const struct_ptr_ty = sema.typeOf(struct_ptr);
2565225680 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);
2565325681
25654 var ptr_ty_data: Type.Payload.Pointer.Data = .{
25655 .pointee_type = field.ty,
25656 .mutable = struct_ptr_ty_info.mutable,
25657 .@"volatile" = struct_ptr_ty_info.@"volatile",
25658 .@"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 },
2565925689 };
2566025690
2566125691 const target = mod.getTarget();
......@@ -25668,24 +25698,22 @@ fn structFieldPtrByIndex(
2566825698 if (!(try sema.typeHasRuntimeBits(f.ty))) continue;
2566925699
2567025700 if (i == field_index) {
25671 ptr_ty_data.bit_offset = running_bits;
25701 ptr_ty_data.packed_offset.bit_offset = running_bits;
2567225702 }
2567325703 running_bits += @intCast(u16, f.ty.bitSize(mod));
2567425704 }
25675 ptr_ty_data.host_size = (running_bits + 7) / 8;
25705 ptr_ty_data.packed_offset.host_size = (running_bits + 7) / 8;
2567625706
2567725707 // If this is a packed struct embedded in another one, we need to offset
2567825708 // the bits against each other.
25679 if (struct_ptr_ty_info.host_size != 0) {
25680 ptr_ty_data.host_size = struct_ptr_ty_info.host_size;
25681 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;
2568225712 }
2568325713
25684 const parent_align = if (struct_ptr_ty_info.@"align" != 0)
25685 struct_ptr_ty_info.@"align"
25686 else
25687 struct_ptr_ty_info.pointee_type.abiAlignment(mod);
25688 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);
2568925717
2569025718 // If the field happens to be byte-aligned, simplify the pointer type.
2569125719 // The pointee type bit size must match its ABI byte size so that loads and stores
......@@ -25695,24 +25723,24 @@ fn structFieldPtrByIndex(
2569525723 // targets before adding the necessary complications to this code. This will not
2569625724 // cause miscompilations; it only means the field pointer uses bit masking when it
2569725725 // might not be strictly necessary.
25698 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
2569925727 target.cpu.arch.endian() == .Little)
2570025728 {
25701 const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(mod);
25702 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);
2570325731 if (elem_size_bytes * 8 == elem_size_bits) {
25704 const byte_offset = ptr_ty_data.bit_offset / 8;
25705 const new_align = @as(u32, 1) << @intCast(u5, @ctz(byte_offset | parent_align));
25706 ptr_ty_data.bit_offset = 0;
25707 ptr_ty_data.host_size = 0;
25708 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 };
2570925737 }
2571025738 }
2571125739 } else {
25712 ptr_ty_data.@"align" = field.abi_align;
25740 ptr_ty_data.flags.alignment = field.abi_align;
2571325741 }
2571425742
25715 const ptr_field_ty = try Type.ptr(sema.arena, mod, ptr_ty_data);
25743 const ptr_field_ty = try mod.ptrType(ptr_ty_data);
2571625744
2571725745 if (field.is_comptime) {
2571825746 const val = try mod.intern(.{ .ptr = .{
......@@ -25874,7 +25902,6 @@ fn unionFieldPtr(
2587425902 unresolved_union_ty: Type,
2587525903 initializing: bool,
2587625904) CompileError!Air.Inst.Ref {
25877 const arena = sema.arena;
2587825905 const mod = sema.mod;
2587925906 const ip = &mod.intern_pool;
2588025907
......@@ -25885,11 +25912,13 @@ fn unionFieldPtr(
2588525912 const union_obj = mod.typeToUnion(union_ty).?;
2588625913 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
2588725914 const field = union_obj.fields.values()[field_index];
25888 const ptr_field_ty = try Type.ptr(arena, mod, .{
25889 .pointee_type = field.ty,
25890 .mutable = union_ptr_ty.ptrIsMutable(mod),
25891 .@"volatile" = union_ptr_ty.isVolatilePtr(mod),
25892 .@"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 },
2589325922 });
2589425923 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?);
2589525924
......@@ -26250,11 +26279,13 @@ fn tupleFieldPtr(
2625026279 }
2625126280
2625226281 const field_ty = tuple_ty.structFieldType(field_index, mod);
26253 const ptr_field_ty = try Type.ptr(sema.arena, mod, .{
26254 .pointee_type = field_ty,
26255 .mutable = tuple_ptr_ty.ptrIsMutable(mod),
26256 .@"volatile" = tuple_ptr_ty.isVolatilePtr(mod),
26257 .@"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 },
2625826289 });
2625926290
2626026291 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
......@@ -26705,15 +26736,15 @@ fn coerceExtra(
2670526736
2670626737 // *T to *[1]T
2670726738 single_item: {
26708 if (dest_info.size != .One) break :single_item;
26739 if (dest_info.flags.size != .One) break :single_item;
2670926740 if (!inst_ty.isSinglePointer(mod)) break :single_item;
2671026741 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2671126742 const ptr_elem_ty = inst_ty.childType(mod);
26712 const array_ty = dest_info.pointee_type;
26743 const array_ty = dest_info.child.toType();
2671326744 if (array_ty.zigTypeTag(mod) != .Array) break :single_item;
2671426745 const array_elem_ty = array_ty.childType(mod);
2671526746 if (array_ty.arrayLen(mod) != 1) break :single_item;
26716 const dest_is_mut = dest_info.mutable;
26747 const dest_is_mut = !dest_info.flags.is_const;
2671726748 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
2671826749 .ok => {},
2671926750 else => break :single_item,
......@@ -26728,9 +26759,9 @@ fn coerceExtra(
2672826759 const array_ty = inst_ty.childType(mod);
2672926760 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
2673026761 const array_elem_type = array_ty.childType(mod);
26731 const dest_is_mut = dest_info.mutable;
26762 const dest_is_mut = !dest_info.flags.is_const;
2673226763
26733 const dst_elem_type = dest_info.pointee_type;
26764 const dst_elem_type = dest_info.child.toType();
2673426765 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src);
2673526766 switch (elem_res) {
2673626767 .ok => {},
......@@ -26744,12 +26775,12 @@ fn coerceExtra(
2674426775 },
2674526776 }
2674626777
26747 if (dest_info.sentinel) |dest_sent| {
26778 if (dest_info.sentinel != .none) {
2674826779 if (array_ty.sentinel(mod)) |inst_sent| {
26749 if (!dest_sent.eql(inst_sent, dst_elem_type, mod)) {
26780 if (dest_info.sentinel != (try mod.getCoerced(inst_sent, dst_elem_type)).toIntern()) {
2675026781 in_memory_result = .{ .ptr_sentinel = .{
2675126782 .actual = inst_sent,
26752 .wanted = dest_sent,
26783 .wanted = dest_info.sentinel.toValue(),
2675326784 .ty = dst_elem_type,
2675426785 } };
2675526786 break :src_array_ptr;
......@@ -26757,14 +26788,14 @@ fn coerceExtra(
2675726788 } else {
2675826789 in_memory_result = .{ .ptr_sentinel = .{
2675926790 .actual = Value.@"unreachable",
26760 .wanted = dest_sent,
26791 .wanted = dest_info.sentinel.toValue(),
2676126792 .ty = dst_elem_type,
2676226793 } };
2676326794 break :src_array_ptr;
2676426795 }
2676526796 }
2676626797
26767 switch (dest_info.size) {
26798 switch (dest_info.flags.size) {
2676826799 .Slice => {
2676926800 // *[N]T to []T
2677026801 return sema.coerceArrayPtrToSlice(block, dest_ty, inst, inst_src);
......@@ -26787,8 +26818,8 @@ fn coerceExtra(
2678726818 // In this case we must add a safety check because the C pointer
2678826819 // could be null.
2678926820 const src_elem_ty = inst_ty.childType(mod);
26790 const dest_is_mut = dest_info.mutable;
26791 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();
2679226823 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
2679326824 .ok => {},
2679426825 else => break :src_c_ptr,
......@@ -26798,7 +26829,7 @@ fn coerceExtra(
2679826829
2679926830 // cast from *T and [*]T to *anyopaque
2680026831 // but don't do it if the source type is a double pointer
26801 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: {
2680226833 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2680326834 const elem_ty = inst_ty.elemType2(mod);
2680426835 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
......@@ -26819,7 +26850,7 @@ fn coerceExtra(
2681926850 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
2682026851 }
2682126852
26822 switch (dest_info.size) {
26853 switch (dest_info.flags.size) {
2682326854 // coercion to C pointer
2682426855 .C => switch (inst_ty.zigTypeTag(mod)) {
2682526856 .Null => {
......@@ -26852,9 +26883,9 @@ fn coerceExtra(
2685226883 const inst_info = inst_ty.ptrInfo(mod);
2685326884 switch (try sema.coerceInMemoryAllowed(
2685426885 block,
26855 dest_info.pointee_type,
26856 inst_info.pointee_type,
26857 dest_info.mutable,
26886 dest_info.child.toType(),
26887 inst_info.child.toType(),
26888 !dest_info.flags.is_const,
2685826889 target,
2685926890 dest_ty_src,
2686026891 inst_src,
......@@ -26862,10 +26893,10 @@ fn coerceExtra(
2686226893 .ok => {},
2686326894 else => break :p,
2686426895 }
26865 if (inst_info.size == .Slice) {
26866 assert(dest_info.sentinel == null);
26867 if (inst_info.sentinel == null or
26868 !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())
2686926900 break :p;
2687026901
2687126902 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -26875,7 +26906,7 @@ fn coerceExtra(
2687526906 },
2687626907 else => {},
2687726908 },
26878 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
26909 .One => switch (dest_info.child.toType().zigTypeTag(mod)) {
2687926910 .Union => {
2688026911 // pointer to anonymous struct to pointer to union
2688126912 if (inst_ty.isSinglePointer(mod) and
......@@ -26929,16 +26960,16 @@ fn coerceExtra(
2692926960 // we use a dummy pointer value with the required alignment.
2693026961 return sema.addConstant(dest_ty, (try mod.intern(.{ .ptr = .{
2693126962 .ty = dest_ty.toIntern(),
26932 .addr = .{ .int = (if (dest_info.@"align" != 0)
26933 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().?)
2693426965 else
26935 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() },
2693626967 .len = (try mod.intValue(Type.usize, 0)).toIntern(),
2693726968 } })).toValue());
2693826969 }
2693926970
2694026971 // pointer to tuple to slice
26941 if (dest_info.mutable) {
26972 if (!dest_info.flags.is_const) {
2694226973 const err_msg = err_msg: {
2694326974 const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)});
2694426975 errdefer err_msg.deinit(sema.gpa);
......@@ -26956,9 +26987,9 @@ fn coerceExtra(
2695626987
2695726988 switch (try sema.coerceInMemoryAllowed(
2695826989 block,
26959 dest_info.pointee_type,
26960 inst_info.pointee_type,
26961 dest_info.mutable,
26990 dest_info.child.toType(),
26991 inst_info.child.toType(),
26992 !dest_info.flags.is_const,
2696226993 target,
2696326994 dest_ty_src,
2696426995 inst_src,
......@@ -26967,12 +26998,9 @@ fn coerceExtra(
2696726998 else => break :p,
2696826999 }
2696927000
26970 if (dest_info.sentinel == null or inst_info.sentinel == null or
26971 !dest_info.sentinel.?.eql(
26972 try mod.getCoerced(inst_info.sentinel.?, dest_info.pointee_type),
26973 dest_info.pointee_type,
26974 mod,
26975 ))
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))
2697627004 break :p;
2697727005
2697827006 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -28098,41 +28126,41 @@ fn coerceInMemoryAllowedPtrs(
2809828126 const dest_info = dest_ptr_ty.ptrInfo(mod);
2809928127 const src_info = src_ptr_ty.ptrInfo(mod);
2810028128
28101 const ok_ptr_size = src_info.size == dest_info.size or
28102 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;
2810328131 if (!ok_ptr_size) {
2810428132 return InMemoryCoercionResult{ .ptr_size = .{
28105 .actual = src_info.size,
28106 .wanted = dest_info.size,
28133 .actual = src_info.flags.size,
28134 .wanted = dest_info.flags.size,
2810728135 } };
2810828136 }
2810928137
2811028138 const ok_cv_qualifiers =
28111 (src_info.mutable or !dest_info.mutable) and
28112 (!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);
2811328141
2811428142 if (!ok_cv_qualifiers) {
2811528143 return InMemoryCoercionResult{ .ptr_qualifiers = .{
28116 .actual_const = !src_info.mutable,
28117 .wanted_const = !dest_info.mutable,
28118 .actual_volatile = src_info.@"volatile",
28119 .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,
2812028148 } };
2812128149 }
2812228150
28123 if (dest_info.@"addrspace" != src_info.@"addrspace") {
28151 if (dest_info.flags.address_space != src_info.flags.address_space) {
2812428152 return InMemoryCoercionResult{ .ptr_addrspace = .{
28125 .actual = src_info.@"addrspace",
28126 .wanted = dest_info.@"addrspace",
28153 .actual = src_info.flags.address_space,
28154 .wanted = dest_info.flags.address_space,
2812728155 } };
2812828156 }
2812928157
28130 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);
2813128159 if (child != .ok) {
2813228160 return InMemoryCoercionResult{ .ptr_child = .{
2813328161 .child = try child.dupe(sema.arena),
28134 .actual = src_info.pointee_type,
28135 .wanted = dest_info.pointee_type,
28162 .actual = src_info.child.toType(),
28163 .wanted = dest_info.child.toType(),
2813628164 } };
2813728165 }
2813828166
......@@ -28149,28 +28177,31 @@ fn coerceInMemoryAllowedPtrs(
2814928177 } };
2815028178 }
2815128179
28152 if (src_info.host_size != dest_info.host_size or
28153 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)
2815428182 {
2815528183 return InMemoryCoercionResult{ .ptr_bit_range = .{
28156 .actual_host = src_info.host_size,
28157 .wanted_host = dest_info.host_size,
28158 .actual_offset = src_info.bit_offset,
28159 .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,
2816028188 } };
2816128189 }
2816228190
28163 const ok_sent = dest_info.sentinel == null or src_info.size == .C or
28164 (src_info.sentinel != null and dest_info.sentinel.?.eql(
28165 try mod.getCoerced(src_info.sentinel.?, dest_info.pointee_type),
28166 dest_info.pointee_type,
28167 sema.mod,
28168 ));
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));
2816928194 if (!ok_sent) {
2817028195 return InMemoryCoercionResult{ .ptr_sentinel = .{
28171 .actual = src_info.sentinel orelse Value.@"unreachable",
28172 .wanted = dest_info.sentinel orelse Value.@"unreachable",
28173 .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(),
2817428205 } };
2817528206 }
2817628207
......@@ -28178,22 +28209,14 @@ fn coerceInMemoryAllowedPtrs(
2817828209 // In this case, if they share the same child type, no need to resolve
2817928210 // pointee type alignment. Otherwise both pointee types must have their alignment
2818028211 // resolved and we compare the alignment numerically.
28181 alignment: {
28182 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and
28183 dest_info.pointee_type.eql(src_info.pointee_type, sema.mod))
28184 {
28185 break :alignment;
28186 }
28187
28188 const src_align = if (src_info.@"align" != 0)
28189 src_info.@"align"
28190 else
28191 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);
2819228217
28193 const dest_align = if (dest_info.@"align" != 0)
28194 dest_info.@"align"
28195 else
28196 dest_info.pointee_type.abiAlignment(mod);
28218 const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse
28219 dest_info.child.toType().abiAlignment(mod);
2819728220
2819828221 if (dest_align > src_align) {
2819928222 return InMemoryCoercionResult{ .ptr_alignment = .{
......@@ -28201,8 +28224,6 @@ fn coerceInMemoryAllowedPtrs(
2820128224 .wanted = dest_align,
2820228225 } };
2820328226 }
28204
28205 break :alignment;
2820628227 }
2820728228
2820828229 return .ok;
......@@ -28367,7 +28388,7 @@ fn storePtr2(
2836728388 try sema.requireRuntimeBlock(block, src, runtime_src);
2836828389 try sema.queueFullTypeResolution(elem_ty);
2836928390
28370 if (ptr_ty.ptrInfo(mod).vector_index == .runtime) {
28391 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
2837128392 const ptr_inst = Air.refToIndex(ptr).?;
2837228393 const air_tags = sema.air_instructions.items(.tag);
2837328394 if (air_tags[ptr_inst] == .ptr_elem_ptr) {
......@@ -29219,11 +29240,14 @@ fn beginComptimePtrLoad(
2921929240 // It's possible that we're loading a [N]T, in which case we'd like to slice
2922029241 // the pointee array directly from our parent array.
2922129242 if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) {
29222 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));
29243 const len = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));
2922329244 const elem_idx = try sema.usizeCast(block, src, elem_ptr.index);
29224 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
29225 .ty = try Type.array(sema.arena, N, null, elem_ty, mod),
29226 .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),
2922729251 } else null;
2922829252 break :blk deref;
2922929253 }
......@@ -29410,42 +29434,38 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul
2941029434 const mod = sema.mod;
2941129435 const dest_info = dest_ty.ptrInfo(mod);
2941229436 const inst_info = inst_ty.ptrInfo(mod);
29413 const len0 = (inst_info.pointee_type.zigTypeTag(mod) == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel(mod) == 0 or
29414 (inst_info.pointee_type.arrayLen(mod) == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or
29415 (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);
2941629440
2941729441 const ok_cv_qualifiers =
29418 ((inst_info.mutable or !dest_info.mutable) or len0) and
29419 (!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);
2942029444
2942129445 if (!ok_cv_qualifiers) {
2942229446 in_memory_result.* = .{ .ptr_qualifiers = .{
29423 .actual_const = !inst_info.mutable,
29424 .wanted_const = !dest_info.mutable,
29425 .actual_volatile = inst_info.@"volatile",
29426 .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,
2942729451 } };
2942829452 return false;
2942929453 }
29430 if (dest_info.@"addrspace" != inst_info.@"addrspace") {
29454 if (dest_info.flags.address_space != inst_info.flags.address_space) {
2943129455 in_memory_result.* = .{ .ptr_addrspace = .{
29432 .actual = inst_info.@"addrspace",
29433 .wanted = dest_info.@"addrspace",
29456 .actual = inst_info.flags.address_space,
29457 .wanted = dest_info.flags.address_space,
2943429458 } };
2943529459 return false;
2943629460 }
29437 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;
2943829462 if (len0) return true;
2943929463
29440 const inst_align = if (inst_info.@"align" != 0)
29441 inst_info.@"align"
29442 else
29443 inst_info.pointee_type.abiAlignment(mod);
29464 const inst_align = inst_info.flags.alignment.toByteUnitsOptional() orelse
29465 inst_info.child.toType().abiAlignment(mod);
2944429466
29445 const dest_align = if (dest_info.@"align" != 0)
29446 dest_info.@"align"
29447 else
29448 dest_info.pointee_type.abiAlignment(mod);
29467 const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse
29468 dest_info.child.toType().abiAlignment(mod);
2944929469
2945029470 if (dest_align > inst_align) {
2945129471 in_memory_result.* = .{ .ptr_alignment = .{
......@@ -29882,9 +29902,13 @@ fn coerceTupleToSlicePtrs(
2988229902 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);
2988329903 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
2988429904 const slice_info = slice_ty.ptrInfo(mod);
29885 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 });
2988629910 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
29887 if (slice_info.@"align" != 0) {
29911 if (slice_info.flags.alignment != .none) {
2988829912 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
2988929913 }
2989029914 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst);
......@@ -29903,9 +29927,9 @@ fn coerceTupleToArrayPtrs(
2990329927 const mod = sema.mod;
2990429928 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
2990529929 const ptr_info = ptr_array_ty.ptrInfo(mod);
29906 const array_ty = ptr_info.pointee_type;
29930 const array_ty = ptr_info.child.toType();
2990729931 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);
29908 if (ptr_info.@"align" != 0) {
29932 if (ptr_info.flags.alignment != .none) {
2990929933 return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});
2991029934 }
2991129935 const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst);
......@@ -30244,7 +30268,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
3024430268 const decl = try anon_decl.finish(
3024530269 ty,
3024630270 val,
30247 0, // default alignment
30271 .none, // default alignment
3024830272 );
3024930273 try sema.maybeQueueFuncBodyAnalysis(decl);
3025030274 try mod.declareDeclDependency(sema.owner_decl_index, decl);
......@@ -30285,7 +30309,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo
3028530309 const ptr_ty = try mod.ptrType(.{
3028630310 .child = decl_tv.ty.toIntern(),
3028730311 .flags = .{
30288 .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"),
30312 .alignment = decl.alignment,
3028930313 .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true,
3029030314 .address_space = decl.@"addrspace",
3029130315 },
......@@ -30315,12 +30339,13 @@ fn analyzeRef(
3031530339 src: LazySrcLoc,
3031630340 operand: Air.Inst.Ref,
3031730341) CompileError!Air.Inst.Ref {
30342 const mod = sema.mod;
3031830343 const operand_ty = sema.typeOf(operand);
3031930344
3032030345 if (try sema.resolveMaybeUndefVal(operand)) |val| {
30321 switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {
30346 switch (mod.intern_pool.indexToKey(val.toIntern())) {
3032230347 .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),
30323 .func => |func| return sema.analyzeDeclRef(sema.mod.funcPtr(func.index).owner_decl),
30348 .func => |func| return sema.analyzeDeclRef(mod.funcPtr(func.index).owner_decl),
3032430349 else => {},
3032530350 }
3032630351 var anon_decl = try block.startAnonDecl();
......@@ -30328,20 +30353,22 @@ fn analyzeRef(
3032830353 return sema.analyzeDeclRef(try anon_decl.finish(
3032930354 operand_ty,
3033030355 val,
30331 0, // default alignment
30356 .none, // default alignment
3033230357 ));
3033330358 }
3033430359
3033530360 try sema.requireRuntimeBlock(block, src, null);
30336 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);
30337 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
30338 .pointee_type = operand_ty,
30339 .mutable = false,
30340 .@"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 },
3034130368 });
30342 const mut_ptr_type = try Type.ptr(sema.arena, sema.mod, .{
30343 .pointee_type = operand_ty,
30344 .@"addrspace" = address_space,
30369 const mut_ptr_type = try mod.ptrType(.{
30370 .child = operand_ty.toIntern(),
30371 .flags = .{ .address_space = address_space },
3034530372 });
3034630373 const alloc = try block.addTy(.alloc, mut_ptr_type);
3034730374 try sema.storePtr(block, src, alloc, operand);
......@@ -30374,7 +30401,7 @@ fn analyzeLoad(
3037430401 }
3037530402 }
3037630403
30377 if (ptr_ty.ptrInfo(mod).vector_index == .runtime) {
30404 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
3037830405 const ptr_inst = Air.refToIndex(ptr).?;
3037930406 const air_tags = sema.air_instructions.items(.tag);
3038030407 if (air_tags[ptr_inst] == .ptr_elem_ptr) {
......@@ -30900,20 +30927,24 @@ fn analyzeSlice(
3090030927 const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len);
3090130928
3090230929 const new_ptr_ty_info = new_ptr_ty.ptrInfo(mod);
30903 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;
3090430931
3090530932 if (opt_new_len_val) |new_len_val| {
3090630933 const new_len_int = new_len_val.toUnsignedInt(mod);
3090730934
30908 const return_ty = try Type.ptr(sema.arena, mod, .{
30909 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod),
30910 .sentinel = null,
30911 .@"align" = new_ptr_ty_info.@"align",
30912 .@"addrspace" = new_ptr_ty_info.@"addrspace",
30913 .mutable = new_ptr_ty_info.mutable,
30914 .@"allowzero" = new_allowzero,
30915 .@"volatile" = new_ptr_ty_info.@"volatile",
30916 .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 },
3091730948 });
3091830949
3091930950 const opt_new_ptr_val = try sema.resolveMaybeUndefVal(new_ptr);
......@@ -30962,15 +30993,17 @@ fn analyzeSlice(
3096230993 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
3096330994 }
3096430995
30965 const return_ty = try Type.ptr(sema.arena, mod, .{
30966 .pointee_type = elem_ty,
30967 .sentinel = sentinel,
30968 .@"align" = new_ptr_ty_info.@"align",
30969 .@"addrspace" = new_ptr_ty_info.@"addrspace",
30970 .mutable = new_ptr_ty_info.mutable,
30971 .@"allowzero" = new_allowzero,
30972 .@"volatile" = new_ptr_ty_info.@"volatile",
30973 .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 },
3097431007 });
3097531008
3097631009 try sema.requireRuntimeBlock(block, src, runtime_src.?);
......@@ -31716,7 +31749,7 @@ const PeerResolveStrategy = enum {
3171631749 .Int => .fixed_int,
3171731750 .ComptimeFloat => .comptime_float,
3171831751 .Float => .fixed_float,
31719 .Pointer => if (ty.ptrInfo(mod).size == .C) .c_ptr else .ptr,
31752 .Pointer => if (ty.ptrInfo(mod).flags.size == .C) .c_ptr else .ptr,
3172031753 .Array => .array,
3172131754 .Vector => .vector,
3172231755 .Optional => .optional,
......@@ -32141,7 +32174,7 @@ fn resolvePeerTypesInner(
3214132174 },
3214232175
3214332176 .c_ptr => {
32144 var opt_ptr_info: ?Type.Payload.Pointer.Data = null;
32177 var opt_ptr_info: ?InternPool.Key.PtrType = null;
3214532178 var first_idx: usize = undefined;
3214632179 for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| {
3214732180 const ty = opt_ty orelse continue;
......@@ -32172,42 +32205,47 @@ fn resolvePeerTypesInner(
3217232205
3217332206 var ptr_info = opt_ptr_info orelse {
3217432207 opt_ptr_info = peer_info;
32175 opt_ptr_info.?.size = .C;
32208 opt_ptr_info.?.flags.size = .C;
3217632209 first_idx = i;
3217732210 continue;
3217832211 };
3217932212
3218032213 // Try peer -> cur, then cur -> peer
32181 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 {
3218232215 return .{ .conflict = .{
3218332216 .peer_idx_a = first_idx,
3218432217 .peer_idx_b = i,
3218532218 } };
32186 };
32219 }).toIntern();
3218732220
32188 if (ptr_info.sentinel != null and peer_info.sentinel != null) {
32189 const peer_sent = try mod.getCoerced(ptr_info.sentinel.?, ptr_info.pointee_type);
32190 const ptr_sent = try mod.getCoerced(peer_info.sentinel.?, ptr_info.pointee_type);
32191 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) {
3219232225 ptr_info.sentinel = ptr_sent;
3219332226 } else {
32194 ptr_info.sentinel = null;
32227 ptr_info.sentinel = .none;
3219532228 }
3219632229 } else {
32197 ptr_info.sentinel = null;
32230 ptr_info.sentinel = .none;
3219832231 }
3219932232
32200 // Note that the align can be always non-zero; Type.ptr will canonicalize it
32201 ptr_info.@"align" = @min(ptr_info.alignment(mod), peer_info.alignment(mod));
32202 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) {
3220332241 return .{ .conflict = .{
3220432242 .peer_idx_a = first_idx,
3220532243 .peer_idx_b = i,
3220632244 } };
3220732245 }
3220832246
32209 if (ptr_info.bit_offset != peer_info.bit_offset or
32210 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)
3221132249 {
3221232250 return .{ .conflict = .{
3221332251 .peer_idx_a = first_idx,
......@@ -32215,12 +32253,12 @@ fn resolvePeerTypesInner(
3221532253 } };
3221632254 }
3221732255
32218 ptr_info.mutable = ptr_info.mutable and peer_info.mutable;
32219 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;
3222032258
3222132259 opt_ptr_info = ptr_info;
3222232260 }
32223 return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) };
32261 return .{ .success = try mod.ptrType(opt_ptr_info.?) };
3222432262 },
3222532263
3222632264 .ptr => {
......@@ -32228,17 +32266,19 @@ fn resolvePeerTypesInner(
3222832266 // if there were no actual slices. Else, we want the slice index to report a conflict.
3222932267 var opt_slice_idx: ?usize = null;
3223032268
32231 var opt_ptr_info: ?Type.Payload.Pointer.Data = null;
32269 var opt_ptr_info: ?InternPool.Key.PtrType = null;
3223232270 var first_idx: usize = undefined;
3223332271 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error
3223432272
3223532273 for (peer_tys, 0..) |opt_ty, i| {
3223632274 const ty = opt_ty orelse continue;
32237 const peer_info: Type.Payload.Pointer.Data = switch (ty.zigTypeTag(mod)) {
32275 const peer_info: InternPool.Key.PtrType = switch (ty.zigTypeTag(mod)) {
3223832276 .Pointer => ty.ptrInfo(mod),
3223932277 .Fn => .{
32240 .pointee_type = ty,
32241 .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant),
32278 .child = ty.toIntern(),
32279 .flags = .{
32280 .address_space = target_util.defaultAddressSpace(target, .global_constant),
32281 },
3224232282 },
3224332283 else => return .{ .conflict = .{
3224432284 .peer_idx_a = strat_reason,
......@@ -32246,7 +32286,7 @@ fn resolvePeerTypesInner(
3224632286 } },
3224732287 };
3224832288
32249 switch (peer_info.size) {
32289 switch (peer_info.flags.size) {
3225032290 .One, .Many => {},
3225132291 .Slice => opt_slice_idx = i,
3225232292 .C => return .{ .conflict = .{
......@@ -32270,51 +32310,56 @@ fn resolvePeerTypesInner(
3227032310 } };
3227132311
3227232312 // Note that the align can be always non-zero; Type.ptr will canonicalize it
32273 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 ));
3227432319
32275 if (ptr_info.@"addrspace" != peer_info.@"addrspace") {
32320 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
3227632321 return generic_err;
3227732322 }
3227832323
32279 if (ptr_info.bit_offset != peer_info.bit_offset or
32280 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)
3228132326 {
3228232327 return generic_err;
3228332328 }
3228432329
32285 ptr_info.mutable = ptr_info.mutable and peer_info.mutable;
32286 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;
3228732332
32288 const peer_sentinel: ?Value = switch (peer_info.size) {
32289 .One => switch (peer_info.pointee_type.zigTypeTag(mod)) {
32290 .Array => peer_info.pointee_type.sentinel(mod),
32291 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,
3229232337 },
3229332338 .Many, .Slice => peer_info.sentinel,
3229432339 .C => unreachable,
3229532340 };
3229632341
32297 const cur_sentinel: ?Value = switch (ptr_info.size) {
32298 .One => switch (ptr_info.pointee_type.zigTypeTag(mod)) {
32299 .Array => ptr_info.pointee_type.sentinel(mod),
32300 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,
3230132346 },
3230232347 .Many, .Slice => ptr_info.sentinel,
3230332348 .C => unreachable,
3230432349 };
3230532350
3230632351 // We abstract array handling slightly so that tuple pointers can work like array pointers
32307 const peer_pointee_array = sema.typeIsArrayLike(peer_info.pointee_type);
32308 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());
3230932354
3231032355 // This switch is just responsible for deciding the size and pointee (not including
3231132356 // single-pointer array sentinel).
3231232357 good: {
32313 switch (peer_info.size) {
32314 .One => switch (ptr_info.size) {
32358 switch (peer_info.flags.size) {
32359 .One => switch (ptr_info.flags.size) {
3231532360 .One => {
32316 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {
32317 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();
3231832363 break :good;
3231932364 }
3232032365
......@@ -32324,29 +32369,29 @@ fn resolvePeerTypesInner(
3232432369 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {
3232532370 // *[n:x]T + *[n:y]T = *[n]T
3232632371 if (cur_arr.len == peer_arr.len) {
32327 ptr_info.pointee_type = try mod.arrayType(.{
32372 ptr_info.child = (try mod.arrayType(.{
3232832373 .len = cur_arr.len,
3232932374 .child = elem_ty.toIntern(),
32330 });
32375 })).toIntern();
3233132376 break :good;
3233232377 }
3233332378 // *[a]T + *[b]T = []T
32334 ptr_info.size = .Slice;
32335 ptr_info.pointee_type = elem_ty;
32379 ptr_info.flags.size = .Slice;
32380 ptr_info.child = elem_ty.toIntern();
3233632381 break :good;
3233732382 }
3233832383
3233932384 if (peer_arr.elem_ty.toIntern() == .noreturn_type) {
3234032385 // *struct{} + *[a]T = []T
32341 ptr_info.size = .Slice;
32342 ptr_info.pointee_type = cur_arr.elem_ty;
32386 ptr_info.flags.size = .Slice;
32387 ptr_info.child = cur_arr.elem_ty.toIntern();
3234332388 break :good;
3234432389 }
3234532390
3234632391 if (cur_arr.elem_ty.toIntern() == .noreturn_type) {
3234732392 // *[a]T + *struct{} = []T
32348 ptr_info.size = .Slice;
32349 ptr_info.pointee_type = peer_arr.elem_ty;
32393 ptr_info.flags.size = .Slice;
32394 ptr_info.child = peer_arr.elem_ty.toIntern();
3235032395 break :good;
3235132396 }
3235232397
......@@ -32355,8 +32400,8 @@ fn resolvePeerTypesInner(
3235532400 .Many => {
3235632401 // Only works for *[n]T + [*]T -> [*]T
3235732402 const arr = peer_pointee_array orelse return generic_err;
32358 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| {
32359 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();
3236032405 break :good;
3236132406 }
3236232407 if (arr.elem_ty.toIntern() == .noreturn_type) {
......@@ -32368,8 +32413,8 @@ fn resolvePeerTypesInner(
3236832413 .Slice => {
3236932414 // Only works for *[n]T + []T -> []T
3237032415 const arr = peer_pointee_array orelse return generic_err;
32371 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| {
32372 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();
3237332418 break :good;
3237432419 }
3237532420 if (arr.elem_ty.toIntern() == .noreturn_type) {
......@@ -32380,26 +32425,26 @@ fn resolvePeerTypesInner(
3238032425 },
3238132426 .C => unreachable,
3238232427 },
32383 .Many => switch (ptr_info.size) {
32428 .Many => switch (ptr_info.flags.size) {
3238432429 .One => {
3238532430 // Only works for [*]T + *[n]T -> [*]T
3238632431 const arr = cur_pointee_array orelse return generic_err;
32387 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| {
32388 ptr_info.size = .Many;
32389 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();
3239032435 break :good;
3239132436 }
3239232437 if (arr.elem_ty.toIntern() == .noreturn_type) {
3239332438 // [*]T + *struct{} -> [*]T
32394 ptr_info.size = .Many;
32395 ptr_info.pointee_type = peer_info.pointee_type;
32439 ptr_info.flags.size = .Many;
32440 ptr_info.child = peer_info.child;
3239632441 break :good;
3239732442 }
3239832443 return generic_err;
3239932444 },
3240032445 .Many => {
32401 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {
32402 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();
3240332448 break :good;
3240432449 }
3240532450 return generic_err;
......@@ -32413,28 +32458,28 @@ fn resolvePeerTypesInner(
3241332458 } };
3241432459 }
3241532460 // Okay, then works for [*]T + "[]T" -> [*]T
32416 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {
32417 ptr_info.size = .Many;
32418 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();
3241932464 break :good;
3242032465 }
3242132466 return generic_err;
3242232467 },
3242332468 .C => unreachable,
3242432469 },
32425 .Slice => switch (ptr_info.size) {
32470 .Slice => switch (ptr_info.flags.size) {
3242632471 .One => {
3242732472 // Only works for []T + *[n]T -> []T
3242832473 const arr = cur_pointee_array orelse return generic_err;
32429 if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| {
32430 ptr_info.size = .Slice;
32431 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();
3243232477 break :good;
3243332478 }
3243432479 if (arr.elem_ty.toIntern() == .noreturn_type) {
3243532480 // []T + *struct{} -> []T
32436 ptr_info.size = .Slice;
32437 ptr_info.pointee_type = peer_info.pointee_type;
32481 ptr_info.flags.size = .Slice;
32482 ptr_info.child = peer_info.child;
3243832483 break :good;
3243932484 }
3244032485 return generic_err;
......@@ -32444,8 +32489,8 @@ fn resolvePeerTypesInner(
3244432489 return generic_err;
3244532490 },
3244632491 .Slice => {
32447 if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| {
32448 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();
3244932494 break :good;
3245032495 }
3245132496 return generic_err;
......@@ -32456,40 +32501,43 @@ fn resolvePeerTypesInner(
3245632501 }
3245732502 }
3245832503
32459 const sentinel_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Array) blk: {
32460 break :blk ptr_info.pointee_type.childType(mod);
32461 } else ptr_info.pointee_type;
32462
32463 // 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 };
3246432511
3246532512 sentinel: {
3246632513 no_sentinel: {
32467 if (peer_sentinel == null) break :no_sentinel;
32468 if (cur_sentinel == null) break :no_sentinel;
32469 const peer_sent_coerced = try mod.getCoerced(peer_sentinel.?, sentinel_ty);
32470 const cur_sent_coerced = try mod.getCoerced(cur_sentinel.?, sentinel_ty);
32471 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;
3247232519 // Sentinels match
32473 if (ptr_info.size == .One) {
32474 assert(ptr_info.pointee_type.zigTypeTag(mod) == .Array);
32475 ptr_info.pointee_type = try mod.arrayType(.{
32476 .len = ptr_info.pointee_type.arrayLen(mod),
32477 .child = ptr_info.pointee_type.childType(mod).toIntern(),
32478 .sentinel = cur_sent_coerced.toIntern(),
32479 });
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,
3248032527 } else {
3248132528 ptr_info.sentinel = cur_sent_coerced;
3248232529 }
3248332530 break :sentinel;
3248432531 }
3248532532 // Clear existing sentinel
32486 ptr_info.sentinel = null;
32487 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
32488 ptr_info.pointee_type = try mod.arrayType(.{
32489 .len = ptr_info.pointee_type.arrayLen(mod),
32490 .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,
3249132538 .sentinel = .none,
32492 });
32539 })).toIntern(),
32540 else => {},
3249332541 }
3249432542 }
3249532543
......@@ -32500,17 +32548,22 @@ fn resolvePeerTypesInner(
3250032548 // &.{} and &.{}, we'll currently have a pointer type of `*[0]noreturn` - we wanted to
3250132549 // coerce the empty struct to a specific type, but no peer provided one. We need to
3250232550 // detect this case and emit an error.
32503 const pointee = opt_ptr_info.?.pointee_type;
32504 if (pointee.toIntern() == .noreturn_type or
32505 (pointee.zigTypeTag(mod) == .Array and pointee.childType(mod).toIntern() == .noreturn_type))
32506 {
32507 return .{ .conflict = .{
32551 const pointee = opt_ptr_info.?.child;
32552 switch (pointee) {
32553 .noreturn_type => return .{ .conflict = .{
3250832554 .peer_idx_a = first_idx,
3250932555 .peer_idx_b = other_idx,
32510 } };
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 },
3251132564 }
3251232565
32513 return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) };
32566 return .{ .success = try mod.ptrType(opt_ptr_info.?) };
3251432567 },
3251532568
3251632569 .func => {
......@@ -34158,7 +34211,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3415834211 }
3415934212 gop.value_ptr.* = .{
3416034213 .ty = Type.noreturn,
34161 .abi_align = 0,
34214 .abi_align = .none,
3416234215 .default_val = .none,
3416334216 .is_comptime = is_comptime,
3416434217 .offset = undefined,
......@@ -34695,7 +34748,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3469534748
3469634749 gop.value_ptr.* = .{
3469734750 .ty = field_ty,
34698 .abi_align = 0,
34751 .abi_align = .none,
3469934752 };
3470034753
3470134754 if (align_ref != .none) {
......@@ -34711,7 +34764,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3471134764 else => |e| return e,
3471234765 };
3471334766 } else {
34714 gop.value_ptr.abi_align = 0;
34767 gop.value_ptr.abi_align = .none;
3471534768 }
3471634769 }
3471734770
......@@ -35335,15 +35388,19 @@ fn analyzeComptimeAlloc(
3533535388 sema: *Sema,
3533635389 block: *Block,
3533735390 var_type: Type,
35338 alignment: u32,
35391 alignment: Alignment,
3533935392) CompileError!Air.Inst.Ref {
35393 const mod = sema.mod;
35394
3534035395 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
3534135396 _ = try sema.typeHasOnePossibleValue(var_type);
3534235397
35343 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
35344 .pointee_type = var_type,
35345 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),
35346 .@"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 },
3534735404 });
3534835405
3534935406 var anon_decl = try block.startAnonDecl();
......@@ -35354,15 +35411,15 @@ fn analyzeComptimeAlloc(
3535435411 // There will be stores before the first load, but they may be to sub-elements or
3535535412 // sub-fields. So we need to initialize with undef to allow the mechanism to expand
3535635413 // into fields/elements and have those overridden with stored values.
35357 (try sema.mod.intern(.{ .undef = var_type.toIntern() })).toValue(),
35414 (try mod.intern(.{ .undef = var_type.toIntern() })).toValue(),
3535835415 alignment,
3535935416 );
35360 const decl = sema.mod.declPtr(decl_index);
35361 decl.@"align" = alignment;
35417 const decl = mod.declPtr(decl_index);
35418 decl.alignment = alignment;
3536235419
3536335420 try sema.comptime_mutable_decls.append(decl_index);
35364 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
35365 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 = .{
3536635423 .ty = ptr_type.toIntern(),
3536735424 .addr = .{ .mut_decl = .{
3536835425 .decl = decl_index,
......@@ -35747,14 +35804,10 @@ fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {
3574735804/// Not valid to call for packed unions.
3574835805/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.
3574935806fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 {
35750 const mod = sema.mod;
35751 if (field.ty.zigTypeTag(mod) == .NoReturn) {
35752 return @as(u32, 0);
35753 } else if (field.abi_align == 0) {
35754 return sema.typeAbiAlignment(field.ty);
35755 } else {
35756 return field.abi_align;
35757 }
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));
3575835811}
3575935812
3576035813/// Synchronize logic with `Type.isFnOrHasRuntimeBits`.
......@@ -36405,16 +36458,16 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3640536458 const mod = sema.mod;
3640636459 const ptr_info = ptr_ty.ptrInfo(mod);
3640736460 const elem_ty = ptr_ty.elemType2(mod);
36408 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;
3640936462 const parent_ty = ptr_ty.childType(mod);
3641036463
36411 const VI = Type.Payload.Pointer.Data.VectorIndex;
36464 const VI = InternPool.Key.PtrType.VectorIndex;
3641236465
3641336466 const vector_info: struct {
3641436467 host_size: u16 = 0,
3641536468 alignment: u32 = 0,
3641636469 vector_index: VI = .none,
36417 } = if (parent_ty.isVector(mod) and ptr_info.size == .One) blk: {
36470 } = if (parent_ty.isVector(mod) and ptr_info.flags.size == .One) blk: {
3641836471 const elem_bits = elem_ty.bitSize(mod);
3641936472 if (elem_bits == 0) break :blk .{};
3642036473 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
......@@ -36422,17 +36475,17 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3642236475
3642336476 break :blk .{
3642436477 .host_size = @intCast(u16, parent_ty.arrayLen(mod)),
36425 .alignment = @intCast(u16, parent_ty.abiAlignment(mod)),
36478 .alignment = @intCast(u32, parent_ty.abiAlignment(mod)),
3642636479 .vector_index = if (offset) |some| @enumFromInt(VI, some) else .runtime,
3642736480 };
3642836481 } else .{};
3642936482
36430 const alignment: u32 = a: {
36483 const alignment: Alignment = a: {
3643136484 // Calculate the new pointer alignment.
36432 if (ptr_info.@"align" == 0) {
36433 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);
3643436487 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
36435 break :a 0;
36488 break :a .none;
3643636489 }
3643736490 // If the addend is not a comptime-known value we can still count on
3643836491 // it being a multiple of the type size.
......@@ -36442,18 +36495,27 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3644236495 // The resulting pointer is aligned to the lcd between the offset (an
3644336496 // arbitrary number) and the alignment factor (always a power of two,
3644436497 // non zero).
36445 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);
3644636503 break :a new_align;
3644736504 };
36448 return try Type.ptr(sema.arena, sema.mod, .{
36449 .pointee_type = elem_ty,
36450 .mutable = ptr_info.mutable,
36451 .@"addrspace" = ptr_info.@"addrspace",
36452 .@"allowzero" = allow_zero,
36453 .@"volatile" = ptr_info.@"volatile",
36454 .@"align" = alignment,
36455 .host_size = vector_info.host_size,
36456 .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 },
3645736519 });
3645836520}
3645936521
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+35-175
......@@ -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});
222 }
223
224 if (info.bit_offset != 0 or info.host_size != 0) {
225 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
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 });
226214 }
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`.
......@@ -3345,58 +3331,6 @@ pub const Type = struct {
33453331 };
33463332 }
33473333
3348 pub const Payload = struct {
3349 /// TODO: remove this data structure since we have `InternPool.Key.PtrType`.
3350 pub const Pointer = struct {
3351 pub const Data = struct {
3352 pointee_type: Type,
3353 sentinel: ?Value = null,
3354 /// If zero use pointee_type.abiAlignment()
3355 /// When creating pointer types, if alignment is equal to pointee type
3356 /// abi alignment, this value should be set to 0 instead.
3357 @"align": u32 = 0,
3358 /// See src/target.zig defaultAddressSpace function for how to obtain
3359 /// an appropriate value for this field.
3360 @"addrspace": std.builtin.AddressSpace,
3361 bit_offset: u16 = 0,
3362 /// If this is non-zero it means the pointer points to a sub-byte
3363 /// range of data, which is backed by a "host integer" with this
3364 /// number of bytes.
3365 /// When host_size=pointee_abi_size and bit_offset=0, this must be
3366 /// represented with host_size=0 instead.
3367 host_size: u16 = 0,
3368 vector_index: VectorIndex = .none,
3369 @"allowzero": bool = false,
3370 mutable: bool = true, // TODO rename this to const, not mutable
3371 @"volatile": bool = false,
3372 size: std.builtin.Type.Pointer.Size = .One,
3373
3374 pub const VectorIndex = InternPool.Key.PtrType.VectorIndex;
3375
3376 pub fn alignment(data: Data, mod: *Module) u32 {
3377 if (data.@"align" != 0) return data.@"align";
3378 return abiAlignment(data.pointee_type, mod);
3379 }
3380
3381 pub fn fromKey(p: InternPool.Key.PtrType) Data {
3382 return .{
3383 .pointee_type = p.child.toType(),
3384 .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null,
3385 .@"align" = @intCast(u32, p.flags.alignment.toByteUnits(0)),
3386 .@"addrspace" = p.flags.address_space,
3387 .bit_offset = p.packed_offset.bit_offset,
3388 .host_size = p.packed_offset.host_size,
3389 .vector_index = p.flags.vector_index,
3390 .@"allowzero" = p.flags.is_allowzero,
3391 .mutable = !p.flags.is_const,
3392 .@"volatile" = p.flags.is_volatile,
3393 .size = p.flags.size,
3394 };
3395 }
3396 };
3397 };
3398 };
3399
34003334 pub const @"u1": Type = .{ .ip_index = .u1_type };
34013335 pub const @"u8": Type = .{ .ip_index = .u8_type };
34023336 pub const @"u16": Type = .{ .ip_index = .u16_type };
......@@ -3454,80 +3388,6 @@ pub const Type = struct {
34543388
34553389 pub const err_int = Type.u16;
34563390
3457 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
3458 // TODO: update callsites of this function to directly call mod.ptrType
3459 // and then delete this function.
3460 _ = arena;
3461
3462 var d = data;
3463
3464 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
3465 // type, we change it to 0 here. If this causes an assertion trip because the
3466 // pointee type needs to be resolved more, that needs to be done before calling
3467 // this ptr() function.
3468 if (d.@"align" != 0) canonicalize: {
3469 if (!d.pointee_type.layoutIsResolved(mod)) break :canonicalize;
3470 if (d.@"align" == d.pointee_type.abiAlignment(mod)) {
3471 d.@"align" = 0;
3472 }
3473 }
3474
3475 // Canonicalize host_size. If it matches the bit size of the pointee type,
3476 // we change it to 0 here. If this causes an assertion trip, the pointee type
3477 // needs to be resolved before calling this ptr() function.
3478 if (d.host_size != 0) {
3479 assert(d.bit_offset < d.host_size * 8);
3480 if (d.host_size * 8 == d.pointee_type.bitSize(mod)) {
3481 assert(d.bit_offset == 0);
3482 d.host_size = 0;
3483 }
3484 }
3485
3486 return mod.ptrType(.{
3487 .child = d.pointee_type.ip_index,
3488 .sentinel = if (d.sentinel) |s| s.ip_index else .none,
3489 .flags = .{
3490 .alignment = InternPool.Alignment.fromByteUnits(d.@"align"),
3491 .vector_index = d.vector_index,
3492 .size = d.size,
3493 .is_const = !d.mutable,
3494 .is_volatile = d.@"volatile",
3495 .is_allowzero = d.@"allowzero",
3496 .address_space = d.@"addrspace",
3497 },
3498 .packed_offset = .{
3499 .host_size = d.host_size,
3500 .bit_offset = d.bit_offset,
3501 },
3502 });
3503 }
3504
3505 pub fn array(
3506 arena: Allocator,
3507 len: u64,
3508 sent: ?Value,
3509 elem_type: Type,
3510 mod: *Module,
3511 ) Allocator.Error!Type {
3512 // TODO: update callsites of this function to directly call mod.arrayType
3513 // and then delete this function.
3514 _ = arena;
3515
3516 return mod.arrayType(.{
3517 .len = len,
3518 .child = elem_type.ip_index,
3519 .sentinel = if (sent) |s| s.ip_index else .none,
3520 });
3521 }
3522
3523 pub fn optional(arena: Allocator, child_type: Type, mod: *Module) Allocator.Error!Type {
3524 // TODO: update callsites of this function to directly call
3525 // mod.optionalType and then delete this function.
3526 _ = arena;
3527
3528 return mod.optionalType(child_type.ip_index);
3529 }
3530
35313391 pub fn smallestUnsignedBits(max: u64) u16 {
35323392 if (max == 0) return 0;
35333393 const base = std.math.log2(max);