authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2025-08-01 12:00:34-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2025-08-01 14:57:16-07:00
log5678a600ffb2ec27f88ab6a308b4eaf56c60daed
tree13241a978bbfaa8e59b7879da57c87633dfcb6fa
parentd6c74a95fdaba4ed373f80baa725dcc53b27e402
signaturelock-open Commit is signed but in an unrecognized format.

refactor `reifyUnion` alignment handling


1 files changed, 21 insertions(+), 28 deletions(-)

src/Sema.zig+21-28
......@@ -20912,8 +20912,6 @@ fn reifyUnion(
2091220912 std.hash.autoHash(&hasher, opt_tag_type_val.toIntern());
2091320913 std.hash.autoHash(&hasher, fields_len);
2091420914
20915 var any_aligns = false;
20916
2091720915 for (0..fields_len) |field_idx| {
2091820916 const field_info = try fields_val.elemValue(pt, field_idx);
2091920917
......@@ -20922,16 +20920,11 @@ fn reifyUnion(
2092220920 const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2));
2092320921
2092420922 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .union_field_name });
20925
2092620923 std.hash.autoHash(&hasher, .{
2092720924 field_name,
2092820925 field_type_val.toIntern(),
2092920926 field_align_val.toIntern(),
2093020927 });
20931
20932 if (field_align_val.toUnsignedInt(zcu) != 0) {
20933 any_aligns = true;
20934 }
2093520928 }
2093620929
2093720930 const tracked_inst = try block.trackZir(inst);
......@@ -20948,7 +20941,7 @@ fn reifyUnion(
2094820941 true => .safety,
2094920942 false => .none,
2095020943 },
20951 .any_aligned_fields = any_aligns,
20944 .any_aligned_fields = layout != .@"packed",
2095220945 .requires_comptime = .unknown,
2095320946 .assumed_runtime_bits = false,
2095420947 .assumed_pointer_aligned = false,
......@@ -20981,8 +20974,7 @@ fn reifyUnion(
2098120974 );
2098220975 wip_ty.setName(ip, type_name.name, type_name.nav);
2098320976
20984 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);
20985 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;
20977 const loaded_union = ip.loadUnionType(wip_ty.index);
2098620978
2098720979 const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(zcu)) |tag_type_val| tag_ty: {
2098820980 switch (ip.indexToKey(tag_type_val.toIntern())) {
......@@ -20995,11 +20987,12 @@ fn reifyUnion(
2099520987 const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu);
2099620988 var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);
2099720989
20998 for (field_types, 0..) |*field_ty, field_idx| {
20990 for (0..fields_len) |field_idx| {
2099920991 const field_info = try fields_val.elemValue(pt, field_idx);
2100020992
2100120993 const field_name_val = try field_info.fieldValue(pt, 0);
2100220994 const field_type_val = try field_info.fieldValue(pt, 1);
20995 const field_alignment_val = try field_info.fieldValue(pt, 2);
2100320996
2100420997 // Don't pass a reason; first loop acts as an assertion that this is valid.
2100520998 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
......@@ -21016,10 +21009,12 @@ fn reifyUnion(
2101621009 }
2101721010 seen_tags.set(enum_index);
2101821011
21019 field_ty.* = field_type_val.toIntern();
21020 if (any_aligns) {
21021 const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
21022 field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align);
21012 loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21013 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21014 if (layout == .@"packed") {
21015 if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{});
21016 } else {
21017 loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
2102321018 }
2102421019 }
2102521020
......@@ -21043,11 +21038,12 @@ fn reifyUnion(
2104321038 var field_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;
2104421039 try field_names.ensureTotalCapacity(sema.arena, fields_len);
2104521040
21046 for (field_types, 0..) |*field_ty, field_idx| {
21041 for (0..fields_len) |field_idx| {
2104721042 const field_info = try fields_val.elemValue(pt, field_idx);
2104821043
2104921044 const field_name_val = try field_info.fieldValue(pt, 0);
2105021045 const field_type_val = try field_info.fieldValue(pt, 1);
21046 const field_alignment_val = try field_info.fieldValue(pt, 2);
2105121047
2105221048 // Don't pass a reason; first loop acts as an assertion that this is valid.
2105321049 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
......@@ -21057,10 +21053,12 @@ fn reifyUnion(
2105721053 return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)});
2105821054 }
2105921055
21060 field_ty.* = field_type_val.toIntern();
21061 if (any_aligns) {
21062 const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
21063 field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align);
21056 loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21057 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21058 if (layout == .@"packed") {
21059 if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{});
21060 } else {
21061 loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
2106421062 }
2106521063 }
2106621064
......@@ -21069,7 +21067,7 @@ fn reifyUnion(
2106921067 };
2107021068 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
2107121069
21072 for (field_types) |field_ty_ip| {
21070 for (loaded_union.field_types.get(ip)) |field_ty_ip| {
2107321071 const field_ty: Type = .fromInterned(field_ty_ip);
2107421072 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
2107521073 return sema.failWithOwnedErrorMsg(block, msg: {
......@@ -21103,11 +21101,6 @@ fn reifyUnion(
2110321101 }
2110421102 }
2110521103
21106 const loaded_union = ip.loadUnionType(wip_ty.index);
21107 loaded_union.setFieldTypes(ip, field_types);
21108 if (any_aligns) {
21109 loaded_union.setFieldAligns(ip, field_aligns);
21110 }
2111121104 loaded_union.setTagType(ip, enum_tag_ty);
2111221105 loaded_union.setStatus(ip, .have_field_types);
2111321106
......@@ -21305,7 +21298,7 @@ fn reifyStruct(
2130521298 .requires_comptime = .unknown,
2130621299 .any_comptime_fields = any_comptime_fields,
2130721300 .any_default_inits = any_default_inits,
21308 .any_aligned_fields = true,
21301 .any_aligned_fields = layout != .@"packed",
2130921302 .inits_resolved = true,
2131021303 .key = .{ .reified = .{
2131121304 .zir_index = tracked_inst,
......@@ -21354,7 +21347,7 @@ fn reifyStruct(
2135421347 }
2135521348 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
2135621349 if (layout == .@"packed") {
21357 if (byte_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
21350 if (byte_align != 0) return sema.fail(block, src, "alignment of a packed struct field must be set to 0", .{});
2135821351 } else {
2135921352 struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
2136021353 }