diff --git a/lib/std/meta.zig b/lib/std/meta.zig index f1e59438ec2e418794230585ee2a3bb019a7aa22..14270ba9d86763f72a5a75eb5f846dee00759954 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -909,6 +909,15 @@ pub inline fn hasUniqueRepresentation(comptime T: type) bool { return @sizeOf(T) == sum_size; }, + .@"union" => |info| { + if (info.layout == .@"packed") return @sizeOf(T) * 8 == @bitSizeOf(T); + inline for (info.field_types) |field_type| { + if (@sizeOf(field_type) != @sizeOf(T)) return false; + if (!hasUniqueRepresentation(field_type)) return false; + } + return true; + }, + .vector => |info| hasUniqueRepresentation(info.child) and @sizeOf(T) == @sizeOf(info.child) * info.len, }; @@ -978,6 +987,27 @@ test hasUniqueRepresentation { try testing.expect(!hasUniqueRepresentation(TestUnion4)); + const TestUnion5 = extern union { + a: u32, + b: i32, + }; + + try testing.expect(hasUniqueRepresentation(TestUnion5)); + + const TestUnion6 = packed union(u7) { + a: u7, + b: i7, + }; + + try testing.expect(!hasUniqueRepresentation(TestUnion6)); + + const TestUnion7 = packed union(u8) { + a: u8, + b: i8, + }; + + try testing.expect(hasUniqueRepresentation(TestUnion7)); + inline for ([_]type{ u8, i16, u32, i64 }) |T| { try testing.expect(hasUniqueRepresentation(T)); try testing.expect(hasUniqueRepresentation(enum(T) { _ })); diff --git a/src/InternPool.zig b/src/InternPool.zig index 9a0aa78e814291caacd7d2e852697f7b37e87586..be6e45441e55ec373e533643786528d0abeb310c 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -2147,9 +2147,11 @@ pub const Key = union(enum) { }; }; - pub const SpirvType = struct { + pub const SpirvType = extern struct { /// A `spirv_reify` instruction. zir_index: TrackedInst.Index, + /// Always 0. + padding: u32 = 0, /// A hash of this type's attributes generated by Sema. type_hash: u64, }; @@ -2591,7 +2593,6 @@ pub const Key = union(enum) { const KeyTag = @typeInfo(Key).@"union".tag_type.?; const seed = @intFromEnum(@as(KeyTag, key)); return switch (key) { - // TODO: assert no padding in these types inline .ptr_type, .array_type, .vector_type, @@ -2608,7 +2609,11 @@ pub const Key = union(enum) { .enum_tag, .inferred_error_set_type, .un, - => |x| Hash.hash(seed, asBytes(&x)), + => |x| { + _ = extern struct { is_extern: @TypeOf(x) }; + comptime assert(std.meta.hasUniqueRepresentation(@TypeOf(x))); + return Hash.hash(seed, asBytes(&x)); + }, .int_type => |x| Hash.hash(seed + @intFromEnum(x.signedness), asBytes(&x.bits)),