diff --git a/src/Sema.zig b/src/Sema.zig index 3bee1130af..8ea0a19fe8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -20912,8 +20912,6 @@ fn reifyUnion( std.hash.autoHash(&hasher, opt_tag_type_val.toIntern()); std.hash.autoHash(&hasher, fields_len); - var any_aligns = false; - for (0..fields_len) |field_idx| { const field_info = try fields_val.elemValue(pt, field_idx); @@ -20922,16 +20920,11 @@ fn reifyUnion( const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2)); const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .union_field_name }); - std.hash.autoHash(&hasher, .{ field_name, field_type_val.toIntern(), field_align_val.toIntern(), }); - - if (field_align_val.toUnsignedInt(zcu) != 0) { - any_aligns = true; - } } const tracked_inst = try block.trackZir(inst); @@ -20948,7 +20941,7 @@ fn reifyUnion( true => .safety, false => .none, }, - .any_aligned_fields = any_aligns, + .any_aligned_fields = layout != .@"packed", .requires_comptime = .unknown, .assumed_runtime_bits = false, .assumed_pointer_aligned = false, @@ -20981,8 +20974,7 @@ fn reifyUnion( ); wip_ty.setName(ip, type_name.name, type_name.nav); - const field_types = try sema.arena.alloc(InternPool.Index, fields_len); - const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined; + const loaded_union = ip.loadUnionType(wip_ty.index); const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(zcu)) |tag_type_val| tag_ty: { switch (ip.indexToKey(tag_type_val.toIntern())) { @@ -20995,11 +20987,12 @@ fn reifyUnion( const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu); var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len); - for (field_types, 0..) |*field_ty, field_idx| { + for (0..fields_len) |field_idx| { const field_info = try fields_val.elemValue(pt, field_idx); const field_name_val = try field_info.fieldValue(pt, 0); const field_type_val = try field_info.fieldValue(pt, 1); + const field_alignment_val = try field_info.fieldValue(pt, 2); // Don't pass a reason; first loop acts as an assertion that this is valid. const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); @@ -21016,10 +21009,12 @@ fn reifyUnion( } seen_tags.set(enum_index); - field_ty.* = field_type_val.toIntern(); - if (any_aligns) { - const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); - field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align); + loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern(); + const byte_align = try field_alignment_val.toUnsignedIntSema(pt); + if (layout == .@"packed") { + if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{}); + } else { + loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align); } } @@ -21043,11 +21038,12 @@ fn reifyUnion( var field_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty; try field_names.ensureTotalCapacity(sema.arena, fields_len); - for (field_types, 0..) |*field_ty, field_idx| { + for (0..fields_len) |field_idx| { const field_info = try fields_val.elemValue(pt, field_idx); const field_name_val = try field_info.fieldValue(pt, 0); const field_type_val = try field_info.fieldValue(pt, 1); + const field_alignment_val = try field_info.fieldValue(pt, 2); // Don't pass a reason; first loop acts as an assertion that this is valid. const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); @@ -21057,10 +21053,12 @@ fn reifyUnion( return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)}); } - field_ty.* = field_type_val.toIntern(); - if (any_aligns) { - const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); - field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align); + loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern(); + const byte_align = try field_alignment_val.toUnsignedIntSema(pt); + if (layout == .@"packed") { + if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{}); + } else { + loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align); } } @@ -21069,7 +21067,7 @@ fn reifyUnion( }; errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error - for (field_types) |field_ty_ip| { + for (loaded_union.field_types.get(ip)) |field_ty_ip| { const field_ty: Type = .fromInterned(field_ty_ip); if (field_ty.zigTypeTag(zcu) == .@"opaque") { return sema.failWithOwnedErrorMsg(block, msg: { @@ -21103,11 +21101,6 @@ fn reifyUnion( } } - const loaded_union = ip.loadUnionType(wip_ty.index); - loaded_union.setFieldTypes(ip, field_types); - if (any_aligns) { - loaded_union.setFieldAligns(ip, field_aligns); - } loaded_union.setTagType(ip, enum_tag_ty); loaded_union.setStatus(ip, .have_field_types); @@ -21305,7 +21298,7 @@ fn reifyStruct( .requires_comptime = .unknown, .any_comptime_fields = any_comptime_fields, .any_default_inits = any_default_inits, - .any_aligned_fields = true, + .any_aligned_fields = layout != .@"packed", .inits_resolved = true, .key = .{ .reified = .{ .zir_index = tracked_inst, @@ -21354,7 +21347,7 @@ fn reifyStruct( } const byte_align = try field_alignment_val.toUnsignedIntSema(pt); if (layout == .@"packed") { - if (byte_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{}); + if (byte_align != 0) return sema.fail(block, src, "alignment of a packed struct field must be set to 0", .{}); } else { struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align); }