authorgravatar for indocomsoft@gmail.comJulius Putra Tanu Setiaji <indocomsoft@gmail.com> 2020-12-26 19:16:53+08:00
committergravatar for indocomsoft@gmail.comJulius Putra Tanu Setiaji <indocomsoft@gmail.com> 2020-12-26 19:43:15+08:00
logf9506e9155d93c14958f9cd559b855a00bf96e11
tree1cef881dc4286d95b67076131488010e9cab2382
parentd9133b9ae056aa70bf6ed83c4d080022127d3397

Handle unions in autoHash


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 {
181181 }
182182 }
183183 }
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 }
184191 return false;
185192 }
186193}
187194
188195/// Provides generic hashing for any eligible type.
189196/// Only hashes `key` itself, pointers are not followed.
190/// Slices and structs containing slices are rejected to avoid ambiguity on the
191/// user's intention.
197/// Slices as well as unions and structs containing slices are rejected to avoid
198/// ambiguity on the user's intention.
192199pub fn autoHash(hasher: anytype, key: anytype) void {
193200 const Key = @TypeOf(key);
194201 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) ++
196203 ") because the intent is unclear. Consider using std.auto_hash.hash or providing your own hash function instead.");
197204 }
198205
lib/std/meta/trait.zig+43
......@@ -530,10 +530,53 @@ test "std.meta.trait.hasUniqueRepresentation" {
530530
531531 testing.expect(hasUniqueRepresentation(TestStruct3));
532532
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
533573 inline for ([_]type{ i0, u8, i16, u32, i64 }) |T| {
534574 testing.expect(hasUniqueRepresentation(T));
535575 }
536576 inline for ([_]type{ i1, u9, i17, u33, i24 }) |T| {
537577 testing.expect(!hasUniqueRepresentation(T));
538578 }
579
580 testing.expect(!hasUniqueRepresentation([]u8));
581 testing.expect(!hasUniqueRepresentation([]const u8));
539582}