| author | |
| committer | |
| log | f9506e9155d93c14958f9cd559b855a00bf96e11 |
| tree | 1cef881dc4286d95b67076131488010e9cab2382 |
| parent | d9133b9ae056aa70bf6ed83c4d080022127d3397 |
2 files changed, 53 insertions(+), 3 deletions(-)
lib/std/hash/auto_hash.zig+10-3| ... | @@ -181,18 +181,25 @@ fn typeContainsSlice(comptime K: type) bool { | ... | @@ -181,18 +181,25 @@ fn typeContainsSlice(comptime K: type) bool { |
| 181 | } | 181 | } |
| 182 | } | 182 | } |
| 183 | } | 183 | } |
| 184 | if (meta.trait.is(.Union)(K)) { | ||
| 185 | inline for (@typeInfo(K).Union.fields) |field| { | ||
| 186 | if (typeContainsSlice(field.field_type)) { | ||
| 187 | return true; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | } | ||
| 184 | return false; | 191 | return false; |
| 185 | } | 192 | } |
| 186 | } | 193 | } |
| 187 | 194 | ||
| 188 | /// Provides generic hashing for any eligible type. | 195 | /// Provides generic hashing for any eligible type. |
| 189 | /// Only hashes `key` itself, pointers are not followed. | 196 | /// Only hashes `key` itself, pointers are not followed. |
| 190 | /// Slices and structs containing slices are rejected to avoid ambiguity on the | 197 | /// Slices as well as unions and structs containing slices are rejected to avoid |
| 191 | /// user's intention. | 198 | /// ambiguity on the user's intention. |
| 192 | pub fn autoHash(hasher: anytype, key: anytype) void { | 199 | pub fn autoHash(hasher: anytype, key: anytype) void { |
| 193 | const Key = @TypeOf(key); | 200 | const Key = @TypeOf(key); |
| 194 | if (comptime typeContainsSlice(Key)) { | 201 | if (comptime typeContainsSlice(Key)) { |
| 195 | @compileError("std.auto_hash.autoHash does not allow slices or structs containing slices here (" ++ @typeName(Key) ++ | 202 | @compileError("std.auto_hash.autoHash does not allow slices as well as unions and structs containing slices here (" ++ @typeName(Key) ++ |
| 196 | ") because the intent is unclear. Consider using std.auto_hash.hash or providing your own hash function instead."); | 203 | ") because the intent is unclear. Consider using std.auto_hash.hash or providing your own hash function instead."); |
| 197 | } | 204 | } |
| 198 | 205 |
lib/std/meta/trait.zig+43| ... | @@ -530,10 +530,53 @@ test "std.meta.trait.hasUniqueRepresentation" { | ... | @@ -530,10 +530,53 @@ test "std.meta.trait.hasUniqueRepresentation" { |
| 530 | 530 | ||
| 531 | testing.expect(hasUniqueRepresentation(TestStruct3)); | 531 | testing.expect(hasUniqueRepresentation(TestStruct3)); |
| 532 | 532 | ||
| 533 | const TestStruct4 = struct { | ||
| 534 | a: []const u8 | ||
| 535 | }; | ||
| 536 | |||
| 537 | testing.expect(!hasUniqueRepresentation(TestStruct4)); | ||
| 538 | |||
| 539 | const TestStruct5 = struct { | ||
| 540 | a: TestStruct4 | ||
| 541 | }; | ||
| 542 | |||
| 543 | testing.expect(!hasUniqueRepresentation(TestStruct5)); | ||
| 544 | |||
| 545 | const TestUnion1 = packed union { | ||
| 546 | a: u32, | ||
| 547 | b: u16, | ||
| 548 | }; | ||
| 549 | |||
| 550 | testing.expect(!hasUniqueRepresentation(TestUnion1)); | ||
| 551 | |||
| 552 | const TestUnion2 = extern union { | ||
| 553 | a: u32, | ||
| 554 | b: u16, | ||
| 555 | }; | ||
| 556 | |||
| 557 | testing.expect(!hasUniqueRepresentation(TestUnion2)); | ||
| 558 | |||
| 559 | const TestUnion3 = union { | ||
| 560 | a: u32, | ||
| 561 | b: u16, | ||
| 562 | }; | ||
| 563 | |||
| 564 | testing.expect(!hasUniqueRepresentation(TestUnion3)); | ||
| 565 | |||
| 566 | const TestUnion4 = union(enum) { | ||
| 567 | a: u32, | ||
| 568 | b: u16, | ||
| 569 | }; | ||
| 570 | |||
| 571 | testing.expect(!hasUniqueRepresentation(TestUnion4)); | ||
| 572 | |||
| 533 | inline for ([_]type{ i0, u8, i16, u32, i64 }) |T| { | 573 | inline for ([_]type{ i0, u8, i16, u32, i64 }) |T| { |
| 534 | testing.expect(hasUniqueRepresentation(T)); | 574 | testing.expect(hasUniqueRepresentation(T)); |
| 535 | } | 575 | } |
| 536 | inline for ([_]type{ i1, u9, i17, u33, i24 }) |T| { | 576 | inline for ([_]type{ i1, u9, i17, u33, i24 }) |T| { |
| 537 | testing.expect(!hasUniqueRepresentation(T)); | 577 | testing.expect(!hasUniqueRepresentation(T)); |
| 538 | } | 578 | } |
| 579 | |||
| 580 | testing.expect(!hasUniqueRepresentation([]u8)); | ||
| 581 | testing.expect(!hasUniqueRepresentation([]const u8)); | ||
| 539 | } | 582 | } |