authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-06-25 20:38:05+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-06-25 20:38:05+02:00
log56e313b288928e998e186286a2ddc3211c20aa71
treed663d63da0d7e703f750cb93ff13904ada8e412d
parentc4c92b0476c5847c92a1b6c6d709207036c60e34
parent87860e80b4859b54f846ae26c61ae09ad9803322

Merge pull request 'Asserts InternPool keys have unique representations' (#35914) from masonremaley/intern-pool-unique-key-reprs into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35914 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

2 files changed, 38 insertions(+), 3 deletions(-)

lib/std/meta.zig+30
...@@ -909,6 +909,15 @@ pub inline fn hasUniqueRepresentation(comptime T: type) bool {...@@ -909,6 +909,15 @@ pub inline fn hasUniqueRepresentation(comptime T: type) bool {
909 return @sizeOf(T) == sum_size;909 return @sizeOf(T) == sum_size;
910 },910 },
911911
912 .@"union" => |info| {
913 if (info.layout == .@"packed") return @sizeOf(T) * 8 == @bitSizeOf(T);
914 inline for (info.field_types) |field_type| {
915 if (@sizeOf(field_type) != @sizeOf(T)) return false;
916 if (!hasUniqueRepresentation(field_type)) return false;
917 }
918 return true;
919 },
920
912 .vector => |info| hasUniqueRepresentation(info.child) and921 .vector => |info| hasUniqueRepresentation(info.child) and
913 @sizeOf(T) == @sizeOf(info.child) * info.len,922 @sizeOf(T) == @sizeOf(info.child) * info.len,
914 };923 };
...@@ -978,6 +987,27 @@ test hasUniqueRepresentation {...@@ -978,6 +987,27 @@ test hasUniqueRepresentation {
978987
979 try testing.expect(!hasUniqueRepresentation(TestUnion4));988 try testing.expect(!hasUniqueRepresentation(TestUnion4));
980989
990 const TestUnion5 = extern union {
991 a: u32,
992 b: i32,
993 };
994
995 try testing.expect(hasUniqueRepresentation(TestUnion5));
996
997 const TestUnion6 = packed union(u7) {
998 a: u7,
999 b: i7,
1000 };
1001
1002 try testing.expect(!hasUniqueRepresentation(TestUnion6));
1003
1004 const TestUnion7 = packed union(u8) {
1005 a: u8,
1006 b: i8,
1007 };
1008
1009 try testing.expect(hasUniqueRepresentation(TestUnion7));
1010
981 inline for ([_]type{ u8, i16, u32, i64 }) |T| {1011 inline for ([_]type{ u8, i16, u32, i64 }) |T| {
982 try testing.expect(hasUniqueRepresentation(T));1012 try testing.expect(hasUniqueRepresentation(T));
983 try testing.expect(hasUniqueRepresentation(enum(T) { _ }));1013 try testing.expect(hasUniqueRepresentation(enum(T) { _ }));
src/InternPool.zig+8-3
...@@ -2147,9 +2147,11 @@ pub const Key = union(enum) {...@@ -2147,9 +2147,11 @@ pub const Key = union(enum) {
2147 };2147 };
2148 };2148 };
21492149
2150 pub const SpirvType = struct {2150 pub const SpirvType = extern struct {
2151 /// A `spirv_reify` instruction.2151 /// A `spirv_reify` instruction.
2152 zir_index: TrackedInst.Index,2152 zir_index: TrackedInst.Index,
2153 /// Always 0.
2154 padding: u32 = 0,
2153 /// A hash of this type's attributes generated by Sema.2155 /// A hash of this type's attributes generated by Sema.
2154 type_hash: u64,2156 type_hash: u64,
2155 };2157 };
...@@ -2591,7 +2593,6 @@ pub const Key = union(enum) {...@@ -2591,7 +2593,6 @@ pub const Key = union(enum) {
2591 const KeyTag = @typeInfo(Key).@"union".tag_type.?;2593 const KeyTag = @typeInfo(Key).@"union".tag_type.?;
2592 const seed = @intFromEnum(@as(KeyTag, key));2594 const seed = @intFromEnum(@as(KeyTag, key));
2593 return switch (key) {2595 return switch (key) {
2594 // TODO: assert no padding in these types
2595 inline .ptr_type,2596 inline .ptr_type,
2596 .array_type,2597 .array_type,
2597 .vector_type,2598 .vector_type,
...@@ -2608,7 +2609,11 @@ pub const Key = union(enum) {...@@ -2608,7 +2609,11 @@ pub const Key = union(enum) {
2608 .enum_tag,2609 .enum_tag,
2609 .inferred_error_set_type,2610 .inferred_error_set_type,
2610 .un,2611 .un,
2611 => |x| Hash.hash(seed, asBytes(&x)),2612 => |x| {
2613 _ = extern struct { is_extern: @TypeOf(x) };
2614 comptime assert(std.meta.hasUniqueRepresentation(@TypeOf(x)));
2615 return Hash.hash(seed, asBytes(&x));
2616 },
26122617
2613 .int_type => |x| Hash.hash(seed + @intFromEnum(x.signedness), asBytes(&x.bits)),2618 .int_type => |x| Hash.hash(seed + @intFromEnum(x.signedness), asBytes(&x.bits)),
26142619