Skip to content

Commit

Permalink
Merge pull request #7447 from LemonBoy/fix-7445
Browse files Browse the repository at this point in the history
std: non-byte-multiple sized integers have no definite representation
  • Loading branch information
Vexu committed Dec 23, 2020
2 parents 6e26226 + 135f479 commit 7154882
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
11 changes: 10 additions & 1 deletion lib/std/hash/auto_hash.zig
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,16 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {

// Help the optimizer see that hashing an int is easy by inlining!
// TODO Check if the situation is better after #561 is resolved.
.Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}),
.Int => {
if (comptime meta.trait.hasUniqueRepresentation(Key)) {
@call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)});
} else {
// Take only the part containing the key value, the remaining
// bytes are undefined and must not be hashed!
const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable;
@call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)[0..byte_size]});
}
},

.Bool => hash(hasher, @boolToInt(key), strat),
.Enum => hash(hasher, @enumToInt(key), strat),
Expand Down
24 changes: 12 additions & 12 deletions lib/std/meta/trait.zig
Original file line number Diff line number Diff line change
Expand Up @@ -476,15 +476,19 @@ pub fn hasUniqueRepresentation(comptime T: type) bool {
else => return false, // TODO can we know if it's true for some of these types ?

.AnyFrame,
.Bool,
.BoundFn,
.Enum,
.ErrorSet,
.Fn,
.Int, // TODO check that it is still true
.Pointer,
=> return true,

.Bool => return false,

// The padding bits are undefined.
.Int => |info| return (info.bits % 8) == 0 and
(info.bits == 0 or std.math.isPowerOfTwo(info.bits)),

.Array => |info| return comptime hasUniqueRepresentation(info.child),

.Struct => |info| {
Expand Down Expand Up @@ -525,14 +529,10 @@ test "std.meta.trait.hasUniqueRepresentation" {

testing.expect(hasUniqueRepresentation(TestStruct3));

testing.expect(hasUniqueRepresentation(i1));
testing.expect(hasUniqueRepresentation(u2));
testing.expect(hasUniqueRepresentation(i3));
testing.expect(hasUniqueRepresentation(u4));
testing.expect(hasUniqueRepresentation(i5));
testing.expect(hasUniqueRepresentation(u6));
testing.expect(hasUniqueRepresentation(i7));
testing.expect(hasUniqueRepresentation(u8));
testing.expect(hasUniqueRepresentation(i9));
testing.expect(hasUniqueRepresentation(u10));
inline for ([_]type{ i0, u8, i16, u32, i64 }) |T| {
testing.expect(hasUniqueRepresentation(T));
}
inline for ([_]type{ i1, u9, i17, u33, i24 }) |T| {
testing.expect(!hasUniqueRepresentation(T));
}
}

0 comments on commit 7154882

Please sign in to comment.