authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-12-24 00:25:52+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-12-24 00:25:52+02:00
log71548824237174aa5310c339c3161eae1623cf73
treee92380c894d1ac5787919207da2a3a5fd37e3ec6
parent6e2622661cdf9dd48cf962e5d6902324b15468c3
parent135f4791e5cbffc75f51d404ef1abb6aca5de0e3
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7447 from LemonBoy/fix-7445

std: non-byte-multiple sized integers have no definite representation

2 files changed, 22 insertions(+), 13 deletions(-)

lib/std/hash/auto_hash.zig+10-1
......@@ -99,7 +99,16 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
9999
100100 // Help the optimizer see that hashing an int is easy by inlining!
101101 // TODO Check if the situation is better after #561 is resolved.
102 .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}),
102 .Int => {
103 if (comptime meta.trait.hasUniqueRepresentation(Key)) {
104 @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)});
105 } else {
106 // Take only the part containing the key value, the remaining
107 // bytes are undefined and must not be hashed!
108 const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable;
109 @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)[0..byte_size]});
110 }
111 },
103112
104113 .Bool => hash(hasher, @boolToInt(key), strat),
105114 .Enum => hash(hasher, @enumToInt(key), strat),
lib/std/meta/trait.zig+12-12
......@@ -476,15 +476,19 @@ pub fn hasUniqueRepresentation(comptime T: type) bool {
476476 else => return false, // TODO can we know if it's true for some of these types ?
477477
478478 .AnyFrame,
479 .Bool,
480479 .BoundFn,
481480 .Enum,
482481 .ErrorSet,
483482 .Fn,
484 .Int, // TODO check that it is still true
485483 .Pointer,
486484 => return true,
487485
486 .Bool => return false,
487
488 // The padding bits are undefined.
489 .Int => |info| return (info.bits % 8) == 0 and
490 (info.bits == 0 or std.math.isPowerOfTwo(info.bits)),
491
488492 .Array => |info| return comptime hasUniqueRepresentation(info.child),
489493
490494 .Struct => |info| {
......@@ -525,14 +529,10 @@ test "std.meta.trait.hasUniqueRepresentation" {
525529
526530 testing.expect(hasUniqueRepresentation(TestStruct3));
527531
528 testing.expect(hasUniqueRepresentation(i1));
529 testing.expect(hasUniqueRepresentation(u2));
530 testing.expect(hasUniqueRepresentation(i3));
531 testing.expect(hasUniqueRepresentation(u4));
532 testing.expect(hasUniqueRepresentation(i5));
533 testing.expect(hasUniqueRepresentation(u6));
534 testing.expect(hasUniqueRepresentation(i7));
535 testing.expect(hasUniqueRepresentation(u8));
536 testing.expect(hasUniqueRepresentation(i9));
537 testing.expect(hasUniqueRepresentation(u10));
532 inline for ([_]type{ i0, u8, i16, u32, i64 }) |T| {
533 testing.expect(hasUniqueRepresentation(T));
534 }
535 inline for ([_]type{ i1, u9, i17, u33, i24 }) |T| {
536 testing.expect(!hasUniqueRepresentation(T));
537 }
538538}