def hash object_id.hash * 32 + args.hash end # ... def hash @registry_name.hash * 32 * 32 + @name.hash * 32 + @object_id.hash end
These are crashing with
OverflowError: Arithmetic overflow:
Error: Arithmetic overflow OverflowError: Arithmetic overflow lib/mocks/src/mocks/registry.cr:86:60 in 'hash' /usr/local/Cellar/crystal/0.31.1/src/hash.cr:893:12 in 'key_hash' /usr/local/Cellar/crystal/0.31.1/src/hash.cr:336:5 in 'upsert' /usr/local/Cellar/crystal/0.31.1/src/hash.cr:912:5 in '=' lib/mocks/src/mocks/registry.cr:104:9 in 'add' lib/mocks/src/mocks/registry.cr:156:9 in 'store_stub' ...
Is there any way I can tell the compiler that I don’t care about overflows, since this is a hashing algorithm where the final result just needs to be unique?
In the meantime, I’ve been able to fix these hash methods with some bit shifts (and sent a PR), to make sure it never overflows a UInt64:
def hash (object_id.hash >> 2) + (args.hash >> 2) end # ... def hash (@registry_name.hash >> 3) + (@name.hash >> 3) + (@object_id.hash >> 3) end
Is there a better way to fix this issue?