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(...@@ -20912,8 +20912,6 @@ fn reifyUnion(
20912 std.hash.autoHash(&hasher, opt_tag_type_val.toIntern());20912 std.hash.autoHash(&hasher, opt_tag_type_val.toIntern());
20913 std.hash.autoHash(&hasher, fields_len);20913 std.hash.autoHash(&hasher, fields_len);
2091420914
20915 var any_aligns = false;
20916
20917 for (0..fields_len) |field_idx| {20915 for (0..fields_len) |field_idx| {
20918 const field_info = try fields_val.elemValue(pt, field_idx);20916 const field_info = try fields_val.elemValue(pt, field_idx);
2091920917
...@@ -20922,16 +20920,11 @@ fn reifyUnion(...@@ -20922,16 +20920,11 @@ fn reifyUnion(
20922 const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2));20920 const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2));
2092320921
20924 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .union_field_name });20922 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .union_field_name });
20925
20926 std.hash.autoHash(&hasher, .{20923 std.hash.autoHash(&hasher, .{
20927 field_name,20924 field_name,
20928 field_type_val.toIntern(),20925 field_type_val.toIntern(),
20929 field_align_val.toIntern(),20926 field_align_val.toIntern(),
20930 });20927 });
20931
20932 if (field_align_val.toUnsignedInt(zcu) != 0) {
20933 any_aligns = true;
20934 }
20935 }20928 }
2093620929
20937 const tracked_inst = try block.trackZir(inst);20930 const tracked_inst = try block.trackZir(inst);
...@@ -20948,7 +20941,7 @@ fn reifyUnion(...@@ -20948,7 +20941,7 @@ fn reifyUnion(
20948 true => .safety,20941 true => .safety,
20949 false => .none,20942 false => .none,
20950 },20943 },
20951 .any_aligned_fields = any_aligns,20944 .any_aligned_fields = layout != .@"packed",
20952 .requires_comptime = .unknown,20945 .requires_comptime = .unknown,
20953 .assumed_runtime_bits = false,20946 .assumed_runtime_bits = false,
20954 .assumed_pointer_aligned = false,20947 .assumed_pointer_aligned = false,
...@@ -20981,8 +20974,7 @@ fn reifyUnion(...@@ -20981,8 +20974,7 @@ fn reifyUnion(
20981 );20974 );
20982 wip_ty.setName(ip, type_name.name, type_name.nav);20975 wip_ty.setName(ip, type_name.name, type_name.nav);
2098320976
20984 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);20977 const loaded_union = ip.loadUnionType(wip_ty.index);
20985 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;
2098620978
20987 const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(zcu)) |tag_type_val| tag_ty: {20979 const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(zcu)) |tag_type_val| tag_ty: {
20988 switch (ip.indexToKey(tag_type_val.toIntern())) {20980 switch (ip.indexToKey(tag_type_val.toIntern())) {
...@@ -20995,11 +20987,12 @@ fn reifyUnion(...@@ -20995,11 +20987,12 @@ fn reifyUnion(
20995 const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu);20987 const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu);
20996 var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);20988 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| {
20999 const field_info = try fields_val.elemValue(pt, field_idx);20991 const field_info = try fields_val.elemValue(pt, field_idx);
2100020992
21001 const field_name_val = try field_info.fieldValue(pt, 0);20993 const field_name_val = try field_info.fieldValue(pt, 0);
21002 const field_type_val = try field_info.fieldValue(pt, 1);20994 const field_type_val = try field_info.fieldValue(pt, 1);
20995 const field_alignment_val = try field_info.fieldValue(pt, 2);
2100320996
21004 // Don't pass a reason; first loop acts as an assertion that this is valid.20997 // Don't pass a reason; first loop acts as an assertion that this is valid.
21005 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);20998 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
...@@ -21016,10 +21009,12 @@ fn reifyUnion(...@@ -21016,10 +21009,12 @@ fn reifyUnion(
21016 }21009 }
21017 seen_tags.set(enum_index);21010 seen_tags.set(enum_index);
2101821011
21019 field_ty.* = field_type_val.toIntern();21012 loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21020 if (any_aligns) {21013 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21021 const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);21014 if (layout == .@"packed") {
21022 field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align);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);
21023 }21018 }
21024 }21019 }
2102521020
...@@ -21043,11 +21038,12 @@ fn reifyUnion(...@@ -21043,11 +21038,12 @@ fn reifyUnion(
21043 var field_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;21038 var field_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;
21044 try field_names.ensureTotalCapacity(sema.arena, fields_len);21039 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| {
21047 const field_info = try fields_val.elemValue(pt, field_idx);21042 const field_info = try fields_val.elemValue(pt, field_idx);
2104821043
21049 const field_name_val = try field_info.fieldValue(pt, 0);21044 const field_name_val = try field_info.fieldValue(pt, 0);
21050 const field_type_val = try field_info.fieldValue(pt, 1);21045 const field_type_val = try field_info.fieldValue(pt, 1);
21046 const field_alignment_val = try field_info.fieldValue(pt, 2);
2105121047
21052 // Don't pass a reason; first loop acts as an assertion that this is valid.21048 // Don't pass a reason; first loop acts as an assertion that this is valid.
21053 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);21049 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
...@@ -21057,10 +21053,12 @@ fn reifyUnion(...@@ -21057,10 +21053,12 @@ fn reifyUnion(
21057 return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)});21053 return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)});
21058 }21054 }
2105921055
21060 field_ty.* = field_type_val.toIntern();21056 loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21061 if (any_aligns) {21057 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21062 const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);21058 if (layout == .@"packed") {
21063 field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align);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);
21064 }21062 }
21065 }21063 }
2106621064
...@@ -21069,7 +21067,7 @@ fn reifyUnion(...@@ -21069,7 +21067,7 @@ fn reifyUnion(
21069 };21067 };
21070 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error21068 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| {
21073 const field_ty: Type = .fromInterned(field_ty_ip);21071 const field_ty: Type = .fromInterned(field_ty_ip);
21074 if (field_ty.zigTypeTag(zcu) == .@"opaque") {21072 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
21075 return sema.failWithOwnedErrorMsg(block, msg: {21073 return sema.failWithOwnedErrorMsg(block, msg: {
...@@ -21103,11 +21101,6 @@ fn reifyUnion(...@@ -21103,11 +21101,6 @@ fn reifyUnion(
21103 }21101 }
21104 }21102 }
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 }
21111 loaded_union.setTagType(ip, enum_tag_ty);21104 loaded_union.setTagType(ip, enum_tag_ty);
21112 loaded_union.setStatus(ip, .have_field_types);21105 loaded_union.setStatus(ip, .have_field_types);
2111321106
...@@ -21305,7 +21298,7 @@ fn reifyStruct(...@@ -21305,7 +21298,7 @@ fn reifyStruct(
21305 .requires_comptime = .unknown,21298 .requires_comptime = .unknown,
21306 .any_comptime_fields = any_comptime_fields,21299 .any_comptime_fields = any_comptime_fields,
21307 .any_default_inits = any_default_inits,21300 .any_default_inits = any_default_inits,
21308 .any_aligned_fields = true,21301 .any_aligned_fields = layout != .@"packed",
21309 .inits_resolved = true,21302 .inits_resolved = true,
21310 .key = .{ .reified = .{21303 .key = .{ .reified = .{
21311 .zir_index = tracked_inst,21304 .zir_index = tracked_inst,
...@@ -21354,7 +21347,7 @@ fn reifyStruct(...@@ -21354,7 +21347,7 @@ fn reifyStruct(
21354 }21347 }
21355 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);21348 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21356 if (layout == .@"packed") {21349 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", .{});
21358 } else {21351 } else {
21359 struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);21352 struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
21360 }21353 }