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(
48874887 const i: u32 = @intCast(i_usize);
48884888 if (opt_field_ptr.unwrap()) |field_ptr| {
48894889 // 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);
48914891 if (try sema.typeHasOnePossibleValue(field_ty)) |opv| {
48924892 field_values[i] = opv.toIntern();
48934893 continue;
......@@ -4999,7 +4999,7 @@ fn validateStructInit(
49994999 var block_index = first_block_index;
50005000 for (block.instructions.items[first_block_index..]) |cur_inst| {
50015001 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);
50035003 if (try field_ty.onePossibleValue(pt)) |_| continue;
50045004 field_ptr_ref = sema.inst_map.get(instrs[init_index]).?;
50055005 }
......@@ -8430,7 +8430,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
84308430 try indexable_ty.resolveFields(pt);
84318431 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction
84328432 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);
84348434 return Air.internedToRef(elem_type.toIntern());
84358435 } else {
84368436 const elem_type = indexable_ty.elemType2(zcu);
......@@ -14419,7 +14419,7 @@ fn analyzeTupleCat(
1441914419 var runtime_src: ?LazySrcLoc = null;
1442014420 var i: u32 = 0;
1442114421 while (i < lhs_len) : (i += 1) {
14422 types[i] = lhs_ty.structFieldType(i, zcu).toIntern();
14422 types[i] = lhs_ty.fieldType(i, zcu).toIntern();
1442314423 const default_val = lhs_ty.structFieldDefaultValue(i, zcu);
1442414424 values[i] = default_val.toIntern();
1442514425 const operand_src = block.src(.{ .array_cat_lhs = .{
......@@ -14433,7 +14433,7 @@ fn analyzeTupleCat(
1443314433 }
1443414434 i = 0;
1443514435 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();
1443714437 const default_val = rhs_ty.structFieldDefaultValue(i, zcu);
1443814438 values[i + lhs_len] = default_val.toIntern();
1443914439 const operand_src = block.src(.{ .array_cat_rhs = .{
......@@ -14791,7 +14791,7 @@ fn analyzeTupleMul(
1479114791 const opt_runtime_src = rs: {
1479214792 var runtime_src: ?LazySrcLoc = null;
1479314793 for (0..tuple_len) |i| {
14794 types[i] = operand_ty.structFieldType(i, zcu).toIntern();
14794 types[i] = operand_ty.fieldType(i, zcu).toIntern();
1479514795 values[i] = operand_ty.structFieldDefaultValue(i, zcu).toIntern();
1479614796 const operand_src = block.src(.{ .array_cat_lhs = .{
1479714797 .array_cat_offset = src_node,
......@@ -18466,13 +18466,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1846618466 };
1846718467
1846818468 const alignment = switch (layout) {
18469 .auto, .@"extern" => try Type.unionFieldNormalAlignmentAdvanced(
18470 union_obj,
18471 @intCast(field_index),
18472 .sema,
18473 pt.zcu,
18474 pt.tid,
18475 ),
18469 .auto, .@"extern" => try ty.fieldAlignmentSema(field_index, pt),
1847618470 .@"packed" => .none,
1847718471 };
1847818472
......@@ -18691,12 +18685,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1869118685 const default_val_ptr = try sema.optRefValue(opt_default_val);
1869218686 const alignment = switch (struct_type.layout) {
1869318687 .@"packed" => .none,
18694 else => try field_ty.structFieldAlignmentAdvanced(
18688 else => try field_ty.structFieldAlignmentSema(
1869518689 struct_type.fieldAlign(ip, field_index),
1869618690 struct_type.layout,
18697 .sema,
18698 pt.zcu,
18699 pt.tid,
18691 pt,
1870018692 ),
1870118693 };
1870218694
......@@ -20327,7 +20319,7 @@ fn zirStructInit(
2032720319 assert(field_inits[field_index] == .none);
2032820320 found_fields[field_index] = item.data.field_type;
2032920321 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);
2033120323 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);
2033220324 if (!is_packed) {
2033320325 try resolved_ty.resolveStructFieldInits(pt);
......@@ -20338,7 +20330,7 @@ fn zirStructInit(
2033820330 });
2033920331 };
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)) {
2034220334 return sema.failWithInvalidComptimeFieldStore(block, field_src, resolved_ty, field_index);
2034320335 }
2034420336 }
......@@ -20799,7 +20791,7 @@ fn zirArrayInit(
2079920791 const arg = args[i + 1];
2080020792 const resolved_arg = try sema.resolveInst(arg);
2080120793 const elem_ty = if (is_tuple)
20802 array_ty.structFieldType(i, zcu)
20794 array_ty.fieldType(i, zcu)
2080320795 else
2080420796 array_ty.elemType2(zcu);
2080520797 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
......@@ -20862,7 +20854,7 @@ fn zirArrayInit(
2086220854 if (is_tuple) {
2086320855 for (resolved_args, 0..) |arg, i| {
2086420856 const elem_ptr_ty = try pt.ptrTypeSema(.{
20865 .child = array_ty.structFieldType(i, zcu).toIntern(),
20857 .child = array_ty.fieldType(i, zcu).toIntern(),
2086620858 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2086720859 });
2086820860 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
2523425226 },
2523525227 .packed_offset = parent_ptr_info.packed_offset,
2523625228 };
25237 const field_ty = parent_ty.structFieldType(field_index, zcu);
25229 const field_ty = parent_ty.fieldType(field_index, zcu);
2523825230 var actual_field_ptr_info: InternPool.Key.PtrType = .{
2523925231 .child = field_ty.toIntern(),
2524025232 .flags = .{
......@@ -25249,19 +25241,17 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2524925241 switch (parent_ty.containerLayout(zcu)) {
2525025242 .auto => {
2525125243 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(
25253 struct_obj.fieldAlign(ip, field_index),
25254 struct_obj.layout,
25255 .sema,
25256 pt.zcu,
25257 pt.tid,
25258 ) else if (zcu.typeToUnion(parent_ty)) |union_obj|
25259 try Type.unionFieldNormalAlignmentAdvanced(
25260 union_obj,
25261 field_index,
25262 .sema,
25263 pt.zcu,
25264 pt.tid,
25244 if (zcu.typeToStruct(parent_ty)) |struct_obj|
25245 try field_ty.structFieldAlignmentSema(
25246 struct_obj.fieldAlign(ip, field_index),
25247 struct_obj.layout,
25248 pt,
25249 )
25250 else if (zcu.typeToUnion(parent_ty)) |union_obj|
25251 try field_ty.unionFieldAlignmentSema(
25252 union_obj.fieldAlign(ip, field_index),
25253 union_obj.flagsUnordered(ip).layout,
25254 pt,
2526525255 )
2526625256 else
2526725257 actual_field_ptr_info.flags.alignment,
......@@ -28035,14 +28025,14 @@ fn fieldCallBind(
2803528025 }
2803628026 if (field_name.toUnsigned(ip)) |field_index| {
2803728027 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);
2803928029 }
2804028030 } else {
2804128031 const max = concrete_ty.structFieldCount(zcu);
2804228032 for (0..max) |i_usize| {
2804328033 const i: u32 = @intCast(i_usize);
2804428034 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);
2804628036 }
2804728037 }
2804828038 }
......@@ -28340,12 +28330,10 @@ fn structFieldPtrByIndex(
2834028330 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));
2834128331 } else {
2834228332 // 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(
2834428334 struct_type.fieldAlign(ip, field_index),
2834528335 struct_type.layout,
28346 .sema,
28347 pt.zcu,
28348 pt.tid,
28336 pt,
2834928337 );
2835028338 ptr_ty_data.flags.alignment = if (struct_ptr_ty_info.flags.alignment == .none)
2835128339 field_align
......@@ -28477,7 +28465,7 @@ fn tupleFieldValByIndex(
2847728465) CompileError!Air.Inst.Ref {
2847828466 const pt = sema.pt;
2847928467 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
2848228470 if (tuple_ty.structFieldIsComptime(field_index, zcu))
2848328471 try tuple_ty.resolveStructFieldInits(pt);
......@@ -28538,13 +28526,7 @@ fn unionFieldPtr(
2853828526 union_ptr_info.flags.alignment
2853928527 else
2854028528 try union_ty.abiAlignmentSema(pt);
28541 const field_align = try Type.unionFieldNormalAlignmentAdvanced(
28542 union_obj,
28543 field_index,
28544 .sema,
28545 pt.zcu,
28546 pt.tid,
28547 );
28529 const field_align = try union_ty.fieldAlignmentSema(field_index, pt);
2854828530 break :blk union_align.min(field_align);
2854928531 } else union_ptr_info.flags.alignment,
2855028532 },
......@@ -28921,7 +28903,7 @@ fn tupleFieldPtr(
2892128903 });
2892228904 }
2892328905
28924 const field_ty = tuple_ty.structFieldType(field_index, zcu);
28906 const field_ty = tuple_ty.fieldType(field_index, zcu);
2892528907 const ptr_field_ty = try pt.ptrTypeSema(.{
2892628908 .child = field_ty.toIntern(),
2892728909 .flags = .{
......@@ -28979,7 +28961,7 @@ fn tupleField(
2897928961 });
2898028962 }
2898128963
28982 const field_ty = tuple_ty.structFieldType(field_index, zcu);
28964 const field_ty = tuple_ty.fieldType(field_index, zcu);
2898328965
2898428966 if (tuple_ty.structFieldIsComptime(field_index, zcu))
2898528967 try tuple_ty.resolveStructFieldInits(pt);
......@@ -30615,9 +30597,9 @@ pub fn coerceInMemoryAllowed(
3061530597 const field_count = dest_ty.structFieldCount(zcu);
3061630598 for (0..field_count) |field_idx| {
3061730599 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;
30619 const dest_field_ty = dest_ty.structFieldType(field_idx, zcu);
30620 const src_field_ty = src_ty.structFieldType(field_idx, zcu);
30600 if (dest_ty.fieldAlignment(field_idx, zcu) != src_ty.fieldAlignment(field_idx, zcu)) break :tuple;
30601 const dest_field_ty = dest_ty.fieldType(field_idx, zcu);
30602 const src_field_ty = src_ty.fieldType(field_idx, zcu);
3062130603 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src, null);
3062230604 if (field != .ok) break :tuple;
3062330605 }
......@@ -35073,7 +35055,7 @@ fn resolvePeerTypesInner(
3507335055 peer_field_val.* = null;
3507435056 continue;
3507535057 };
35076 peer_field_ty.* = ty.structFieldType(field_index, zcu);
35058 peer_field_ty.* = ty.fieldType(field_index, zcu);
3507735059 peer_field_val.* = if (opt_val) |val| try val.fieldValue(pt, field_index) else null;
3507835060 }
3507935061
......@@ -35095,7 +35077,7 @@ fn resolvePeerTypesInner(
3509535077 // Already-resolved types won't be referenced by the error so it's fine
3509635078 // to leave them undefined.
3509735079 const ty = opt_ty orelse continue;
35098 peer_field_ty.* = ty.structFieldType(field_index, zcu);
35080 peer_field_ty.* = ty.fieldType(field_index, zcu);
3509935081 }
3510035082
3510135083 return .{ .field_error = .{
......@@ -35220,9 +35202,9 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
3522035202 .elem_ty = Type.noreturn,
3522135203 };
3522235204 if (!ty.isTuple(zcu)) return null;
35223 const elem_ty = ty.structFieldType(0, zcu);
35205 const elem_ty = ty.fieldType(0, zcu);
3522435206 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)) {
3522635208 return null;
3522735209 }
3522835210 }
......@@ -35309,12 +35291,10 @@ pub fn resolveStructAlignment(
3530935291 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
3531035292 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt))
3531135293 continue;
35312 const field_align = try field_ty.structFieldAlignmentAdvanced(
35294 const field_align = try field_ty.structFieldAlignmentSema(
3531335295 struct_type.fieldAlign(ip, i),
3531435296 struct_type.layout,
35315 .sema,
35316 pt.zcu,
35317 pt.tid,
35297 pt,
3531835298 );
3531935299 alignment = alignment.maxStrict(field_align);
3532035300 }
......@@ -35375,12 +35355,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3537535355 },
3537635356 else => return err,
3537735357 };
35378 field_align.* = try field_ty.structFieldAlignmentAdvanced(
35358 field_align.* = try field_ty.structFieldAlignmentSema(
3537935359 struct_type.fieldAlign(ip, i),
3538035360 struct_type.layout,
35381 .sema,
35382 pt.zcu,
35383 pt.tid,
35361 pt,
3538435362 );
3538535363 big_align = big_align.maxStrict(field_align.*);
3538635364 }
src/Sema/bitcast.zig+3-3
......@@ -542,7 +542,7 @@ const PackValueBits = struct {
542542 while (it.next()) |field_idx| {
543543 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8;
544544 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);
546546 elems[field_idx] = (try pack.get(field_ty)).toIntern();
547547 cur_bit_off = want_bit_off + field_ty.bitSize(zcu);
548548 }
......@@ -552,7 +552,7 @@ const PackValueBits = struct {
552552 var cur_bit_off: u64 = ty.bitSize(zcu);
553553 var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip);
554554 while (it.next()) |field_idx| {
555 const field_ty = ty.structFieldType(field_idx, zcu);
555 const field_ty = ty.fieldType(field_idx, zcu);
556556 const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu);
557557 try pack.padding(cur_bit_off - want_bit_off);
558558 elems[field_idx] = (try pack.get(field_ty)).toIntern();
......@@ -578,7 +578,7 @@ const PackValueBits = struct {
578578 // This is identical between LE and BE targets.
579579 const elems = try arena.alloc(InternPool.Index, ty.structFieldCount(zcu));
580580 for (elems, 0..) |*elem, i| {
581 const field_ty = ty.structFieldType(i, zcu);
581 const field_ty = ty.fieldType(i, zcu);
582582 elem.* = (try pack.get(field_ty)).toIntern();
583583 }
584584 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
src/Sema/comptime_ptr_access.zig+2-2
......@@ -451,7 +451,7 @@ fn loadComptimePtrInner(
451451 .@"packed" => break, // let the bitcast logic handle this
452452 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
453453 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);
455455 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
456456 cur_val = try cur_val.getElem(sema.pt, field_idx);
457457 cur_offset -= start_off;
......@@ -873,7 +873,7 @@ fn prepareComptimePtrStore(
873873 .@"packed" => break, // let the bitcast logic handle this
874874 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
875875 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);
877877 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
878878 cur_val = try cur_val.elem(pt, sema.arena, field_idx);
879879 cur_offset -= start_off;
src/Type.zig+83-44
......@@ -3191,8 +3191,8 @@ pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {
31913191 };
31923192}
31933193
3194/// Supports structs and unions.
3195pub fn structFieldType(ty: Type, index: usize, zcu: *const Zcu) Type {
3194/// Returns the field type. Supports structs and unions.
3195pub fn fieldType(ty: Type, index: usize, zcu: *const Zcu) Type {
31963196 const ip = &zcu.intern_pool;
31973197 return switch (ip.indexToKey(ty.toIntern())) {
31983198 .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 {
32053205 };
32063206}
32073207
3208pub fn structFieldAlign(ty: Type, index: usize, zcu: *Zcu) Alignment {
3209 return ty.structFieldAlignAdvanced(index, .normal, zcu, {}) catch unreachable;
3208pub fn fieldAlignment(ty: Type, index: usize, zcu: *Zcu) Alignment {
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);
32103214}
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(
32133222 ty: Type,
32143223 index: usize,
32153224 comptime strat: ResolveStrat,
32163225 zcu: *Zcu,
32173226 tid: strat.Tid(),
3218) !Alignment {
3227) SemaError!Alignment {
32193228 const ip = &zcu.intern_pool;
32203229 switch (ip.indexToKey(ty.toIntern())) {
32213230 .struct_type => {
......@@ -3223,13 +3232,7 @@ pub fn structFieldAlignAdvanced(
32233232 assert(struct_type.layout != .@"packed");
32243233 const explicit_align = struct_type.fieldAlign(ip, index);
32253234 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);
3226 return field_ty.structFieldAlignmentAdvanced(
3227 explicit_align,
3228 struct_type.layout,
3229 strat,
3230 zcu,
3231 tid,
3232 );
3235 return field_ty.structFieldAlignmentInner(explicit_align, struct_type.layout, strat, zcu, tid);
32333236 },
32343237 .anon_struct_type => |anon_struct| {
32353238 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentInner(
......@@ -3240,28 +3243,62 @@ pub fn structFieldAlignAdvanced(
32403243 },
32413244 .union_type => {
32423245 const union_obj = ip.loadUnionType(ty.toIntern());
3243 return unionFieldNormalAlignmentAdvanced(
3244 union_obj,
3245 @intCast(index),
3246 strat,
3247 zcu,
3248 tid,
3249 );
3246 const layout = union_obj.flagsUnordered(ip).layout;
3247 assert(layout != .@"packed");
3248 const explicit_align = union_obj.fieldAlign(ip, index);
3249 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[index]);
3250 return field_ty.unionFieldAlignmentInner(explicit_align, layout, strat, zcu, tid);
32503251 },
32513252 else => unreachable,
32523253 }
32533254}
32543255
3255/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
3256/// If `strat` is `.sema`, may perform type resolution.
3257pub fn structFieldAlignmentAdvanced(
3256/// Returns the alignment of a non-packed struct field. Assert the layout is not packed.
3257///
3258/// Asserts that all resolution needed was done.
3259pub fn structFieldAlignment(
32583260 field_ty: Type,
32593261 explicit_alignment: InternPool.Alignment,
32603262 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,
32613298 comptime strat: Type.ResolveStrat,
32623299 zcu: *Zcu,
32633300 tid: strat.Tid(),
3264) Zcu.SemaError!InternPool.Alignment {
3301) SemaError!Alignment {
32653302 assert(layout != .@"packed");
32663303 if (explicit_alignment != .none) return explicit_alignment;
32673304 const ty_abi_align = (try field_ty.abiAlignmentInner(
......@@ -3281,29 +3318,31 @@ pub fn structFieldAlignmentAdvanced(
32813318 return ty_abi_align;
32823319}
32833320
3284/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
3285pub fn unionFieldNormalAlignment(
3286 loaded_union: InternPool.LoadedUnionType,
3287 field_index: u32,
3288 zcu: *Zcu,
3289) InternPool.Alignment {
3290 return unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal, zcu, {}) catch unreachable;
3321pub fn unionFieldAlignmentSema(
3322 field_ty: Type,
3323 explicit_alignment: Alignment,
3324 layout: std.builtin.Type.ContainerLayout,
3325 pt: Zcu.PerThread,
3326) SemaError!Alignment {
3327 return field_ty.unionFieldAlignmentInner(
3328 explicit_alignment,
3329 layout,
3330 .sema,
3331 pt.zcu,
3332 pt.tid,
3333 );
32913334}
32923335
3293/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
3294/// If `strat` is `.sema`, may perform type resolution.
3295pub fn unionFieldNormalAlignmentAdvanced(
3296 loaded_union: InternPool.LoadedUnionType,
3297 field_index: u32,
3336pub fn unionFieldAlignmentInner(
3337 field_ty: Type,
3338 explicit_alignment: Alignment,
3339 layout: std.builtin.Type.ContainerLayout,
32983340 comptime strat: Type.ResolveStrat,
32993341 zcu: *Zcu,
33003342 tid: strat.Tid(),
3301) Zcu.SemaError!InternPool.Alignment {
3302 const ip = &zcu.intern_pool;
3303 assert(loaded_union.flagsUnordered(ip).layout != .@"packed");
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]);
3343) SemaError!Alignment {
3344 assert(layout != .@"packed");
3345 if (explicit_alignment != .none) return explicit_alignment;
33073346 if (field_ty.isNoReturn(zcu)) return .none;
33083347 return (try field_ty.abiAlignmentInner(strat.toLazy(), zcu, tid)).scalar;
33093348}
......@@ -3608,12 +3647,12 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
36083647
36093648 const zcu = pt.zcu;
36103649 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
36133652 var bit_offset: u16 = 0;
36143653 var running_bits: u16 = 0;
36153654 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);
36173656 if (i == field_idx) {
36183657 bit_offset = running_bits;
36193658 }
src/Value.zig+10-10
......@@ -1414,7 +1414,7 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
14141414 const zcu = pt.zcu;
14151415 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
14161416 .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(),
14181418 })),
14191419 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {
14201420 .bytes => |bytes| try pt.intern(.{ .int = .{
......@@ -3810,9 +3810,9 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
38103810 // `field_align` may be `.none` to represent the natural alignment of `field_ty`, but is not necessarily.
38113811 const field_ty: Type, const field_align: InternPool.Alignment = switch (aggregate_ty.zigTypeTag(zcu)) {
38123812 .Struct => field: {
3813 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);
3813 const field_ty = aggregate_ty.fieldType(field_idx, zcu);
38143814 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) },
38163816 .@"extern" => {
38173817 // Well-defined layout, so just offset the pointer appropriately.
38183818 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 {
38633863 const union_obj = zcu.typeToUnion(aggregate_ty).?;
38643864 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);
38653865 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) },
38673867 .@"extern" => {
38683868 // Point to the same address.
38693869 const result_ty = try pt.ptrTypeSema(info: {
......@@ -4198,14 +4198,14 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
41984198 const base_ptr_ty = base_ptr.typeOf(zcu);
41994199 const agg_ty = base_ptr_ty.childType(zcu);
42004200 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {
4201 .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(
4202 @intCast(field.index),
4201 .Struct => .{ agg_ty.fieldType(field.index, zcu), try agg_ty.fieldAlignmentInner(
4202 field.index,
42034203 if (have_sema) .sema else .normal,
42044204 pt.zcu,
42054205 if (have_sema) pt.tid else {},
42064206 ) },
4207 .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(
4208 @intCast(field.index),
4207 .Union => .{ agg_ty.unionFieldTypeByIndex(field.index, zcu), try agg_ty.fieldAlignmentInner(
4208 field.index,
42094209 if (have_sema) .sema else .normal,
42104210 pt.zcu,
42114211 if (have_sema) pt.tid else {},
......@@ -4344,7 +4344,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
43444344 .Struct => switch (cur_ty.containerLayout(zcu)) {
43454345 .auto, .@"packed" => break,
43464346 .@"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);
43484348 const start_off = cur_ty.structFieldOffset(field_idx, zcu);
43494349 const end_off = start_off + field_ty.abiSize(zcu);
43504350 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
......@@ -4401,7 +4401,7 @@ pub fn resolveLazy(
44014401 .u64, .i64, .big_int => return val,
44024402 .lazy_align, .lazy_size => return pt.intValue(
44034403 Type.fromInterned(int.ty),
4404 (try val.getUnsignedIntInner(.sema, pt.zcu, pt.tid)).?,
4404 try val.toUnsignedIntSema(pt),
44054405 ),
44064406 },
44074407 .slice => |slice| {
src/Zcu/PerThread.zig-32
......@@ -3040,38 +3040,6 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 {
30403040 }
30413041}
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
30753043/// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets
30763044/// into the packed struct InternPool data rather than computing this on the
30773045/// 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 {
41444144 const zcu = pt.zcu;
41454145 const mcv = try self.resolveInst(operand);
41464146 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);
41484148 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, zcu)));
41494149
41504150 switch (mcv) {
......@@ -5473,10 +5473,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
54735473 const reg_lock = self.register_manager.lockReg(rwo.reg);
54745474 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);
54775477 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);
54805480 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, zcu)));
54815481 const raw_cond_reg = try self.register_manager.allocReg(null, gp);
54825482 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 {
9595 var count: u8 = 0;
9696 var i: u32 = 0;
9797 while (i < fields_len) : (i += 1) {
98 const field_ty = ty.structFieldType(i, zcu);
98 const field_ty = ty.fieldType(i, zcu);
9999 const field_count = countFloats(field_ty, zcu, maybe_float_bits);
100100 if (field_count == invalid) return invalid;
101101 count += field_count;
......@@ -130,7 +130,7 @@ pub fn getFloatArrayType(ty: Type, zcu: *Zcu) ?Type {
130130 const fields_len = ty.structFieldCount(zcu);
131131 var i: u32 = 0;
132132 while (i < fields_len) : (i += 1) {
133 const field_ty = ty.structFieldType(i, zcu);
133 const field_ty = ty.fieldType(i, zcu);
134134 if (getFloatArrayType(field_ty, zcu)) |some| return some;
135135 }
136136 return null;
src/arch/arm/CodeGen.zig+3-3
......@@ -2926,7 +2926,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
29262926 const mcv = try self.resolveInst(operand);
29272927 const struct_ty = self.typeOf(operand);
29282928 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
29312931 switch (mcv) {
29322932 .dead, .unreach => unreachable,
......@@ -5434,10 +5434,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
54345434 const reg_lock = self.register_manager.lockReg(reg);
54355435 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);
54385438 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);
54415441 const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, zcu));
54425442 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 {
4444 const fields = ty.structFieldCount(zcu);
4545 var i: u32 = 0;
4646 while (i < fields) : (i += 1) {
47 const field_ty = ty.structFieldType(i, zcu);
48 const field_alignment = ty.structFieldAlign(i, zcu);
47 const field_ty = ty.fieldType(i, zcu);
48 const field_alignment = ty.fieldAlignment(i, zcu);
4949 const field_size = field_ty.bitSize(zcu);
5050 if (field_size > 32 or field_alignment.compare(.gt, .@"32")) {
5151 return Class.arrSize(bit_size, 64);
......@@ -66,7 +66,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
6666
6767 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {
6868 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"))
7070 {
7171 return Class.arrSize(bit_size, 64);
7272 }
......@@ -141,7 +141,7 @@ fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u32 {
141141 var count: u32 = 0;
142142 var i: u32 = 0;
143143 while (i < fields_len) : (i += 1) {
144 const field_ty = ty.structFieldType(i, zcu);
144 const field_ty = ty.fieldType(i, zcu);
145145 const field_count = countFloats(field_ty, zcu, maybe_float_bits);
146146 if (field_count == invalid) return invalid;
147147 count += field_count;
src/arch/riscv64/CodeGen.zig+3-3
......@@ -4576,7 +4576,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
45764576 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
45774577 const src_mcv = try func.resolveInst(operand);
45784578 const struct_ty = func.typeOf(operand);
4579 const field_ty = struct_ty.structFieldType(index, zcu);
4579 const field_ty = struct_ty.fieldType(index, zcu);
45804580 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
45814581
45824582 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {
......@@ -7882,7 +7882,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
78827882 const elem_i: u32 = @intCast(elem_i_usize);
78837883 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);
78867886 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));
78877887 if (elem_bit_size > 64) {
78887888 return func.fail(
......@@ -7916,7 +7916,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
79167916 } else for (elements, 0..) |elem, elem_i| {
79177917 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);
79207920 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));
79217921 const elem_mcv = try func.resolveInst(elem);
79227922 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 {
2626 var any_fp = false;
2727 var field_count: usize = 0;
2828 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);
3030 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
3131 if (field_ty.isRuntimeFloat())
3232 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
39803980 const reg_lock = self.register_manager.lockReg(rwo.reg);
39813981 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);
39843984 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);
39873987 const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, zcu)));
39883988 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 {
39543954 const struct_ty = func.typeOf(struct_field.struct_operand);
39553955 const operand = try func.resolveInst(struct_field.struct_operand);
39563956 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);
39583958 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return func.finishAir(inst, .none, &.{struct_field.struct_operand});
39593959
39603960 const result: WValue = switch (struct_ty.containerLayout(zcu)) {
......@@ -5378,7 +5378,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
53785378 for (elements, 0..) |elem, elem_index| {
53795379 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);
53825382 const field_offset = result_ty.structFieldOffset(elem_index, zcu);
53835383 _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify);
53845384 prev_field_offset = field_offset;
src/arch/wasm/abi.zig+1-1
......@@ -108,7 +108,7 @@ pub fn scalarType(ty: Type, zcu: *Zcu) Type {
108108 return scalarType(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), zcu);
109109 } else {
110110 assert(ty.structFieldCount(zcu) == 1);
111 return scalarType(ty.structFieldType(0, zcu), zcu);
111 return scalarType(ty.fieldType(0, zcu), zcu);
112112 }
113113 },
114114 .Union => {
src/arch/x86_64/CodeGen.zig+15-15
......@@ -4352,14 +4352,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
43524352 try self.genSetMem(
43534353 .{ .frame = frame_index },
43544354 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4355 tuple_ty.structFieldType(1, zcu),
4355 tuple_ty.fieldType(1, zcu),
43564356 .{ .eflags = cc },
43574357 .{},
43584358 );
43594359 try self.genSetMem(
43604360 .{ .frame = frame_index },
43614361 @intCast(tuple_ty.structFieldOffset(0, zcu)),
4362 tuple_ty.structFieldType(0, zcu),
4362 tuple_ty.fieldType(0, zcu),
43634363 partial_mcv,
43644364 .{},
43654365 );
......@@ -4392,7 +4392,7 @@ fn genSetFrameTruncatedOverflowCompare(
43924392 };
43934393 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);
43964396 const int_info = ty.intInfo(zcu);
43974397
43984398 const hi_bits = (int_info.bits - 1) % 64 + 1;
......@@ -4450,7 +4450,7 @@ fn genSetFrameTruncatedOverflowCompare(
44504450 try self.genSetMem(
44514451 .{ .frame = frame_index },
44524452 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4453 tuple_ty.structFieldType(1, zcu),
4453 tuple_ty.fieldType(1, zcu),
44544454 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },
44554455 .{},
44564456 );
......@@ -4637,7 +4637,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
46374637 try self.genSetMem(
46384638 .{ .frame = dst_mcv.load_frame.index },
46394639 @intCast(tuple_ty.structFieldOffset(0, zcu)),
4640 tuple_ty.structFieldType(0, zcu),
4640 tuple_ty.fieldType(0, zcu),
46414641 result,
46424642 .{},
46434643 );
......@@ -4649,7 +4649,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
46494649 try self.genSetMem(
46504650 .{ .frame = dst_mcv.load_frame.index },
46514651 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4652 tuple_ty.structFieldType(1, zcu),
4652 tuple_ty.fieldType(1, zcu),
46534653 .{ .eflags = .ne },
46544654 .{},
46554655 );
......@@ -4761,14 +4761,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
47614761 try self.genSetMem(
47624762 .{ .frame = dst_mcv.load_frame.index },
47634763 @intCast(tuple_ty.structFieldOffset(0, zcu)),
4764 tuple_ty.structFieldType(0, zcu),
4764 tuple_ty.fieldType(0, zcu),
47654765 .{ .register_pair = .{ .rax, .rdx } },
47664766 .{},
47674767 );
47684768 try self.genSetMem(
47694769 .{ .frame = dst_mcv.load_frame.index },
47704770 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4771 tuple_ty.structFieldType(1, zcu),
4771 tuple_ty.fieldType(1, zcu),
47724772 .{ .register = tmp_regs[1] },
47734773 .{},
47744774 );
......@@ -4816,14 +4816,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
48164816 try self.genSetMem(
48174817 .{ .frame = frame_index },
48184818 @intCast(tuple_ty.structFieldOffset(0, zcu)),
4819 tuple_ty.structFieldType(0, zcu),
4819 tuple_ty.fieldType(0, zcu),
48204820 partial_mcv,
48214821 .{},
48224822 );
48234823 try self.genSetMem(
48244824 .{ .frame = frame_index },
48254825 @intCast(tuple_ty.structFieldOffset(1, zcu)),
4826 tuple_ty.structFieldType(1, zcu),
4826 tuple_ty.fieldType(1, zcu),
48274827 .{ .immediate = 0 }, // cc being set is impossible
48284828 .{},
48294829 );
......@@ -8143,7 +8143,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
81438143
81448144 const container_ty = self.typeOf(operand);
81458145 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);
81478147 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
81488148 const field_rc = self.regClassForType(field_ty);
81498149 const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp);
......@@ -15273,14 +15273,14 @@ fn genSetMem(
1527315273 try self.genSetMem(
1527415274 base,
1527515275 disp + @as(i32, @intCast(ty.structFieldOffset(0, zcu))),
15276 ty.structFieldType(0, zcu),
15276 ty.fieldType(0, zcu),
1527715277 .{ .register = ro.reg },
1527815278 opts,
1527915279 );
1528015280 try self.genSetMem(
1528115281 base,
1528215282 disp + @as(i32, @intCast(ty.structFieldOffset(1, zcu))),
15283 ty.structFieldType(1, zcu),
15283 ty.fieldType(1, zcu),
1528415284 .{ .eflags = ro.eflags },
1528515285 opts,
1528615286 );
......@@ -18150,7 +18150,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1815018150 const elem_i: u32 = @intCast(elem_i_usize);
1815118151 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);
1815418154 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));
1815518155 if (elem_bit_size > 64) {
1815618156 return self.fail(
......@@ -18232,7 +18232,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1823218232 } else for (elements, 0..) |elem, elem_i| {
1823318233 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);
1823618236 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));
1823718237 const elem_mcv = try self.resolveInst(elem);
1823818238 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 {
72067206 var empty = true;
72077207 for (0..elements.len) |field_index| {
72087208 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);
72107210 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
72117211
72127212 if (!empty) {
......@@ -7219,7 +7219,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
72197219 empty = true;
72207220 for (resolved_elements, 0..) |element, field_index| {
72217221 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);
72237223 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
72247224
72257225 if (!empty) try writer.writeAll(", ");
src/codegen/llvm.zig+12-26
......@@ -2496,16 +2496,10 @@ pub const Object = struct {
24962496 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
24972497 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
24982498 const field_size = field_ty.abiSize(zcu);
2499 const field_align = pt.structFieldAlignment(
2500 struct_type.fieldAlign(ip, field_index),
2501 field_ty,
2502 struct_type.layout,
2503 );
2499 const field_align = ty.fieldAlignment(field_index, zcu);
25042500 const field_offset = ty.structFieldOffset(field_index, zcu);
2505
25062501 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
25072502 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
2508
25092503 fields.appendAssumeCapacity(try o.builder.debugMemberType(
25102504 try o.builder.metadataString(field_name.toSlice(ip)),
25112505 .none, // File
......@@ -2598,7 +2592,7 @@ pub const Object = struct {
25982592 const field_size = Type.fromInterned(field_ty).abiSize(zcu);
25992593 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {
26002594 .@"packed" => .none,
2601 .auto, .@"extern" => Type.unionFieldNormalAlignment(union_type, @intCast(field_index), zcu),
2595 .auto, .@"extern" => ty.fieldAlignment(field_index, zcu),
26022596 };
26032597
26042598 const field_name = tag_type.names.get(ip)[field_index];
......@@ -3315,11 +3309,7 @@ pub const Object = struct {
33153309 var it = struct_type.iterateRuntimeOrder(ip);
33163310 while (it.next()) |field_index| {
33173311 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
3318 const field_align = pt.structFieldAlignment(
3319 struct_type.fieldAlign(ip, field_index),
3320 field_ty,
3321 struct_type.layout,
3322 );
3312 const field_align = t.fieldAlignment(field_index, zcu);
33233313 const field_ty_align = field_ty.abiAlignment(zcu);
33243314 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";
33253315 big_align = big_align.max(field_align);
......@@ -4127,11 +4117,7 @@ pub const Object = struct {
41274117 var field_it = struct_type.iterateRuntimeOrder(ip);
41284118 while (field_it.next()) |field_index| {
41294119 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
4130 const field_align = pt.structFieldAlignment(
4131 struct_type.fieldAlign(ip, field_index),
4132 field_ty,
4133 struct_type.layout,
4134 );
4120 const field_align = ty.fieldAlignment(field_index, zcu);
41354121 big_align = big_align.max(field_align);
41364122 const prev_offset = offset;
41374123 offset = field_align.forward(offset);
......@@ -6528,7 +6514,7 @@ pub const FuncGen = struct {
65286514 const struct_ty = self.typeOf(struct_field.struct_operand);
65296515 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
65306516 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);
65326518 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;
65336519
65346520 if (!isByRef(struct_ty, zcu)) {
......@@ -6590,7 +6576,7 @@ pub const FuncGen = struct {
65906576 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
65916577 const field_ptr =
65926578 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);
65946580 const field_ptr_ty = try pt.ptrType(.{
65956581 .child = field_ty.toIntern(),
65966582 .flags = .{ .alignment = alignment },
......@@ -7471,8 +7457,8 @@ pub const FuncGen = struct {
74717457 assert(self.err_ret_trace != .none);
74727458 const field_ptr =
74737459 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");
7474 const field_alignment = struct_ty.structFieldAlign(field_index, zcu);
7475 const field_ty = struct_ty.structFieldType(field_index, zcu);
7460 const field_alignment = struct_ty.fieldAlignment(field_index, zcu);
7461 const field_ty = struct_ty.fieldType(field_index, zcu);
74767462 const field_ptr_ty = try pt.ptrType(.{
74777463 .child = field_ty.toIntern(),
74787464 .flags = .{ .alignment = field_alignment },
......@@ -10080,7 +10066,7 @@ pub const FuncGen = struct {
1008010066 const field_ptr_ty = try pt.ptrType(.{
1008110067 .child = self.typeOf(elem).toIntern(),
1008210068 .flags = .{
10083 .alignment = result_ty.structFieldAlign(i, zcu),
10069 .alignment = result_ty.fieldAlignment(i, zcu),
1008410070 },
1008510071 });
1008610072 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);
......@@ -10185,7 +10171,7 @@ pub const FuncGen = struct {
1018510171 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
1018610172 const field_llvm_ty = try o.lowerType(field_ty);
1018710173 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);
1018910175 const llvm_usize = try o.lowerType(Type.usize);
1019010176 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
1118811174 var types_len: usize = 0;
1118911175 var types: [8]Builder.Type = undefined;
1119011176 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);
1119211178 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
1119311179 types[types_len] = try o.lowerType(field_ty);
1119411180 types_len += 1;
......@@ -11444,7 +11430,7 @@ const ParamTypeIterator = struct {
1144411430 .fields => {
1144511431 it.types_len = 0;
1144611432 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);
1144811434 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
1144911435 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);
1145011436 it.types_len += 1;
src/codegen/spirv.zig+1-1
......@@ -5148,7 +5148,7 @@ const NavGen = struct {
51485148 const object_ty = self.typeOf(struct_field.struct_operand);
51495149 const object_id = try self.resolve(struct_field.struct_operand);
51505150 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
51535153 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;
51545154
src/mutable_value.zig+1-1
......@@ -223,7 +223,7 @@ pub const MutableValue = union(enum) {
223223 @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem });
224224 },
225225 .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();
227227 mut_elem.* = .{ .interned = try pt.intern(.{ .undef = field_ty }) };
228228 },
229229 else => unreachable,