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 {...@@ -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}
187194
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 the197/// Slices as well as unions and structs containing slices are rejected to avoid
191/// user's intention.198/// ambiguity on the user's intention.
192pub fn autoHash(hasher: anytype, key: anytype) void {199pub 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 }
198205
lib/std/meta/trait.zig+43
...@@ -530,10 +530,53 @@ test "std.meta.trait.hasUniqueRepresentation" {...@@ -530,10 +530,53 @@ test "std.meta.trait.hasUniqueRepresentation" {
530530
531 testing.expect(hasUniqueRepresentation(TestStruct3));531 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
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}