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 {
909909 return @sizeOf(T) == sum_size;
910910 },
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
912921 .vector => |info| hasUniqueRepresentation(info.child) and
913922 @sizeOf(T) == @sizeOf(info.child) * info.len,
914923 };
......@@ -978,6 +987,27 @@ test hasUniqueRepresentation {
978987
979988 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
9811011 inline for ([_]type{ u8, i16, u32, i64 }) |T| {
9821012 try testing.expect(hasUniqueRepresentation(T));
9831013 try testing.expect(hasUniqueRepresentation(enum(T) { _ }));
src/InternPool.zig+8-3
......@@ -2147,9 +2147,11 @@ pub const Key = union(enum) {
21472147 };
21482148 };
21492149
2150 pub const SpirvType = struct {
2150 pub const SpirvType = extern struct {
21512151 /// A `spirv_reify` instruction.
21522152 zir_index: TrackedInst.Index,
2153 /// Always 0.
2154 padding: u32 = 0,
21532155 /// A hash of this type's attributes generated by Sema.
21542156 type_hash: u64,
21552157 };
......@@ -2591,7 +2593,6 @@ pub const Key = union(enum) {
25912593 const KeyTag = @typeInfo(Key).@"union".tag_type.?;
25922594 const seed = @intFromEnum(@as(KeyTag, key));
25932595 return switch (key) {
2594 // TODO: assert no padding in these types
25952596 inline .ptr_type,
25962597 .array_type,
25972598 .vector_type,
......@@ -2608,7 +2609,11 @@ pub const Key = union(enum) {
26082609 .enum_tag,
26092610 .inferred_error_set_type,
26102611 .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
26132618 .int_type => |x| Hash.hash(seed + @intFromEnum(x.signedness), asBytes(&x.bits)),
26142619