authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-08-11 19:28:42-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-08-25 15:16:46-07:00
log80cd53d3bbf5cdc82715a4400592b40fb93cd5c9
tree5f12824c1173b4a2fc9cc78f39a0226419a18f54
parentb4bb64ce78bf2dee9437f366a362ef4d8c77b204
signaturelock-open Commit is signed but in an unrecognized format.

sema: clean-up `{union,struct}FieldAlignment` and friends

My main gripes with this design were that it was incorrectly namespaced, the naming was inconsistent and a bit wrong (`fooAlign` vs `fooAlignment`). This commit moves all the logic from `PerThread.zig` to use the zcu + tid system that the previous couple commits introduce. I've organized and merged the functions to be a bit more specific to their own purpose. - `fieldAlignment` takes a struct or union type, an index, and a Zcu (or the Sema version which takes a Pt), and gives you the alignment of the field at the index. - `structFieldAlignment` takes the field type itself, and provides the logic to handle special cases, such as externs. A design goal I had in mind was to avoid using the word 'struct' in the function name, when it worked for things that aren't structs, such as unions.

20 files changed, 194 insertions(+), 223 deletions(-)

src/Sema.zig+44-66
...@@ -4887,7 +4887,7 @@ fn validateStructInit(...@@ -4887,7 +4887,7 @@ fn validateStructInit(
4887 const i: u32 = @intCast(i_usize);4887 const i: u32 = @intCast(i_usize);
4888 if (opt_field_ptr.unwrap()) |field_ptr| {4888 if (opt_field_ptr.unwrap()) |field_ptr| {
4889 // Determine whether the value stored to this pointer is comptime-known.4889 // Determine whether the value stored to this pointer is comptime-known.
4890 const field_ty = struct_ty.structFieldType(i, zcu);4890 const field_ty = struct_ty.fieldType(i, zcu);
4891 if (try sema.typeHasOnePossibleValue(field_ty)) |opv| {4891 if (try sema.typeHasOnePossibleValue(field_ty)) |opv| {
4892 field_values[i] = opv.toIntern();4892 field_values[i] = opv.toIntern();
4893 continue;4893 continue;
...@@ -4999,7 +4999,7 @@ fn validateStructInit(...@@ -4999,7 +4999,7 @@ fn validateStructInit(
4999 var block_index = first_block_index;4999 var block_index = first_block_index;
5000 for (block.instructions.items[first_block_index..]) |cur_inst| {5000 for (block.instructions.items[first_block_index..]) |cur_inst| {
5001 while (field_ptr_ref == .none and init_index < instrs.len) : (init_index += 1) {5001 while (field_ptr_ref == .none and init_index < instrs.len) : (init_index += 1) {
5002 const field_ty = struct_ty.structFieldType(field_indices[init_index], zcu);5002 const field_ty = struct_ty.fieldType(field_indices[init_index], zcu);
5003 if (try field_ty.onePossibleValue(pt)) |_| continue;5003 if (try field_ty.onePossibleValue(pt)) |_| continue;
5004 field_ptr_ref = sema.inst_map.get(instrs[init_index]).?;5004 field_ptr_ref = sema.inst_map.get(instrs[init_index]).?;
5005 }5005 }
...@@ -8430,7 +8430,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8430,7 +8430,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8430 try indexable_ty.resolveFields(pt);8430 try indexable_ty.resolveFields(pt);
8431 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction8431 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction
8432 if (indexable_ty.zigTypeTag(zcu) == .Struct) {8432 if (indexable_ty.zigTypeTag(zcu) == .Struct) {
8433 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), zcu);8433 const elem_type = indexable_ty.fieldType(@intFromEnum(bin.rhs), zcu);
8434 return Air.internedToRef(elem_type.toIntern());8434 return Air.internedToRef(elem_type.toIntern());
8435 } else {8435 } else {
8436 const elem_type = indexable_ty.elemType2(zcu);8436 const elem_type = indexable_ty.elemType2(zcu);
...@@ -14419,7 +14419,7 @@ fn analyzeTupleCat(...@@ -14419,7 +14419,7 @@ fn analyzeTupleCat(
14419 var runtime_src: ?LazySrcLoc = null;14419 var runtime_src: ?LazySrcLoc = null;
14420 var i: u32 = 0;14420 var i: u32 = 0;
14421 while (i < lhs_len) : (i += 1) {14421 while (i < lhs_len) : (i += 1) {
14422 types[i] = lhs_ty.structFieldType(i, zcu).toIntern();14422 types[i] = lhs_ty.fieldType(i, zcu).toIntern();
14423 const default_val = lhs_ty.structFieldDefaultValue(i, zcu);14423 const default_val = lhs_ty.structFieldDefaultValue(i, zcu);
14424 values[i] = default_val.toIntern();14424 values[i] = default_val.toIntern();
14425 const operand_src = block.src(.{ .array_cat_lhs = .{14425 const operand_src = block.src(.{ .array_cat_lhs = .{
...@@ -14433,7 +14433,7 @@ fn analyzeTupleCat(...@@ -14433,7 +14433,7 @@ fn analyzeTupleCat(
14433 }14433 }
14434 i = 0;14434 i = 0;
14435 while (i < rhs_len) : (i += 1) {14435 while (i < rhs_len) : (i += 1) {
14436 types[i + lhs_len] = rhs_ty.structFieldType(i, zcu).toIntern();14436 types[i + lhs_len] = rhs_ty.fieldType(i, zcu).toIntern();
14437 const default_val = rhs_ty.structFieldDefaultValue(i, zcu);14437 const default_val = rhs_ty.structFieldDefaultValue(i, zcu);
14438 values[i + lhs_len] = default_val.toIntern();14438 values[i + lhs_len] = default_val.toIntern();
14439 const operand_src = block.src(.{ .array_cat_rhs = .{14439 const operand_src = block.src(.{ .array_cat_rhs = .{
...@@ -14791,7 +14791,7 @@ fn analyzeTupleMul(...@@ -14791,7 +14791,7 @@ fn analyzeTupleMul(
14791 const opt_runtime_src = rs: {14791 const opt_runtime_src = rs: {
14792 var runtime_src: ?LazySrcLoc = null;14792 var runtime_src: ?LazySrcLoc = null;
14793 for (0..tuple_len) |i| {14793 for (0..tuple_len) |i| {
14794 types[i] = operand_ty.structFieldType(i, zcu).toIntern();14794 types[i] = operand_ty.fieldType(i, zcu).toIntern();
14795 values[i] = operand_ty.structFieldDefaultValue(i, zcu).toIntern();14795 values[i] = operand_ty.structFieldDefaultValue(i, zcu).toIntern();
14796 const operand_src = block.src(.{ .array_cat_lhs = .{14796 const operand_src = block.src(.{ .array_cat_lhs = .{
14797 .array_cat_offset = src_node,14797 .array_cat_offset = src_node,
...@@ -18466,13 +18466,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18466,13 +18466,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18466 };18466 };
1846718467
18468 const alignment = switch (layout) {18468 const alignment = switch (layout) {
18469 .auto, .@"extern" => try Type.unionFieldNormalAlignmentAdvanced(18469 .auto, .@"extern" => try ty.fieldAlignmentSema(field_index, pt),
18470 union_obj,
18471 @intCast(field_index),
18472 .sema,
18473 pt.zcu,
18474 pt.tid,
18475 ),
18476 .@"packed" => .none,18470 .@"packed" => .none,
18477 };18471 };
1847818472
...@@ -18691,12 +18685,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18691,12 +18685,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18691 const default_val_ptr = try sema.optRefValue(opt_default_val);18685 const default_val_ptr = try sema.optRefValue(opt_default_val);
18692 const alignment = switch (struct_type.layout) {18686 const alignment = switch (struct_type.layout) {
18693 .@"packed" => .none,18687 .@"packed" => .none,
18694 else => try field_ty.structFieldAlignmentAdvanced(18688 else => try field_ty.structFieldAlignmentSema(
18695 struct_type.fieldAlign(ip, field_index),18689 struct_type.fieldAlign(ip, field_index),
18696 struct_type.layout,18690 struct_type.layout,
18697 .sema,18691 pt,
18698 pt.zcu,
18699 pt.tid,
18700 ),18692 ),
18701 };18693 };
1870218694
...@@ -20327,7 +20319,7 @@ fn zirStructInit(...@@ -20327,7 +20319,7 @@ fn zirStructInit(
20327 assert(field_inits[field_index] == .none);20319 assert(field_inits[field_index] == .none);
20328 found_fields[field_index] = item.data.field_type;20320 found_fields[field_index] = item.data.field_type;
20329 const uncoerced_init = try sema.resolveInst(item.data.init);20321 const uncoerced_init = try sema.resolveInst(item.data.init);
20330 const field_ty = resolved_ty.structFieldType(field_index, zcu);20322 const field_ty = resolved_ty.fieldType(field_index, zcu);
20331 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);20323 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);
20332 if (!is_packed) {20324 if (!is_packed) {
20333 try resolved_ty.resolveStructFieldInits(pt);20325 try resolved_ty.resolveStructFieldInits(pt);
...@@ -20338,7 +20330,7 @@ fn zirStructInit(...@@ -20338,7 +20330,7 @@ fn zirStructInit(
20338 });20330 });
20339 };20331 };
2034020332
20341 if (!init_val.eql(default_value, resolved_ty.structFieldType(field_index, zcu), zcu)) {20333 if (!init_val.eql(default_value, resolved_ty.fieldType(field_index, zcu), zcu)) {
20342 return sema.failWithInvalidComptimeFieldStore(block, field_src, resolved_ty, field_index);20334 return sema.failWithInvalidComptimeFieldStore(block, field_src, resolved_ty, field_index);
20343 }20335 }
20344 }20336 }
...@@ -20799,7 +20791,7 @@ fn zirArrayInit(...@@ -20799,7 +20791,7 @@ fn zirArrayInit(
20799 const arg = args[i + 1];20791 const arg = args[i + 1];
20800 const resolved_arg = try sema.resolveInst(arg);20792 const resolved_arg = try sema.resolveInst(arg);
20801 const elem_ty = if (is_tuple)20793 const elem_ty = if (is_tuple)
20802 array_ty.structFieldType(i, zcu)20794 array_ty.fieldType(i, zcu)
20803 else20795 else
20804 array_ty.elemType2(zcu);20796 array_ty.elemType2(zcu);
20805 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);20797 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
...@@ -20862,7 +20854,7 @@ fn zirArrayInit(...@@ -20862,7 +20854,7 @@ fn zirArrayInit(
20862 if (is_tuple) {20854 if (is_tuple) {
20863 for (resolved_args, 0..) |arg, i| {20855 for (resolved_args, 0..) |arg, i| {
20864 const elem_ptr_ty = try pt.ptrTypeSema(.{20856 const elem_ptr_ty = try pt.ptrTypeSema(.{
20865 .child = array_ty.structFieldType(i, zcu).toIntern(),20857 .child = array_ty.fieldType(i, zcu).toIntern(),
20866 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20858 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20867 });20859 });
20868 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());20860 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());
...@@ -25234,7 +25226,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -25234,7 +25226,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
25234 },25226 },
25235 .packed_offset = parent_ptr_info.packed_offset,25227 .packed_offset = parent_ptr_info.packed_offset,
25236 };25228 };
25237 const field_ty = parent_ty.structFieldType(field_index, zcu);25229 const field_ty = parent_ty.fieldType(field_index, zcu);
25238 var actual_field_ptr_info: InternPool.Key.PtrType = .{25230 var actual_field_ptr_info: InternPool.Key.PtrType = .{
25239 .child = field_ty.toIntern(),25231 .child = field_ty.toIntern(),
25240 .flags = .{25232 .flags = .{
...@@ -25249,19 +25241,17 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -25249,19 +25241,17 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
25249 switch (parent_ty.containerLayout(zcu)) {25241 switch (parent_ty.containerLayout(zcu)) {
25250 .auto => {25242 .auto => {
25251 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(25243 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(
25252 if (zcu.typeToStruct(parent_ty)) |struct_obj| try field_ty.structFieldAlignmentAdvanced(25244 if (zcu.typeToStruct(parent_ty)) |struct_obj|
25253 struct_obj.fieldAlign(ip, field_index),25245 try field_ty.structFieldAlignmentSema(
25254 struct_obj.layout,25246 struct_obj.fieldAlign(ip, field_index),
25255 .sema,25247 struct_obj.layout,
25256 pt.zcu,25248 pt,
25257 pt.tid,25249 )
25258 ) else if (zcu.typeToUnion(parent_ty)) |union_obj|25250 else if (zcu.typeToUnion(parent_ty)) |union_obj|
25259 try Type.unionFieldNormalAlignmentAdvanced(25251 try field_ty.unionFieldAlignmentSema(
25260 union_obj,25252 union_obj.fieldAlign(ip, field_index),
25261 field_index,25253 union_obj.flagsUnordered(ip).layout,
25262 .sema,25254 pt,
25263 pt.zcu,
25264 pt.tid,
25265 )25255 )
25266 else25256 else
25267 actual_field_ptr_info.flags.alignment,25257 actual_field_ptr_info.flags.alignment,
...@@ -28035,14 +28025,14 @@ fn fieldCallBind(...@@ -28035,14 +28025,14 @@ fn fieldCallBind(
28035 }28025 }
28036 if (field_name.toUnsigned(ip)) |field_index| {28026 if (field_name.toUnsigned(ip)) |field_index| {
28037 if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field;28027 if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field;
28038 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, zcu), field_index, object_ptr);28028 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.fieldType(field_index, zcu), field_index, object_ptr);
28039 }28029 }
28040 } else {28030 } else {
28041 const max = concrete_ty.structFieldCount(zcu);28031 const max = concrete_ty.structFieldCount(zcu);
28042 for (0..max) |i_usize| {28032 for (0..max) |i_usize| {
28043 const i: u32 = @intCast(i_usize);28033 const i: u32 = @intCast(i_usize);
28044 if (field_name == concrete_ty.structFieldName(i, zcu).unwrap().?) {28034 if (field_name == concrete_ty.structFieldName(i, zcu).unwrap().?) {
28045 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, zcu), i, object_ptr);28035 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.fieldType(i, zcu), i, object_ptr);
28046 }28036 }
28047 }28037 }
28048 }28038 }
...@@ -28340,12 +28330,10 @@ fn structFieldPtrByIndex(...@@ -28340,12 +28330,10 @@ fn structFieldPtrByIndex(
28340 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));28330 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));
28341 } else {28331 } else {
28342 // Our alignment is capped at the field alignment.28332 // Our alignment is capped at the field alignment.
28343 const field_align = try Type.fromInterned(field_ty).structFieldAlignmentAdvanced(28333 const field_align = try Type.fromInterned(field_ty).structFieldAlignmentSema(
28344 struct_type.fieldAlign(ip, field_index),28334 struct_type.fieldAlign(ip, field_index),
28345 struct_type.layout,28335 struct_type.layout,
28346 .sema,28336 pt,
28347 pt.zcu,
28348 pt.tid,
28349 );28337 );
28350 ptr_ty_data.flags.alignment = if (struct_ptr_ty_info.flags.alignment == .none)28338 ptr_ty_data.flags.alignment = if (struct_ptr_ty_info.flags.alignment == .none)
28351 field_align28339 field_align
...@@ -28477,7 +28465,7 @@ fn tupleFieldValByIndex(...@@ -28477,7 +28465,7 @@ fn tupleFieldValByIndex(
28477) CompileError!Air.Inst.Ref {28465) CompileError!Air.Inst.Ref {
28478 const pt = sema.pt;28466 const pt = sema.pt;
28479 const zcu = pt.zcu;28467 const zcu = pt.zcu;
28480 const field_ty = tuple_ty.structFieldType(field_index, zcu);28468 const field_ty = tuple_ty.fieldType(field_index, zcu);
2848128469
28482 if (tuple_ty.structFieldIsComptime(field_index, zcu))28470 if (tuple_ty.structFieldIsComptime(field_index, zcu))
28483 try tuple_ty.resolveStructFieldInits(pt);28471 try tuple_ty.resolveStructFieldInits(pt);
...@@ -28538,13 +28526,7 @@ fn unionFieldPtr(...@@ -28538,13 +28526,7 @@ fn unionFieldPtr(
28538 union_ptr_info.flags.alignment28526 union_ptr_info.flags.alignment
28539 else28527 else
28540 try union_ty.abiAlignmentSema(pt);28528 try union_ty.abiAlignmentSema(pt);
28541 const field_align = try Type.unionFieldNormalAlignmentAdvanced(28529 const field_align = try union_ty.fieldAlignmentSema(field_index, pt);
28542 union_obj,
28543 field_index,
28544 .sema,
28545 pt.zcu,
28546 pt.tid,
28547 );
28548 break :blk union_align.min(field_align);28530 break :blk union_align.min(field_align);
28549 } else union_ptr_info.flags.alignment,28531 } else union_ptr_info.flags.alignment,
28550 },28532 },
...@@ -28921,7 +28903,7 @@ fn tupleFieldPtr(...@@ -28921,7 +28903,7 @@ fn tupleFieldPtr(
28921 });28903 });
28922 }28904 }
2892328905
28924 const field_ty = tuple_ty.structFieldType(field_index, zcu);28906 const field_ty = tuple_ty.fieldType(field_index, zcu);
28925 const ptr_field_ty = try pt.ptrTypeSema(.{28907 const ptr_field_ty = try pt.ptrTypeSema(.{
28926 .child = field_ty.toIntern(),28908 .child = field_ty.toIntern(),
28927 .flags = .{28909 .flags = .{
...@@ -28979,7 +28961,7 @@ fn tupleField(...@@ -28979,7 +28961,7 @@ fn tupleField(
28979 });28961 });
28980 }28962 }
2898128963
28982 const field_ty = tuple_ty.structFieldType(field_index, zcu);28964 const field_ty = tuple_ty.fieldType(field_index, zcu);
2898328965
28984 if (tuple_ty.structFieldIsComptime(field_index, zcu))28966 if (tuple_ty.structFieldIsComptime(field_index, zcu))
28985 try tuple_ty.resolveStructFieldInits(pt);28967 try tuple_ty.resolveStructFieldInits(pt);
...@@ -30615,9 +30597,9 @@ pub fn coerceInMemoryAllowed(...@@ -30615,9 +30597,9 @@ pub fn coerceInMemoryAllowed(
30615 const field_count = dest_ty.structFieldCount(zcu);30597 const field_count = dest_ty.structFieldCount(zcu);
30616 for (0..field_count) |field_idx| {30598 for (0..field_count) |field_idx| {
30617 if (dest_ty.structFieldIsComptime(field_idx, zcu) != src_ty.structFieldIsComptime(field_idx, zcu)) break :tuple;30599 if (dest_ty.structFieldIsComptime(field_idx, zcu) != src_ty.structFieldIsComptime(field_idx, zcu)) break :tuple;
30618 if (dest_ty.structFieldAlign(field_idx, zcu) != src_ty.structFieldAlign(field_idx, zcu)) break :tuple;30600 if (dest_ty.fieldAlignment(field_idx, zcu) != src_ty.fieldAlignment(field_idx, zcu)) break :tuple;
30619 const dest_field_ty = dest_ty.structFieldType(field_idx, zcu);30601 const dest_field_ty = dest_ty.fieldType(field_idx, zcu);
30620 const src_field_ty = src_ty.structFieldType(field_idx, zcu);30602 const src_field_ty = src_ty.fieldType(field_idx, zcu);
30621 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src, null);30603 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src, null);
30622 if (field != .ok) break :tuple;30604 if (field != .ok) break :tuple;
30623 }30605 }
...@@ -35073,7 +35055,7 @@ fn resolvePeerTypesInner(...@@ -35073,7 +35055,7 @@ fn resolvePeerTypesInner(
35073 peer_field_val.* = null;35055 peer_field_val.* = null;
35074 continue;35056 continue;
35075 };35057 };
35076 peer_field_ty.* = ty.structFieldType(field_index, zcu);35058 peer_field_ty.* = ty.fieldType(field_index, zcu);
35077 peer_field_val.* = if (opt_val) |val| try val.fieldValue(pt, field_index) else null;35059 peer_field_val.* = if (opt_val) |val| try val.fieldValue(pt, field_index) else null;
35078 }35060 }
3507935061
...@@ -35095,7 +35077,7 @@ fn resolvePeerTypesInner(...@@ -35095,7 +35077,7 @@ fn resolvePeerTypesInner(
35095 // Already-resolved types won't be referenced by the error so it's fine35077 // Already-resolved types won't be referenced by the error so it's fine
35096 // to leave them undefined.35078 // to leave them undefined.
35097 const ty = opt_ty orelse continue;35079 const ty = opt_ty orelse continue;
35098 peer_field_ty.* = ty.structFieldType(field_index, zcu);35080 peer_field_ty.* = ty.fieldType(field_index, zcu);
35099 }35081 }
3510035082
35101 return .{ .field_error = .{35083 return .{ .field_error = .{
...@@ -35220,9 +35202,9 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {...@@ -35220,9 +35202,9 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
35220 .elem_ty = Type.noreturn,35202 .elem_ty = Type.noreturn,
35221 };35203 };
35222 if (!ty.isTuple(zcu)) return null;35204 if (!ty.isTuple(zcu)) return null;
35223 const elem_ty = ty.structFieldType(0, zcu);35205 const elem_ty = ty.fieldType(0, zcu);
35224 for (1..field_count) |i| {35206 for (1..field_count) |i| {
35225 if (!ty.structFieldType(i, zcu).eql(elem_ty, zcu)) {35207 if (!ty.fieldType(i, zcu).eql(elem_ty, zcu)) {
35226 return null;35208 return null;
35227 }35209 }
35228 }35210 }
...@@ -35309,12 +35291,10 @@ pub fn resolveStructAlignment(...@@ -35309,12 +35291,10 @@ pub fn resolveStructAlignment(
35309 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35291 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
35310 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt))35292 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt))
35311 continue;35293 continue;
35312 const field_align = try field_ty.structFieldAlignmentAdvanced(35294 const field_align = try field_ty.structFieldAlignmentSema(
35313 struct_type.fieldAlign(ip, i),35295 struct_type.fieldAlign(ip, i),
35314 struct_type.layout,35296 struct_type.layout,
35315 .sema,35297 pt,
35316 pt.zcu,
35317 pt.tid,
35318 );35298 );
35319 alignment = alignment.maxStrict(field_align);35299 alignment = alignment.maxStrict(field_align);
35320 }35300 }
...@@ -35375,12 +35355,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35375,12 +35355,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
35375 },35355 },
35376 else => return err,35356 else => return err,
35377 };35357 };
35378 field_align.* = try field_ty.structFieldAlignmentAdvanced(35358 field_align.* = try field_ty.structFieldAlignmentSema(
35379 struct_type.fieldAlign(ip, i),35359 struct_type.fieldAlign(ip, i),
35380 struct_type.layout,35360 struct_type.layout,
35381 .sema,35361 pt,
35382 pt.zcu,
35383 pt.tid,
35384 );35362 );
35385 big_align = big_align.maxStrict(field_align.*);35363 big_align = big_align.maxStrict(field_align.*);
35386 }35364 }
src/Sema/bitcast.zig+3-3
...@@ -542,7 +542,7 @@ const PackValueBits = struct {...@@ -542,7 +542,7 @@ const PackValueBits = struct {
542 while (it.next()) |field_idx| {542 while (it.next()) |field_idx| {
543 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8;543 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8;
544 try pack.padding(want_bit_off - cur_bit_off);544 try pack.padding(want_bit_off - cur_bit_off);
545 const field_ty = ty.structFieldType(field_idx, zcu);545 const field_ty = ty.fieldType(field_idx, zcu);
546 elems[field_idx] = (try pack.get(field_ty)).toIntern();546 elems[field_idx] = (try pack.get(field_ty)).toIntern();
547 cur_bit_off = want_bit_off + field_ty.bitSize(zcu);547 cur_bit_off = want_bit_off + field_ty.bitSize(zcu);
548 }548 }
...@@ -552,7 +552,7 @@ const PackValueBits = struct {...@@ -552,7 +552,7 @@ const PackValueBits = struct {
552 var cur_bit_off: u64 = ty.bitSize(zcu);552 var cur_bit_off: u64 = ty.bitSize(zcu);
553 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip);553 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip);
554 while (it.next()) |field_idx| {554 while (it.next()) |field_idx| {
555 const field_ty = ty.structFieldType(field_idx, zcu);555 const field_ty = ty.fieldType(field_idx, zcu);
556 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu);556 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu);
557 try pack.padding(cur_bit_off - want_bit_off);557 try pack.padding(cur_bit_off - want_bit_off);
558 elems[field_idx] = (try pack.get(field_ty)).toIntern();558 elems[field_idx] = (try pack.get(field_ty)).toIntern();
...@@ -578,7 +578,7 @@ const PackValueBits = struct {...@@ -578,7 +578,7 @@ const PackValueBits = struct {
578 // This is identical between LE and BE targets.578 // This is identical between LE and BE targets.
579 const elems = try arena.alloc(InternPool.Index, ty.structFieldCount(zcu));579 const elems = try arena.alloc(InternPool.Index, ty.structFieldCount(zcu));
580 for (elems, 0..) |*elem, i| {580 for (elems, 0..) |*elem, i| {
581 const field_ty = ty.structFieldType(i, zcu);581 const field_ty = ty.fieldType(i, zcu);
582 elem.* = (try pack.get(field_ty)).toIntern();582 elem.* = (try pack.get(field_ty)).toIntern();
583 }583 }
584 return Value.fromInterned(try pt.intern(.{ .aggregate = .{584 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
src/Sema/comptime_ptr_access.zig+2-2
...@@ -451,7 +451,7 @@ fn loadComptimePtrInner(...@@ -451,7 +451,7 @@ fn loadComptimePtrInner(
451 .@"packed" => break, // let the bitcast logic handle this451 .@"packed" => break, // let the bitcast logic handle this
452 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {452 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
453 const start_off = cur_ty.structFieldOffset(field_idx, zcu);453 const start_off = cur_ty.structFieldOffset(field_idx, zcu);
454 const end_off = start_off + try cur_ty.structFieldType(field_idx, zcu).abiSizeSema(pt);454 const end_off = start_off + try cur_ty.fieldType(field_idx, zcu).abiSizeSema(pt);
455 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {455 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
456 cur_val = try cur_val.getElem(sema.pt, field_idx);456 cur_val = try cur_val.getElem(sema.pt, field_idx);
457 cur_offset -= start_off;457 cur_offset -= start_off;
...@@ -873,7 +873,7 @@ fn prepareComptimePtrStore(...@@ -873,7 +873,7 @@ fn prepareComptimePtrStore(
873 .@"packed" => break, // let the bitcast logic handle this873 .@"packed" => break, // let the bitcast logic handle this
874 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {874 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
875 const start_off = cur_ty.structFieldOffset(field_idx, zcu);875 const start_off = cur_ty.structFieldOffset(field_idx, zcu);
876 const end_off = start_off + try cur_ty.structFieldType(field_idx, zcu).abiSizeSema(pt);876 const end_off = start_off + try cur_ty.fieldType(field_idx, zcu).abiSizeSema(pt);
877 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {877 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
878 cur_val = try cur_val.elem(pt, sema.arena, field_idx);878 cur_val = try cur_val.elem(pt, sema.arena, field_idx);
879 cur_offset -= start_off;879 cur_offset -= start_off;
src/Type.zig+83-44
...@@ -3191,8 +3191,8 @@ pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {...@@ -3191,8 +3191,8 @@ pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {
3191 };3191 };
3192}3192}
31933193
3194/// Supports structs and unions.3194/// Returns the field type. Supports structs and unions.
3195pub fn structFieldType(ty: Type, index: usize, zcu: *const Zcu) Type {3195pub fn fieldType(ty: Type, index: usize, zcu: *const Zcu) Type {
3196 const ip = &zcu.intern_pool;3196 const ip = &zcu.intern_pool;
3197 return switch (ip.indexToKey(ty.toIntern())) {3197 return switch (ip.indexToKey(ty.toIntern())) {
3198 .struct_type => Type.fromInterned(ip.loadStructType(ty.toIntern()).field_types.get(ip)[index]),3198 .struct_type => Type.fromInterned(ip.loadStructType(ty.toIntern()).field_types.get(ip)[index]),
...@@ -3205,17 +3205,26 @@ pub fn structFieldType(ty: Type, index: usize, zcu: *const Zcu) Type {...@@ -3205,17 +3205,26 @@ pub fn structFieldType(ty: Type, index: usize, zcu: *const Zcu) Type {
3205 };3205 };
3206}3206}
32073207
3208pub fn structFieldAlign(ty: Type, index: usize, zcu: *Zcu) Alignment {3208pub fn fieldAlignment(ty: Type, index: usize, zcu: *Zcu) Alignment {
3209 return ty.structFieldAlignAdvanced(index, .normal, zcu, {}) catch unreachable;3209 return ty.fieldAlignmentInner(index, .normal, zcu, {}) catch unreachable;
3210}
3211
3212pub fn fieldAlignmentSema(ty: Type, index: usize, pt: Zcu.PerThread) SemaError!Alignment {
3213 return try ty.fieldAlignmentInner(index, .sema, pt.zcu, pt.tid);
3210}3214}
32113215
3212pub fn structFieldAlignAdvanced(3216/// Returns the field alignment. Supports structs and unions.
3217/// If `strat` is `.sema`, may perform type resolution.
3218/// Asserts the layout is not packed.
3219///
3220/// Provide the struct field as the `ty`.
3221pub fn fieldAlignmentInner(
3213 ty: Type,3222 ty: Type,
3214 index: usize,3223 index: usize,
3215 comptime strat: ResolveStrat,3224 comptime strat: ResolveStrat,
3216 zcu: *Zcu,3225 zcu: *Zcu,
3217 tid: strat.Tid(),3226 tid: strat.Tid(),
3218) !Alignment {3227) SemaError!Alignment {
3219 const ip = &zcu.intern_pool;3228 const ip = &zcu.intern_pool;
3220 switch (ip.indexToKey(ty.toIntern())) {3229 switch (ip.indexToKey(ty.toIntern())) {
3221 .struct_type => {3230 .struct_type => {
...@@ -3223,13 +3232,7 @@ pub fn structFieldAlignAdvanced(...@@ -3223,13 +3232,7 @@ pub fn structFieldAlignAdvanced(
3223 assert(struct_type.layout != .@"packed");3232 assert(struct_type.layout != .@"packed");
3224 const explicit_align = struct_type.fieldAlign(ip, index);3233 const explicit_align = struct_type.fieldAlign(ip, index);
3225 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);3234 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);
3226 return field_ty.structFieldAlignmentAdvanced(3235 return field_ty.structFieldAlignmentInner(explicit_align, struct_type.layout, strat, zcu, tid);
3227 explicit_align,
3228 struct_type.layout,
3229 strat,
3230 zcu,
3231 tid,
3232 );
3233 },3236 },
3234 .anon_struct_type => |anon_struct| {3237 .anon_struct_type => |anon_struct| {
3235 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentInner(3238 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentInner(
...@@ -3240,28 +3243,62 @@ pub fn structFieldAlignAdvanced(...@@ -3240,28 +3243,62 @@ pub fn structFieldAlignAdvanced(
3240 },3243 },
3241 .union_type => {3244 .union_type => {
3242 const union_obj = ip.loadUnionType(ty.toIntern());3245 const union_obj = ip.loadUnionType(ty.toIntern());
3243 return unionFieldNormalAlignmentAdvanced(3246 const layout = union_obj.flagsUnordered(ip).layout;
3244 union_obj,3247 assert(layout != .@"packed");
3245 @intCast(index),3248 const explicit_align = union_obj.fieldAlign(ip, index);
3246 strat,3249 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[index]);
3247 zcu,3250 return field_ty.unionFieldAlignmentInner(explicit_align, layout, strat, zcu, tid);
3248 tid,
3249 );
3250 },3251 },
3251 else => unreachable,3252 else => unreachable,
3252 }3253 }
3253}3254}
32543255
3255/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.3256/// Returns the alignment of a non-packed struct field. Assert the layout is not packed.
3256/// If `strat` is `.sema`, may perform type resolution.3257///
3257pub fn structFieldAlignmentAdvanced(3258/// Asserts that all resolution needed was done.
3259pub fn structFieldAlignment(
3258 field_ty: Type,3260 field_ty: Type,
3259 explicit_alignment: InternPool.Alignment,3261 explicit_alignment: InternPool.Alignment,
3260 layout: std.builtin.Type.ContainerLayout,3262 layout: std.builtin.Type.ContainerLayout,
3263 zcu: *Zcu,
3264) Alignment {
3265 return field_ty.structFieldAlignmentInner(
3266 explicit_alignment,
3267 layout,
3268 .normal,
3269 zcu,
3270 {},
3271 ) catch unreachable;
3272}
3273
3274/// Returns the alignment of a non-packed struct field. Assert the layout is not packed.
3275/// May do type resolution when needed.
3276/// Asserts that all resolution needed was done.
3277pub fn structFieldAlignmentSema(
3278 field_ty: Type,
3279 explicit_alignment: InternPool.Alignment,
3280 layout: std.builtin.Type.ContainerLayout,
3281 pt: Zcu.PerThread,
3282) SemaError!Alignment {
3283 return try field_ty.structFieldAlignmentInner(
3284 explicit_alignment,
3285 layout,
3286 .sema,
3287 pt.zcu,
3288 pt.tid,
3289 );
3290}
3291
3292/// Returns the alignment of a non-packed struct field. Asserts the layout is not packed.
3293/// If `strat` is `.sema`, may perform type resolution.
3294pub fn structFieldAlignmentInner(
3295 field_ty: Type,
3296 explicit_alignment: Alignment,
3297 layout: std.builtin.Type.ContainerLayout,
3261 comptime strat: Type.ResolveStrat,3298 comptime strat: Type.ResolveStrat,
3262 zcu: *Zcu,3299 zcu: *Zcu,
3263 tid: strat.Tid(),3300 tid: strat.Tid(),
3264) Zcu.SemaError!InternPool.Alignment {3301) SemaError!Alignment {
3265 assert(layout != .@"packed");3302 assert(layout != .@"packed");
3266 if (explicit_alignment != .none) return explicit_alignment;3303 if (explicit_alignment != .none) return explicit_alignment;
3267 const ty_abi_align = (try field_ty.abiAlignmentInner(3304 const ty_abi_align = (try field_ty.abiAlignmentInner(
...@@ -3281,29 +3318,31 @@ pub fn structFieldAlignmentAdvanced(...@@ -3281,29 +3318,31 @@ pub fn structFieldAlignmentAdvanced(
3281 return ty_abi_align;3318 return ty_abi_align;
3282}3319}
32833320
3284/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.3321pub fn unionFieldAlignmentSema(
3285pub fn unionFieldNormalAlignment(3322 field_ty: Type,
3286 loaded_union: InternPool.LoadedUnionType,3323 explicit_alignment: Alignment,
3287 field_index: u32,3324 layout: std.builtin.Type.ContainerLayout,
3288 zcu: *Zcu,3325 pt: Zcu.PerThread,
3289) InternPool.Alignment {3326) SemaError!Alignment {
3290 return unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal, zcu, {}) catch unreachable;3327 return field_ty.unionFieldAlignmentInner(
3328 explicit_alignment,
3329 layout,
3330 .sema,
3331 pt.zcu,
3332 pt.tid,
3333 );
3291}3334}
32923335
3293/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.3336pub fn unionFieldAlignmentInner(
3294/// If `strat` is `.sema`, may perform type resolution.3337 field_ty: Type,
3295pub fn unionFieldNormalAlignmentAdvanced(3338 explicit_alignment: Alignment,
3296 loaded_union: InternPool.LoadedUnionType,3339 layout: std.builtin.Type.ContainerLayout,
3297 field_index: u32,
3298 comptime strat: Type.ResolveStrat,3340 comptime strat: Type.ResolveStrat,
3299 zcu: *Zcu,3341 zcu: *Zcu,
3300 tid: strat.Tid(),3342 tid: strat.Tid(),
3301) Zcu.SemaError!InternPool.Alignment {3343) SemaError!Alignment {
3302 const ip = &zcu.intern_pool;3344 assert(layout != .@"packed");
3303 assert(loaded_union.flagsUnordered(ip).layout != .@"packed");3345 if (explicit_alignment != .none) return explicit_alignment;
3304 const field_align = loaded_union.fieldAlign(ip, field_index);
3305 if (field_align != .none) return field_align;
3306 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
3307 if (field_ty.isNoReturn(zcu)) return .none;3346 if (field_ty.isNoReturn(zcu)) return .none;
3308 return (try field_ty.abiAlignmentInner(strat.toLazy(), zcu, tid)).scalar;3347 return (try field_ty.abiAlignmentInner(strat.toLazy(), zcu, tid)).scalar;
3309}3348}
...@@ -3608,12 +3647,12 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:...@@ -3608,12 +3647,12 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
36083647
3609 const zcu = pt.zcu;3648 const zcu = pt.zcu;
3610 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);3649 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
3611 const field_ty = struct_ty.structFieldType(field_idx, zcu);3650 const field_ty = struct_ty.fieldType(field_idx, zcu);
36123651
3613 var bit_offset: u16 = 0;3652 var bit_offset: u16 = 0;
3614 var running_bits: u16 = 0;3653 var running_bits: u16 = 0;
3615 for (0..struct_ty.structFieldCount(zcu)) |i| {3654 for (0..struct_ty.structFieldCount(zcu)) |i| {
3616 const f_ty = struct_ty.structFieldType(i, zcu);3655 const f_ty = struct_ty.fieldType(i, zcu);
3617 if (i == field_idx) {3656 if (i == field_idx) {
3618 bit_offset = running_bits;3657 bit_offset = running_bits;
3619 }3658 }
src/Value.zig+10-10
...@@ -1414,7 +1414,7 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {...@@ -1414,7 +1414,7 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
1414 const zcu = pt.zcu;1414 const zcu = pt.zcu;
1415 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {1415 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1416 .undef => |ty| Value.fromInterned(try pt.intern(.{1416 .undef => |ty| Value.fromInterned(try pt.intern(.{
1417 .undef = Type.fromInterned(ty).structFieldType(index, zcu).toIntern(),1417 .undef = Type.fromInterned(ty).fieldType(index, zcu).toIntern(),
1418 })),1418 })),
1419 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {1419 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {
1420 .bytes => |bytes| try pt.intern(.{ .int = .{1420 .bytes => |bytes| try pt.intern(.{ .int = .{
...@@ -3810,9 +3810,9 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {...@@ -3810,9 +3810,9 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
3810 // `field_align` may be `.none` to represent the natural alignment of `field_ty`, but is not necessarily.3810 // `field_align` may be `.none` to represent the natural alignment of `field_ty`, but is not necessarily.
3811 const field_ty: Type, const field_align: InternPool.Alignment = switch (aggregate_ty.zigTypeTag(zcu)) {3811 const field_ty: Type, const field_align: InternPool.Alignment = switch (aggregate_ty.zigTypeTag(zcu)) {
3812 .Struct => field: {3812 .Struct => field: {
3813 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);3813 const field_ty = aggregate_ty.fieldType(field_idx, zcu);
3814 switch (aggregate_ty.containerLayout(zcu)) {3814 switch (aggregate_ty.containerLayout(zcu)) {
3815 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), .sema, zcu, pt.tid) },3815 .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) },
3816 .@"extern" => {3816 .@"extern" => {
3817 // Well-defined layout, so just offset the pointer appropriately.3817 // Well-defined layout, so just offset the pointer appropriately.
3818 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);3818 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);
...@@ -3863,7 +3863,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {...@@ -3863,7 +3863,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
3863 const union_obj = zcu.typeToUnion(aggregate_ty).?;3863 const union_obj = zcu.typeToUnion(aggregate_ty).?;
3864 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);3864 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);
3865 switch (aggregate_ty.containerLayout(zcu)) {3865 switch (aggregate_ty.containerLayout(zcu)) {
3866 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), .sema, zcu, pt.tid) },3866 .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) },
3867 .@"extern" => {3867 .@"extern" => {
3868 // Point to the same address.3868 // Point to the same address.
3869 const result_ty = try pt.ptrTypeSema(info: {3869 const result_ty = try pt.ptrTypeSema(info: {
...@@ -4198,14 +4198,14 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -4198,14 +4198,14 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
4198 const base_ptr_ty = base_ptr.typeOf(zcu);4198 const base_ptr_ty = base_ptr.typeOf(zcu);
4199 const agg_ty = base_ptr_ty.childType(zcu);4199 const agg_ty = base_ptr_ty.childType(zcu);
4200 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {4200 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {
4201 .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(4201 .Struct => .{ agg_ty.fieldType(field.index, zcu), try agg_ty.fieldAlignmentInner(
4202 @intCast(field.index),4202 field.index,
4203 if (have_sema) .sema else .normal,4203 if (have_sema) .sema else .normal,
4204 pt.zcu,4204 pt.zcu,
4205 if (have_sema) pt.tid else {},4205 if (have_sema) pt.tid else {},
4206 ) },4206 ) },
4207 .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(4207 .Union => .{ agg_ty.unionFieldTypeByIndex(field.index, zcu), try agg_ty.fieldAlignmentInner(
4208 @intCast(field.index),4208 field.index,
4209 if (have_sema) .sema else .normal,4209 if (have_sema) .sema else .normal,
4210 pt.zcu,4210 pt.zcu,
4211 if (have_sema) pt.tid else {},4211 if (have_sema) pt.tid else {},
...@@ -4344,7 +4344,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -4344,7 +4344,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
4344 .Struct => switch (cur_ty.containerLayout(zcu)) {4344 .Struct => switch (cur_ty.containerLayout(zcu)) {
4345 .auto, .@"packed" => break,4345 .auto, .@"packed" => break,
4346 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {4346 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
4347 const field_ty = cur_ty.structFieldType(field_idx, zcu);4347 const field_ty = cur_ty.fieldType(field_idx, zcu);
4348 const start_off = cur_ty.structFieldOffset(field_idx, zcu);4348 const start_off = cur_ty.structFieldOffset(field_idx, zcu);
4349 const end_off = start_off + field_ty.abiSize(zcu);4349 const end_off = start_off + field_ty.abiSize(zcu);
4350 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {4350 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
...@@ -4401,7 +4401,7 @@ pub fn resolveLazy(...@@ -4401,7 +4401,7 @@ pub fn resolveLazy(
4401 .u64, .i64, .big_int => return val,4401 .u64, .i64, .big_int => return val,
4402 .lazy_align, .lazy_size => return pt.intValue(4402 .lazy_align, .lazy_size => return pt.intValue(
4403 Type.fromInterned(int.ty),4403 Type.fromInterned(int.ty),
4404 (try val.getUnsignedIntInner(.sema, pt.zcu, pt.tid)).?,4404 try val.toUnsignedIntSema(pt),
4405 ),4405 ),
4406 },4406 },
4407 .slice => |slice| {4407 .slice => |slice| {
src/Zcu/PerThread.zig-32
...@@ -3040,38 +3040,6 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 {...@@ -3040,38 +3040,6 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 {
3040 }3040 }
3041}3041}
30423042
3043/// Returns 0 if the union is represented with 0 bits at runtime.
3044pub fn unionAbiAlignment(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) InternPool.Alignment {
3045 const zcu = pt.zcu;
3046 const ip = &zcu.intern_pool;
3047 const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag();
3048 var max_align: InternPool.Alignment = .none;
3049 if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(zcu);
3050 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
3051 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
3052
3053 const field_align = zcu.unionFieldNormalAlignment(loaded_union, @intCast(field_index));
3054 max_align = max_align.max(field_align);
3055 }
3056 return max_align;
3057}
3058
3059/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
3060pub fn structFieldAlignment(
3061 pt: Zcu.PerThread,
3062 explicit_alignment: InternPool.Alignment,
3063 field_ty: Type,
3064 layout: std.builtin.Type.ContainerLayout,
3065) InternPool.Alignment {
3066 return field_ty.structFieldAlignmentAdvanced(
3067 explicit_alignment,
3068 layout,
3069 .normal,
3070 pt.zcu,
3071 {},
3072 ) catch unreachable;
3073}
3074
3075/// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets3043/// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets
3076/// into the packed struct InternPool data rather than computing this on the3044/// into the packed struct InternPool data rather than computing this on the
3077/// fly, however it was found to perform worse when measured on real world3045/// fly, however it was found to perform worse when measured on real world
src/arch/aarch64/CodeGen.zig+3-3
...@@ -4144,7 +4144,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4144,7 +4144,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
4144 const zcu = pt.zcu;4144 const zcu = pt.zcu;
4145 const mcv = try self.resolveInst(operand);4145 const mcv = try self.resolveInst(operand);
4146 const struct_ty = self.typeOf(operand);4146 const struct_ty = self.typeOf(operand);
4147 const struct_field_ty = struct_ty.structFieldType(index, zcu);4147 const struct_field_ty = struct_ty.fieldType(index, zcu);
4148 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, zcu)));4148 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, zcu)));
41494149
4150 switch (mcv) {4150 switch (mcv) {
...@@ -5473,10 +5473,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5473,10 +5473,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5473 const reg_lock = self.register_manager.lockReg(rwo.reg);5473 const reg_lock = self.register_manager.lockReg(rwo.reg);
5474 defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg);5474 defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg);
54755475
5476 const wrapped_ty = ty.structFieldType(0, zcu);5476 const wrapped_ty = ty.fieldType(0, zcu);
5477 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });5477 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });
54785478
5479 const overflow_bit_ty = ty.structFieldType(1, zcu);5479 const overflow_bit_ty = ty.fieldType(1, zcu);
5480 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, zcu)));5480 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, zcu)));
5481 const raw_cond_reg = try self.register_manager.allocReg(null, gp);5481 const raw_cond_reg = try self.register_manager.allocReg(null, gp);
5482 const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty);5482 const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty);
src/arch/aarch64/abi.zig+2-2
...@@ -95,7 +95,7 @@ fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u8 {...@@ -95,7 +95,7 @@ fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u8 {
95 var count: u8 = 0;95 var count: u8 = 0;
96 var i: u32 = 0;96 var i: u32 = 0;
97 while (i < fields_len) : (i += 1) {97 while (i < fields_len) : (i += 1) {
98 const field_ty = ty.structFieldType(i, zcu);98 const field_ty = ty.fieldType(i, zcu);
99 const field_count = countFloats(field_ty, zcu, maybe_float_bits);99 const field_count = countFloats(field_ty, zcu, maybe_float_bits);
100 if (field_count == invalid) return invalid;100 if (field_count == invalid) return invalid;
101 count += field_count;101 count += field_count;
...@@ -130,7 +130,7 @@ pub fn getFloatArrayType(ty: Type, zcu: *Zcu) ?Type {...@@ -130,7 +130,7 @@ pub fn getFloatArrayType(ty: Type, zcu: *Zcu) ?Type {
130 const fields_len = ty.structFieldCount(zcu);130 const fields_len = ty.structFieldCount(zcu);
131 var i: u32 = 0;131 var i: u32 = 0;
132 while (i < fields_len) : (i += 1) {132 while (i < fields_len) : (i += 1) {
133 const field_ty = ty.structFieldType(i, zcu);133 const field_ty = ty.fieldType(i, zcu);
134 if (getFloatArrayType(field_ty, zcu)) |some| return some;134 if (getFloatArrayType(field_ty, zcu)) |some| return some;
135 }135 }
136 return null;136 return null;
src/arch/arm/CodeGen.zig+3-3
...@@ -2926,7 +2926,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2926,7 +2926,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2926 const mcv = try self.resolveInst(operand);2926 const mcv = try self.resolveInst(operand);
2927 const struct_ty = self.typeOf(operand);2927 const struct_ty = self.typeOf(operand);
2928 const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, zcu));2928 const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, zcu));
2929 const struct_field_ty = struct_ty.structFieldType(index, zcu);2929 const struct_field_ty = struct_ty.fieldType(index, zcu);
29302930
2931 switch (mcv) {2931 switch (mcv) {
2932 .dead, .unreach => unreachable,2932 .dead, .unreach => unreachable,
...@@ -5434,10 +5434,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5434,10 +5434,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5434 const reg_lock = self.register_manager.lockReg(reg);5434 const reg_lock = self.register_manager.lockReg(reg);
5435 defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg);5435 defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg);
54365436
5437 const wrapped_ty = ty.structFieldType(0, zcu);5437 const wrapped_ty = ty.fieldType(0, zcu);
5438 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg });5438 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg });
54395439
5440 const overflow_bit_ty = ty.structFieldType(1, zcu);5440 const overflow_bit_ty = ty.fieldType(1, zcu);
5441 const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, zcu));5441 const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, zcu));
5442 const cond_reg = try self.register_manager.allocReg(null, gp);5442 const cond_reg = try self.register_manager.allocReg(null, gp);
54435443
src/arch/arm/abi.zig+4-4
...@@ -44,8 +44,8 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -44,8 +44,8 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
44 const fields = ty.structFieldCount(zcu);44 const fields = ty.structFieldCount(zcu);
45 var i: u32 = 0;45 var i: u32 = 0;
46 while (i < fields) : (i += 1) {46 while (i < fields) : (i += 1) {
47 const field_ty = ty.structFieldType(i, zcu);47 const field_ty = ty.fieldType(i, zcu);
48 const field_alignment = ty.structFieldAlign(i, zcu);48 const field_alignment = ty.fieldAlignment(i, zcu);
49 const field_size = field_ty.bitSize(zcu);49 const field_size = field_ty.bitSize(zcu);
50 if (field_size > 32 or field_alignment.compare(.gt, .@"32")) {50 if (field_size > 32 or field_alignment.compare(.gt, .@"32")) {
51 return Class.arrSize(bit_size, 64);51 return Class.arrSize(bit_size, 64);
...@@ -66,7 +66,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -66,7 +66,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
6666
67 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {67 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {
68 if (Type.fromInterned(field_ty).bitSize(zcu) > 32 or68 if (Type.fromInterned(field_ty).bitSize(zcu) > 32 or
69 Type.unionFieldNormalAlignment(union_obj, @intCast(field_index), zcu).compare(.gt, .@"32"))69 ty.fieldAlignment(field_index, zcu).compare(.gt, .@"32"))
70 {70 {
71 return Class.arrSize(bit_size, 64);71 return Class.arrSize(bit_size, 64);
72 }72 }
...@@ -141,7 +141,7 @@ fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u32 {...@@ -141,7 +141,7 @@ fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u32 {
141 var count: u32 = 0;141 var count: u32 = 0;
142 var i: u32 = 0;142 var i: u32 = 0;
143 while (i < fields_len) : (i += 1) {143 while (i < fields_len) : (i += 1) {
144 const field_ty = ty.structFieldType(i, zcu);144 const field_ty = ty.fieldType(i, zcu);
145 const field_count = countFloats(field_ty, zcu, maybe_float_bits);145 const field_count = countFloats(field_ty, zcu, maybe_float_bits);
146 if (field_count == invalid) return invalid;146 if (field_count == invalid) return invalid;
147 count += field_count;147 count += field_count;
src/arch/riscv64/CodeGen.zig+3-3
...@@ -4576,7 +4576,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {...@@ -4576,7 +4576,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
4576 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {4576 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
4577 const src_mcv = try func.resolveInst(operand);4577 const src_mcv = try func.resolveInst(operand);
4578 const struct_ty = func.typeOf(operand);4578 const struct_ty = func.typeOf(operand);
4579 const field_ty = struct_ty.structFieldType(index, zcu);4579 const field_ty = struct_ty.fieldType(index, zcu);
4580 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;4580 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
45814581
4582 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {4582 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {
...@@ -7882,7 +7882,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {...@@ -7882,7 +7882,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
7882 const elem_i: u32 = @intCast(elem_i_usize);7882 const elem_i: u32 = @intCast(elem_i_usize);
7883 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;7883 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
78847884
7885 const elem_ty = result_ty.structFieldType(elem_i, zcu);7885 const elem_ty = result_ty.fieldType(elem_i, zcu);
7886 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));7886 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));
7887 if (elem_bit_size > 64) {7887 if (elem_bit_size > 64) {
7888 return func.fail(7888 return func.fail(
...@@ -7916,7 +7916,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {...@@ -7916,7 +7916,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
7916 } else for (elements, 0..) |elem, elem_i| {7916 } else for (elements, 0..) |elem, elem_i| {
7917 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;7917 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
79187918
7919 const elem_ty = result_ty.structFieldType(elem_i, zcu);7919 const elem_ty = result_ty.fieldType(elem_i, zcu);
7920 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));7920 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));
7921 const elem_mcv = try func.resolveInst(elem);7921 const elem_mcv = try func.resolveInst(elem);
7922 try func.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv);7922 try func.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv);
src/arch/riscv64/abi.zig+1-1
...@@ -26,7 +26,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {...@@ -26,7 +26,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {
26 var any_fp = false;26 var any_fp = false;
27 var field_count: usize = 0;27 var field_count: usize = 0;
28 for (0..ty.structFieldCount(zcu)) |field_index| {28 for (0..ty.structFieldCount(zcu)) |field_index| {
29 const field_ty = ty.structFieldType(field_index, zcu);29 const field_ty = ty.fieldType(field_index, zcu);
30 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;30 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
31 if (field_ty.isRuntimeFloat())31 if (field_ty.isRuntimeFloat())
32 any_fp = true32 any_fp = true
src/arch/sparc64/CodeGen.zig+2-2
...@@ -3980,10 +3980,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3980,10 +3980,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3980 const reg_lock = self.register_manager.lockReg(rwo.reg);3980 const reg_lock = self.register_manager.lockReg(rwo.reg);
3981 defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg);3981 defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg);
39823982
3983 const wrapped_ty = ty.structFieldType(0, zcu);3983 const wrapped_ty = ty.fieldType(0, zcu);
3984 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });3984 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });
39853985
3986 const overflow_bit_ty = ty.structFieldType(1, zcu);3986 const overflow_bit_ty = ty.fieldType(1, zcu);
3987 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, zcu)));3987 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, zcu)));
3988 const cond_reg = try self.register_manager.allocReg(null, gp);3988 const cond_reg = try self.register_manager.allocReg(null, gp);
39893989
src/arch/wasm/CodeGen.zig+2-2
...@@ -3954,7 +3954,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3954,7 +3954,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3954 const struct_ty = func.typeOf(struct_field.struct_operand);3954 const struct_ty = func.typeOf(struct_field.struct_operand);
3955 const operand = try func.resolveInst(struct_field.struct_operand);3955 const operand = try func.resolveInst(struct_field.struct_operand);
3956 const field_index = struct_field.field_index;3956 const field_index = struct_field.field_index;
3957 const field_ty = struct_ty.structFieldType(field_index, zcu);3957 const field_ty = struct_ty.fieldType(field_index, zcu);
3958 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return func.finishAir(inst, .none, &.{struct_field.struct_operand});3958 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return func.finishAir(inst, .none, &.{struct_field.struct_operand});
39593959
3960 const result: WValue = switch (struct_ty.containerLayout(zcu)) {3960 const result: WValue = switch (struct_ty.containerLayout(zcu)) {
...@@ -5378,7 +5378,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5378,7 +5378,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5378 for (elements, 0..) |elem, elem_index| {5378 for (elements, 0..) |elem, elem_index| {
5379 if (try result_ty.structFieldValueComptime(pt, elem_index) != null) continue;5379 if (try result_ty.structFieldValueComptime(pt, elem_index) != null) continue;
53805380
5381 const elem_ty = result_ty.structFieldType(elem_index, zcu);5381 const elem_ty = result_ty.fieldType(elem_index, zcu);
5382 const field_offset = result_ty.structFieldOffset(elem_index, zcu);5382 const field_offset = result_ty.structFieldOffset(elem_index, zcu);
5383 _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify);5383 _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify);
5384 prev_field_offset = field_offset;5384 prev_field_offset = field_offset;
src/arch/wasm/abi.zig+1-1
...@@ -108,7 +108,7 @@ pub fn scalarType(ty: Type, zcu: *Zcu) Type {...@@ -108,7 +108,7 @@ pub fn scalarType(ty: Type, zcu: *Zcu) Type {
108 return scalarType(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), zcu);108 return scalarType(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), zcu);
109 } else {109 } else {
110 assert(ty.structFieldCount(zcu) == 1);110 assert(ty.structFieldCount(zcu) == 1);
111 return scalarType(ty.structFieldType(0, zcu), zcu);111 return scalarType(ty.fieldType(0, zcu), zcu);
112 }112 }
113 },113 },
114 .Union => {114 .Union => {
src/arch/x86_64/CodeGen.zig+15-15
...@@ -4352,14 +4352,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4352,14 +4352,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4352 try self.genSetMem(4352 try self.genSetMem(
4353 .{ .frame = frame_index },4353 .{ .frame = frame_index },
4354 @intCast(tuple_ty.structFieldOffset(1, zcu)),4354 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4355 tuple_ty.structFieldType(1, zcu),4355 tuple_ty.fieldType(1, zcu),
4356 .{ .eflags = cc },4356 .{ .eflags = cc },
4357 .{},4357 .{},
4358 );4358 );
4359 try self.genSetMem(4359 try self.genSetMem(
4360 .{ .frame = frame_index },4360 .{ .frame = frame_index },
4361 @intCast(tuple_ty.structFieldOffset(0, zcu)),4361 @intCast(tuple_ty.structFieldOffset(0, zcu)),
4362 tuple_ty.structFieldType(0, zcu),4362 tuple_ty.fieldType(0, zcu),
4363 partial_mcv,4363 partial_mcv,
4364 .{},4364 .{},
4365 );4365 );
...@@ -4392,7 +4392,7 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -4392,7 +4392,7 @@ fn genSetFrameTruncatedOverflowCompare(
4392 };4392 };
4393 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);4393 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
43944394
4395 const ty = tuple_ty.structFieldType(0, zcu);4395 const ty = tuple_ty.fieldType(0, zcu);
4396 const int_info = ty.intInfo(zcu);4396 const int_info = ty.intInfo(zcu);
43974397
4398 const hi_bits = (int_info.bits - 1) % 64 + 1;4398 const hi_bits = (int_info.bits - 1) % 64 + 1;
...@@ -4450,7 +4450,7 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -4450,7 +4450,7 @@ fn genSetFrameTruncatedOverflowCompare(
4450 try self.genSetMem(4450 try self.genSetMem(
4451 .{ .frame = frame_index },4451 .{ .frame = frame_index },
4452 @intCast(tuple_ty.structFieldOffset(1, zcu)),4452 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4453 tuple_ty.structFieldType(1, zcu),4453 tuple_ty.fieldType(1, zcu),
4454 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },4454 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },
4455 .{},4455 .{},
4456 );4456 );
...@@ -4637,7 +4637,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4637,7 +4637,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4637 try self.genSetMem(4637 try self.genSetMem(
4638 .{ .frame = dst_mcv.load_frame.index },4638 .{ .frame = dst_mcv.load_frame.index },
4639 @intCast(tuple_ty.structFieldOffset(0, zcu)),4639 @intCast(tuple_ty.structFieldOffset(0, zcu)),
4640 tuple_ty.structFieldType(0, zcu),4640 tuple_ty.fieldType(0, zcu),
4641 result,4641 result,
4642 .{},4642 .{},
4643 );4643 );
...@@ -4649,7 +4649,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4649,7 +4649,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4649 try self.genSetMem(4649 try self.genSetMem(
4650 .{ .frame = dst_mcv.load_frame.index },4650 .{ .frame = dst_mcv.load_frame.index },
4651 @intCast(tuple_ty.structFieldOffset(1, zcu)),4651 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4652 tuple_ty.structFieldType(1, zcu),4652 tuple_ty.fieldType(1, zcu),
4653 .{ .eflags = .ne },4653 .{ .eflags = .ne },
4654 .{},4654 .{},
4655 );4655 );
...@@ -4761,14 +4761,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4761,14 +4761,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4761 try self.genSetMem(4761 try self.genSetMem(
4762 .{ .frame = dst_mcv.load_frame.index },4762 .{ .frame = dst_mcv.load_frame.index },
4763 @intCast(tuple_ty.structFieldOffset(0, zcu)),4763 @intCast(tuple_ty.structFieldOffset(0, zcu)),
4764 tuple_ty.structFieldType(0, zcu),4764 tuple_ty.fieldType(0, zcu),
4765 .{ .register_pair = .{ .rax, .rdx } },4765 .{ .register_pair = .{ .rax, .rdx } },
4766 .{},4766 .{},
4767 );4767 );
4768 try self.genSetMem(4768 try self.genSetMem(
4769 .{ .frame = dst_mcv.load_frame.index },4769 .{ .frame = dst_mcv.load_frame.index },
4770 @intCast(tuple_ty.structFieldOffset(1, zcu)),4770 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4771 tuple_ty.structFieldType(1, zcu),4771 tuple_ty.fieldType(1, zcu),
4772 .{ .register = tmp_regs[1] },4772 .{ .register = tmp_regs[1] },
4773 .{},4773 .{},
4774 );4774 );
...@@ -4816,14 +4816,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -4816,14 +4816,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
4816 try self.genSetMem(4816 try self.genSetMem(
4817 .{ .frame = frame_index },4817 .{ .frame = frame_index },
4818 @intCast(tuple_ty.structFieldOffset(0, zcu)),4818 @intCast(tuple_ty.structFieldOffset(0, zcu)),
4819 tuple_ty.structFieldType(0, zcu),4819 tuple_ty.fieldType(0, zcu),
4820 partial_mcv,4820 partial_mcv,
4821 .{},4821 .{},
4822 );4822 );
4823 try self.genSetMem(4823 try self.genSetMem(
4824 .{ .frame = frame_index },4824 .{ .frame = frame_index },
4825 @intCast(tuple_ty.structFieldOffset(1, zcu)),4825 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4826 tuple_ty.structFieldType(1, zcu),4826 tuple_ty.fieldType(1, zcu),
4827 .{ .immediate = 0 }, // cc being set is impossible4827 .{ .immediate = 0 }, // cc being set is impossible
4828 .{},4828 .{},
4829 );4829 );
...@@ -8143,7 +8143,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -8143,7 +8143,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
81438143
8144 const container_ty = self.typeOf(operand);8144 const container_ty = self.typeOf(operand);
8145 const container_rc = self.regClassForType(container_ty);8145 const container_rc = self.regClassForType(container_ty);
8146 const field_ty = container_ty.structFieldType(index, zcu);8146 const field_ty = container_ty.fieldType(index, zcu);
8147 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;8147 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
8148 const field_rc = self.regClassForType(field_ty);8148 const field_rc = self.regClassForType(field_ty);
8149 const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp);8149 const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp);
...@@ -15273,14 +15273,14 @@ fn genSetMem(...@@ -15273,14 +15273,14 @@ fn genSetMem(
15273 try self.genSetMem(15273 try self.genSetMem(
15274 base,15274 base,
15275 disp + @as(i32, @intCast(ty.structFieldOffset(0, zcu))),15275 disp + @as(i32, @intCast(ty.structFieldOffset(0, zcu))),
15276 ty.structFieldType(0, zcu),15276 ty.fieldType(0, zcu),
15277 .{ .register = ro.reg },15277 .{ .register = ro.reg },
15278 opts,15278 opts,
15279 );15279 );
15280 try self.genSetMem(15280 try self.genSetMem(
15281 base,15281 base,
15282 disp + @as(i32, @intCast(ty.structFieldOffset(1, zcu))),15282 disp + @as(i32, @intCast(ty.structFieldOffset(1, zcu))),
15283 ty.structFieldType(1, zcu),15283 ty.fieldType(1, zcu),
15284 .{ .eflags = ro.eflags },15284 .{ .eflags = ro.eflags },
15285 opts,15285 opts,
15286 );15286 );
...@@ -18150,7 +18150,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -18150,7 +18150,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
18150 const elem_i: u32 = @intCast(elem_i_usize);18150 const elem_i: u32 = @intCast(elem_i_usize);
18151 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;18151 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
1815218152
18153 const elem_ty = result_ty.structFieldType(elem_i, zcu);18153 const elem_ty = result_ty.fieldType(elem_i, zcu);
18154 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));18154 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));
18155 if (elem_bit_size > 64) {18155 if (elem_bit_size > 64) {
18156 return self.fail(18156 return self.fail(
...@@ -18232,7 +18232,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -18232,7 +18232,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
18232 } else for (elements, 0..) |elem, elem_i| {18232 } else for (elements, 0..) |elem, elem_i| {
18233 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;18233 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
1823418234
18235 const elem_ty = result_ty.structFieldType(elem_i, zcu);18235 const elem_ty = result_ty.fieldType(elem_i, zcu);
18236 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));18236 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));
18237 const elem_mcv = try self.resolveInst(elem);18237 const elem_mcv = try self.resolveInst(elem);
18238 const mat_elem_mcv = switch (elem_mcv) {18238 const mat_elem_mcv = switch (elem_mcv) {
src/codegen/c.zig+2-2
...@@ -7206,7 +7206,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7206,7 +7206,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7206 var empty = true;7206 var empty = true;
7207 for (0..elements.len) |field_index| {7207 for (0..elements.len) |field_index| {
7208 if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;7208 if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;
7209 const field_ty = inst_ty.structFieldType(field_index, zcu);7209 const field_ty = inst_ty.fieldType(field_index, zcu);
7210 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7210 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
72117211
7212 if (!empty) {7212 if (!empty) {
...@@ -7219,7 +7219,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7219,7 +7219,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7219 empty = true;7219 empty = true;
7220 for (resolved_elements, 0..) |element, field_index| {7220 for (resolved_elements, 0..) |element, field_index| {
7221 if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;7221 if (inst_ty.structFieldIsComptime(field_index, zcu)) continue;
7222 const field_ty = inst_ty.structFieldType(field_index, zcu);7222 const field_ty = inst_ty.fieldType(field_index, zcu);
7223 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7223 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
72247224
7225 if (!empty) try writer.writeAll(", ");7225 if (!empty) try writer.writeAll(", ");
src/codegen/llvm.zig+12-26
...@@ -2496,16 +2496,10 @@ pub const Object = struct {...@@ -2496,16 +2496,10 @@ pub const Object = struct {
2496 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);2496 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2497 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;2497 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
2498 const field_size = field_ty.abiSize(zcu);2498 const field_size = field_ty.abiSize(zcu);
2499 const field_align = pt.structFieldAlignment(2499 const field_align = ty.fieldAlignment(field_index, zcu);
2500 struct_type.fieldAlign(ip, field_index),
2501 field_ty,
2502 struct_type.layout,
2503 );
2504 const field_offset = ty.structFieldOffset(field_index, zcu);2500 const field_offset = ty.structFieldOffset(field_index, zcu);
2505
2506 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse2501 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
2507 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);2502 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
2508
2509 fields.appendAssumeCapacity(try o.builder.debugMemberType(2503 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2510 try o.builder.metadataString(field_name.toSlice(ip)),2504 try o.builder.metadataString(field_name.toSlice(ip)),
2511 .none, // File2505 .none, // File
...@@ -2598,7 +2592,7 @@ pub const Object = struct {...@@ -2598,7 +2592,7 @@ pub const Object = struct {
2598 const field_size = Type.fromInterned(field_ty).abiSize(zcu);2592 const field_size = Type.fromInterned(field_ty).abiSize(zcu);
2599 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {2593 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {
2600 .@"packed" => .none,2594 .@"packed" => .none,
2601 .auto, .@"extern" => Type.unionFieldNormalAlignment(union_type, @intCast(field_index), zcu),2595 .auto, .@"extern" => ty.fieldAlignment(field_index, zcu),
2602 };2596 };
26032597
2604 const field_name = tag_type.names.get(ip)[field_index];2598 const field_name = tag_type.names.get(ip)[field_index];
...@@ -3315,11 +3309,7 @@ pub const Object = struct {...@@ -3315,11 +3309,7 @@ pub const Object = struct {
3315 var it = struct_type.iterateRuntimeOrder(ip);3309 var it = struct_type.iterateRuntimeOrder(ip);
3316 while (it.next()) |field_index| {3310 while (it.next()) |field_index| {
3317 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);3311 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
3318 const field_align = pt.structFieldAlignment(3312 const field_align = t.fieldAlignment(field_index, zcu);
3319 struct_type.fieldAlign(ip, field_index),
3320 field_ty,
3321 struct_type.layout,
3322 );
3323 const field_ty_align = field_ty.abiAlignment(zcu);3313 const field_ty_align = field_ty.abiAlignment(zcu);
3324 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";3314 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";
3325 big_align = big_align.max(field_align);3315 big_align = big_align.max(field_align);
...@@ -4127,11 +4117,7 @@ pub const Object = struct {...@@ -4127,11 +4117,7 @@ pub const Object = struct {
4127 var field_it = struct_type.iterateRuntimeOrder(ip);4117 var field_it = struct_type.iterateRuntimeOrder(ip);
4128 while (field_it.next()) |field_index| {4118 while (field_it.next()) |field_index| {
4129 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);4119 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
4130 const field_align = pt.structFieldAlignment(4120 const field_align = ty.fieldAlignment(field_index, zcu);
4131 struct_type.fieldAlign(ip, field_index),
4132 field_ty,
4133 struct_type.layout,
4134 );
4135 big_align = big_align.max(field_align);4121 big_align = big_align.max(field_align);
4136 const prev_offset = offset;4122 const prev_offset = offset;
4137 offset = field_align.forward(offset);4123 offset = field_align.forward(offset);
...@@ -6528,7 +6514,7 @@ pub const FuncGen = struct {...@@ -6528,7 +6514,7 @@ pub const FuncGen = struct {
6528 const struct_ty = self.typeOf(struct_field.struct_operand);6514 const struct_ty = self.typeOf(struct_field.struct_operand);
6529 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);6515 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
6530 const field_index = struct_field.field_index;6516 const field_index = struct_field.field_index;
6531 const field_ty = struct_ty.structFieldType(field_index, zcu);6517 const field_ty = struct_ty.fieldType(field_index, zcu);
6532 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;6518 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;
65336519
6534 if (!isByRef(struct_ty, zcu)) {6520 if (!isByRef(struct_ty, zcu)) {
...@@ -6590,7 +6576,7 @@ pub const FuncGen = struct {...@@ -6590,7 +6576,7 @@ pub const FuncGen = struct {
6590 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;6576 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
6591 const field_ptr =6577 const field_ptr =
6592 try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");6578 try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");
6593 const alignment = struct_ty.structFieldAlign(field_index, zcu);6579 const alignment = struct_ty.fieldAlignment(field_index, zcu);
6594 const field_ptr_ty = try pt.ptrType(.{6580 const field_ptr_ty = try pt.ptrType(.{
6595 .child = field_ty.toIntern(),6581 .child = field_ty.toIntern(),
6596 .flags = .{ .alignment = alignment },6582 .flags = .{ .alignment = alignment },
...@@ -7471,8 +7457,8 @@ pub const FuncGen = struct {...@@ -7471,8 +7457,8 @@ pub const FuncGen = struct {
7471 assert(self.err_ret_trace != .none);7457 assert(self.err_ret_trace != .none);
7472 const field_ptr =7458 const field_ptr =
7473 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");7459 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");
7474 const field_alignment = struct_ty.structFieldAlign(field_index, zcu);7460 const field_alignment = struct_ty.fieldAlignment(field_index, zcu);
7475 const field_ty = struct_ty.structFieldType(field_index, zcu);7461 const field_ty = struct_ty.fieldType(field_index, zcu);
7476 const field_ptr_ty = try pt.ptrType(.{7462 const field_ptr_ty = try pt.ptrType(.{
7477 .child = field_ty.toIntern(),7463 .child = field_ty.toIntern(),
7478 .flags = .{ .alignment = field_alignment },7464 .flags = .{ .alignment = field_alignment },
...@@ -10080,7 +10066,7 @@ pub const FuncGen = struct {...@@ -10080,7 +10066,7 @@ pub const FuncGen = struct {
10080 const field_ptr_ty = try pt.ptrType(.{10066 const field_ptr_ty = try pt.ptrType(.{
10081 .child = self.typeOf(elem).toIntern(),10067 .child = self.typeOf(elem).toIntern(),
10082 .flags = .{10068 .flags = .{
10083 .alignment = result_ty.structFieldAlign(i, zcu),10069 .alignment = result_ty.fieldAlignment(i, zcu),
10084 },10070 },
10085 });10071 });
10086 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);10072 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);
...@@ -10185,7 +10171,7 @@ pub const FuncGen = struct {...@@ -10185,7 +10171,7 @@ pub const FuncGen = struct {
10185 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);10171 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
10186 const field_llvm_ty = try o.lowerType(field_ty);10172 const field_llvm_ty = try o.lowerType(field_ty);
10187 const field_size = field_ty.abiSize(zcu);10173 const field_size = field_ty.abiSize(zcu);
10188 const field_align = Type.unionFieldNormalAlignment(union_obj, extra.field_index, zcu);10174 const field_align = union_ty.fieldAlignment(extra.field_index, zcu);
10189 const llvm_usize = try o.lowerType(Type.usize);10175 const llvm_usize = try o.lowerType(Type.usize);
10190 const usize_zero = try o.builder.intValue(llvm_usize, 0);10176 const usize_zero = try o.builder.intValue(llvm_usize, 0);
1019110177
...@@ -11188,7 +11174,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11188,7 +11174,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11188 var types_len: usize = 0;11174 var types_len: usize = 0;
11189 var types: [8]Builder.Type = undefined;11175 var types: [8]Builder.Type = undefined;
11190 for (0..return_type.structFieldCount(zcu)) |field_index| {11176 for (0..return_type.structFieldCount(zcu)) |field_index| {
11191 const field_ty = return_type.structFieldType(field_index, zcu);11177 const field_ty = return_type.fieldType(field_index, zcu);
11192 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;11178 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
11193 types[types_len] = try o.lowerType(field_ty);11179 types[types_len] = try o.lowerType(field_ty);
11194 types_len += 1;11180 types_len += 1;
...@@ -11444,7 +11430,7 @@ const ParamTypeIterator = struct {...@@ -11444,7 +11430,7 @@ const ParamTypeIterator = struct {
11444 .fields => {11430 .fields => {
11445 it.types_len = 0;11431 it.types_len = 0;
11446 for (0..ty.structFieldCount(zcu)) |field_index| {11432 for (0..ty.structFieldCount(zcu)) |field_index| {
11447 const field_ty = ty.structFieldType(field_index, zcu);11433 const field_ty = ty.fieldType(field_index, zcu);
11448 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;11434 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
11449 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);11435 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);
11450 it.types_len += 1;11436 it.types_len += 1;
src/codegen/spirv.zig+1-1
...@@ -5148,7 +5148,7 @@ const NavGen = struct {...@@ -5148,7 +5148,7 @@ const NavGen = struct {
5148 const object_ty = self.typeOf(struct_field.struct_operand);5148 const object_ty = self.typeOf(struct_field.struct_operand);
5149 const object_id = try self.resolve(struct_field.struct_operand);5149 const object_id = try self.resolve(struct_field.struct_operand);
5150 const field_index = struct_field.field_index;5150 const field_index = struct_field.field_index;
5151 const field_ty = object_ty.structFieldType(field_index, zcu);5151 const field_ty = object_ty.fieldType(field_index, zcu);
51525152
5153 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;5153 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;
51545154
src/mutable_value.zig+1-1
...@@ -223,7 +223,7 @@ pub const MutableValue = union(enum) {...@@ -223,7 +223,7 @@ pub const MutableValue = union(enum) {
223 @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem });223 @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem });
224 },224 },
225 .Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| {225 .Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| {
226 const field_ty = ty.structFieldType(i, zcu).toIntern();226 const field_ty = ty.fieldType(i, zcu).toIntern();
227 mut_elem.* = .{ .interned = try pt.intern(.{ .undef = field_ty }) };227 mut_elem.* = .{ .interned = try pt.intern(.{ .undef = field_ty }) };
228 },228 },
229 else => unreachable,229 else => unreachable,