| author | |
| committer | |
| log | 56e313b288928e998e186286a2ddc3211c20aa71 |
| tree | d663d63da0d7e703f750cb93ff13904ada8e412d |
| parent | c4c92b0476c5847c92a1b6c6d709207036c60e34 |
| parent | 87860e80b4859b54f846ae26c61ae09ad9803322 |
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 | }, |
| 911 | 911 | ||
| 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) and | 921 | .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 { |
| 978 | 987 | ||
| 979 | try testing.expect(!hasUniqueRepresentation(TestUnion4)); | 988 | try testing.expect(!hasUniqueRepresentation(TestUnion4)); |
| 980 | 989 | ||
| 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 | }; |
| 2149 | 2149 | ||
| 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 | }, | ||
| 2612 | 2617 | ||
| 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)), |
| 2614 | 2619 |