| ... | ... | @@ -565,7 +565,7 @@ pub const Value = extern union { |
| 565 | 565 | .int_u64 => return BigIntMutable.init(&space.limbs, self.cast(Payload.Int_u64).?.int).toConst(), |
| 566 | 566 | .int_i64 => return BigIntMutable.init(&space.limbs, self.cast(Payload.Int_i64).?.int).toConst(), |
| 567 | 567 | .int_big_positive => return self.cast(Payload.IntBigPositive).?.asBigInt(), |
| 568 | | .int_big_negative => return self.cast(Payload.IntBigPositive).?.asBigInt(), |
| 568 | .int_big_negative => return self.cast(Payload.IntBigNegative).?.asBigInt(), |
| 569 | 569 | } |
| 570 | 570 | } |
| 571 | 571 | |
| ... | ... | @@ -1255,7 +1255,6 @@ pub const Value = extern union { |
| 1255 | 1255 | |
| 1256 | 1256 | pub fn hash(self: Value) u64 { |
| 1257 | 1257 | var hasher = std.hash.Wyhash.init(0); |
| 1258 | | std.hash.autoHash(&hasher, self.tag()); |
| 1259 | 1258 | |
| 1260 | 1259 | switch (self.tag()) { |
| 1261 | 1260 | .u8_type, |
| ... | ... | @@ -1321,18 +1320,19 @@ pub const Value = extern union { |
| 1321 | 1320 | } |
| 1322 | 1321 | }, |
| 1323 | 1322 | |
| 1324 | | .undef, |
| 1325 | | .zero, |
| 1326 | | .one, |
| 1327 | | .void_value, |
| 1328 | | .unreachable_value, |
| 1329 | 1323 | .empty_struct_value, |
| 1330 | 1324 | .empty_array, |
| 1331 | | .null_value, |
| 1332 | | .bool_true, |
| 1333 | | .bool_false, |
| 1334 | 1325 | => {}, |
| 1335 | 1326 | |
| 1327 | .undef, |
| 1328 | .null_value, |
| 1329 | .void_value, |
| 1330 | .unreachable_value, |
| 1331 | => std.hash.autoHash(&hasher, self.tag()), |
| 1332 | |
| 1333 | .zero, .bool_false => std.hash.autoHash(&hasher, @as(u64, 0)), |
| 1334 | .one, .bool_true => std.hash.autoHash(&hasher, @as(u64, 1)), |
| 1335 | |
| 1336 | 1336 | .float_16, .float_32, .float_64, .float_128 => {}, |
| 1337 | 1337 | .enum_literal, .bytes => { |
| 1338 | 1338 | const payload = @fieldParentPtr(Payload.Bytes, "base", self.ptr_otherwise); |
| ... | ... | @@ -1357,9 +1357,18 @@ pub const Value = extern union { |
| 1357 | 1357 | .int_big_positive, .int_big_negative => { |
| 1358 | 1358 | var space: BigIntSpace = undefined; |
| 1359 | 1359 | const big = self.toBigInt(&space); |
| 1360 | | std.hash.autoHash(&hasher, big.positive); |
| 1361 | | for (big.limbs) |limb| { |
| 1362 | | std.hash.autoHash(&hasher, limb); |
| 1360 | if (big.limbs.len == 1) { |
| 1361 | // handle like {u,i}64 to ensure same hash as with Int{i,u}64 |
| 1362 | if (big.positive) { |
| 1363 | std.hash.autoHash(&hasher, @as(u64, big.limbs[0])); |
| 1364 | } else { |
| 1365 | std.hash.autoHash(&hasher, @as(u64, @bitCast(usize, -@bitCast(isize, big.limbs[0])))); |
| 1366 | } |
| 1367 | } else { |
| 1368 | std.hash.autoHash(&hasher, big.positive); |
| 1369 | for (big.limbs) |limb| { |
| 1370 | std.hash.autoHash(&hasher, limb); |
| 1371 | } |
| 1363 | 1372 | } |
| 1364 | 1373 | }, |
| 1365 | 1374 | .elem_ptr => { |
| ... | ... | @@ -1741,7 +1750,7 @@ pub const Value = extern union { |
| 1741 | 1750 | .@"error", |
| 1742 | 1751 | .empty_struct_value, |
| 1743 | 1752 | .null_value, |
| 1744 | | => false, |
| 1753 | => false, |
| 1745 | 1754 | |
| 1746 | 1755 | .undef => unreachable, |
| 1747 | 1756 | .unreachable_value => unreachable, |
| ... | ... | @@ -1882,3 +1891,18 @@ pub const Value = extern union { |
| 1882 | 1891 | limbs: [(@sizeOf(u64) / @sizeOf(std.math.big.Limb)) + 1]std.math.big.Limb, |
| 1883 | 1892 | }; |
| 1884 | 1893 | }; |
| 1894 | |
| 1895 | test "hash same value different representation" { |
| 1896 | const zero_1 = Value.initTag(.zero); |
| 1897 | var payload_1 = Value.Payload.Int_u64{ .int = 0 }; |
| 1898 | const zero_2 = Value.initPayload(&payload_1.base); |
| 1899 | std.testing.expectEqual(zero_1.hash(), zero_2.hash()); |
| 1900 | |
| 1901 | var payload_2 = Value.Payload.Int_i64{ .int = 0 }; |
| 1902 | const zero_3 = Value.initPayload(&payload_2.base); |
| 1903 | std.testing.expectEqual(zero_2.hash(), zero_3.hash()); |
| 1904 | |
| 1905 | var payload_3 = Value.Payload.IntBigNegative{ .limbs = &[_]std.math.big.Limb{0} }; |
| 1906 | const zero_4 = Value.initPayload(&payload_3.base); |
| 1907 | std.testing.expectEqual(zero_3.hash(), zero_4.hash()); |
| 1908 | } |