authorgravatar for sahnvour@pm.meSahnvour <sahnvour@pm.me> 2020-07-26 22:04:10+02:00
committergravatar for sahnvour@pm.meSahnvour <sahnvour@pm.me> 2020-07-26 22:04:10+02:00
log345cb3200c353d6fb7aeb0e058986d8ca59ced1e
treeca458b60eb26e7ec73f29cc592fb579ff2c602a6
parent7ae1b3a6b348a24f07bacb6e19f1aa6d7b3ba32d

improve autoHash type switch

floats shouldn't be autoHash'd as they have multiple representations for some values, preventing it by default is safer

1 files changed, 9 insertions(+), 11 deletions(-)

lib/std/hash/auto_hash.zig+9-11
...@@ -81,24 +81,22 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {...@@ -81,24 +81,22 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
81 .Undefined,81 .Undefined,
82 .Void,82 .Void,
83 .Null,83 .Null,
84 .BoundFn,
85 .ComptimeFloat,84 .ComptimeFloat,
86 .ComptimeInt,85 .ComptimeInt,
87 .Type,86 .Type,
88 .EnumLiteral,87 .EnumLiteral,
89 .Frame,88 .Frame,
89 .Float,
90 => @compileError("cannot hash this type"),90 => @compileError("cannot hash this type"),
9191
92 // Help the optimizer see that hashing an int is easy by inlining!92 // Help the optimizer see that hashing an int is easy by inlining!
93 // TODO Check if the situation is better after #561 is resolved.93 // TODO Check if the situation is better after #561 is resolved.
94 .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}),94 .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}),
9595
96 .Float => |info| hash(hasher, @bitCast(std.meta.Int(false, info.bits), key), strat),
97
98 .Bool => hash(hasher, @boolToInt(key), strat),96 .Bool => hash(hasher, @boolToInt(key), strat),
99 .Enum => hash(hasher, @enumToInt(key), strat),97 .Enum => hash(hasher, @enumToInt(key), strat),
100 .ErrorSet => hash(hasher, @errorToInt(key), strat),98 .ErrorSet => hash(hasher, @errorToInt(key), strat),
101 .AnyFrame, .Fn => hash(hasher, @ptrToInt(key), strat),99 .AnyFrame, .BoundFn, .Fn => hash(hasher, @ptrToInt(key), strat),
102100
103 .Pointer => @call(.{ .modifier = .always_inline }, hashPointer, .{ hasher, key, strat }),101 .Pointer => @call(.{ .modifier = .always_inline }, hashPointer, .{ hasher, key, strat }),
104102
...@@ -266,12 +264,12 @@ test "hash slice deep" {...@@ -266,12 +264,12 @@ test "hash slice deep" {
266test "hash struct deep" {264test "hash struct deep" {
267 const Foo = struct {265 const Foo = struct {
268 a: u32,266 a: u32,
269 b: f64,267 b: u16,
270 c: *bool,268 c: *bool,
271269
272 const Self = @This();270 const Self = @This();
273271
274 pub fn init(allocator: *mem.Allocator, a_: u32, b_: f64, c_: bool) !Self {272 pub fn init(allocator: *mem.Allocator, a_: u32, b_: u16, c_: bool) !Self {
275 const ptr = try allocator.create(bool);273 const ptr = try allocator.create(bool);
276 ptr.* = c_;274 ptr.* = c_;
277 return Self{ .a = a_, .b = b_, .c = ptr };275 return Self{ .a = a_, .b = b_, .c = ptr };
...@@ -279,9 +277,9 @@ test "hash struct deep" {...@@ -279,9 +277,9 @@ test "hash struct deep" {
279 };277 };
280278
281 const allocator = std.testing.allocator;279 const allocator = std.testing.allocator;
282 const foo = try Foo.init(allocator, 123, 1.0, true);280 const foo = try Foo.init(allocator, 123, 10, true);
283 const bar = try Foo.init(allocator, 123, 1.0, true);281 const bar = try Foo.init(allocator, 123, 10, true);
284 const baz = try Foo.init(allocator, 123, 1.0, false);282 const baz = try Foo.init(allocator, 123, 10, false);
285 defer allocator.destroy(foo.c);283 defer allocator.destroy(foo.c);
286 defer allocator.destroy(bar.c);284 defer allocator.destroy(bar.c);
287 defer allocator.destroy(baz.c);285 defer allocator.destroy(baz.c);
...@@ -338,12 +336,12 @@ test "testHash struct" {...@@ -338,12 +336,12 @@ test "testHash struct" {
338test "testHash union" {336test "testHash union" {
339 const Foo = union(enum) {337 const Foo = union(enum) {
340 A: u32,338 A: u32,
341 B: f32,339 B: bool,
342 C: u32,340 C: u32,
343 };341 };
344342
345 const a = Foo{ .A = 18 };343 const a = Foo{ .A = 18 };
346 var b = Foo{ .B = 12.34 };344 var b = Foo{ .B = true };
347 const c = Foo{ .C = 18 };345 const c = Foo{ .C = 18 };
348 testing.expect(testHash(a) == testHash(a));346 testing.expect(testHash(a) == testHash(a));
349 testing.expect(testHash(a) != testHash(b));347 testing.expect(testHash(a) != testHash(b));