Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ghc-hashable for openSUSE:Factory checked in at 2023-08-06 16:29:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-hashable (Old) and /work/SRC/openSUSE:Factory/.ghc-hashable.new.22712 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-hashable" Sun Aug 6 16:29:43 2023 rev:34 rq:1102507 version:1.4.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-hashable/ghc-hashable.changes 2023-04-04 21:20:29.877220066 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-hashable.new.22712/ghc-hashable.changes 2023-08-06 16:30:00.827865943 +0200 @@ -1,0 +2,10 @@ +Sat Jul 29 15:01:55 UTC 2023 - Peter Simons <psim...@suse.com> + +- Update hashable to version 1.4.3.0. + ## Version 1.4.3.0 + + * Export `defaultHashWithSalt` and `defaultHash`. + * Fix issue of tuples with 0 first component causing all-zero state. + * Change `hashInt` to mix bits more. + +------------------------------------------------------------------- Old: ---- hashable-1.4.2.0.tar.gz hashable.cabal New: ---- hashable-1.4.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-hashable.spec ++++++ --- /var/tmp/diff_new_pack.6xqQop/_old 2023-08-06 16:30:01.299868804 +0200 +++ /var/tmp/diff_new_pack.6xqQop/_new 2023-08-06 16:30:01.307868852 +0200 @@ -20,13 +20,12 @@ %global pkgver %{pkg_name}-%{version} %bcond_with tests Name: ghc-%{pkg_name} -Version: 1.4.2.0 +Version: 1.4.3.0 Release: 0 Summary: A class for types that can be converted to a hash value License: BSD-3-Clause URL: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz -Source1: https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal#/%{pkg_name}.cabal BuildRequires: ghc-Cabal-devel BuildRequires: ghc-base-devel BuildRequires: ghc-base-prof @@ -65,6 +64,10 @@ The package provides instances for basic types and a way to combine hash values. +The 'Hashable' 'hash' values are not guaranteed to be stable across library +versions, operating systems or architectures. For stable hashing use named +hashes: SHA256, CRC32 etc. + %package devel Summary: Haskell %{pkg_name} library development files Requires: %{name} = %{version}-%{release} @@ -93,7 +96,6 @@ %prep %autosetup -n %{pkg_name}-%{version} -cp -p %{SOURCE1} %{pkg_name}.cabal %build %ghc_lib_build ++++++ hashable-1.4.2.0.tar.gz -> hashable-1.4.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.4.2.0/CHANGES.md new/hashable-1.4.3.0/CHANGES.md --- old/hashable-1.4.2.0/CHANGES.md 2001-09-09 03:46:40.000000000 +0200 +++ new/hashable-1.4.3.0/CHANGES.md 2001-09-09 03:46:40.000000000 +0200 @@ -1,5 +1,11 @@ See also https://pvp.haskell.org/faq +## Version 1.4.3.0 + + * Export `defaultHashWithSalt` and `defaultHash`. + * Fix issue of tuples with 0 first component causing all-zero state. + * Change `hashInt` to mix bits more. + ## Version 1.4.2.0 * Fix the foreign signature of `getThreadId` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.4.2.0/hashable.cabal new/hashable-1.4.3.0/hashable.cabal --- old/hashable-1.4.2.0/hashable.cabal 2001-09-09 03:46:40.000000000 +0200 +++ new/hashable-1.4.3.0/hashable.cabal 2001-09-09 03:46:40.000000000 +0200 @@ -1,6 +1,6 @@ cabal-version: 1.12 name: hashable -version: 1.4.2.0 +version: 1.4.3.0 synopsis: A class for types that can be converted to a hash value description: This package defines a class, 'Hashable', for types that @@ -8,6 +8,8 @@ exists for the benefit of hashing-based data structures. The package provides instances for basic types and a way to combine hash values. + . + The 'Hashable' 'hash' values are not guaranteed to be stable across library versions, operating systems or architectures. For stable hashing use named hashes: SHA256, CRC32 etc. homepage: http://github.com/haskell-unordered-containers/hashable @@ -36,6 +38,7 @@ || ==9.0.2 || ==9.2.5 || ==9.4.4 + || ==9.6.1 extra-source-files: CHANGES.md @@ -75,7 +78,7 @@ include-dirs: include hs-source-dirs: src build-depends: - base >=4.10.1.0 && <4.18 + base >=4.10.1.0 && <4.19 , bytestring >=0.10.8.2 && <0.12 , containers >=0.5.10.2 && <0.7 , deepseq >=1.4.3.0 && <1.5 @@ -84,7 +87,7 @@ , text >=1.2.3.0 && <1.3 || >=2.0 && <2.1 if !impl(ghc >=9.2) - build-depends: base-orphans >=0.8.6 && <0.9 + build-depends: base-orphans >=0.8.6 && <0.10 if !impl(ghc >=9.4) build-depends: data-array-byte >=0.1.0.1 && <0.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.4.2.0/src/Data/Hashable/Class.hs new/hashable-1.4.3.0/src/Data/Hashable/Class.hs --- old/hashable-1.4.2.0/src/Data/Hashable/Class.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/hashable-1.4.3.0/src/Data/Hashable/Class.hs 2001-09-09 03:46:40.000000000 +0200 @@ -50,6 +50,7 @@ , hashByteArray , hashByteArrayWithSalt , defaultHashWithSalt + , defaultHash -- * Higher Rank Functions , hashWithSalt1 , hashWithSalt2 @@ -228,7 +229,7 @@ -- Instances might want to implement this method to provide a more -- efficient implementation than the default implementation. hash :: a -> Int - hash = hashWithSalt defaultSalt + hash = defaultHash default hashWithSalt :: (Generic a, GHashable Zero (Rep a)) => Int -> a -> Int hashWithSalt = genericHashWithSalt @@ -293,9 +294,19 @@ -- cannot also provide a default implementation for that method for -- the non-generic instance use case. Instead we provide -- 'defaultHashWith'. +-- +-- @since 1.4.3.0 +-- defaultHashWithSalt :: Hashable a => Int -> a -> Int defaultHashWithSalt salt x = salt `hashInt` hash x +-- | Default implementation of 'hash' based on 'hashWithSalt'. +-- +-- @since 1.4.3.0 +-- +defaultHash :: Hashable a => a -> Int +defaultHash = hashWithSalt defaultSalt + -- | Transform a value into a 'Hashable' value, then hash the -- transformed value using the given salt. -- @@ -533,7 +544,6 @@ liftHashWithSalt2 _ h s (Right b) = s `hashInt` distinguisher `h` b instance (Hashable a1, Hashable a2) => Hashable (a1, a2) where - hash (a1, a2) = hash a1 `hashWithSalt` a2 hashWithSalt = hashWithSalt1 instance Hashable a1 => Hashable1 ((,) a1) where @@ -543,7 +553,6 @@ liftHashWithSalt2 h1 h2 s (a1, a2) = s `h1` a1 `h2` a2 instance (Hashable a1, Hashable a2, Hashable a3) => Hashable (a1, a2, a3) where - hash (a1, a2, a3) = hash a1 `hashWithSalt` a2 `hashWithSalt` a3 hashWithSalt = hashWithSalt1 instance (Hashable a1, Hashable a2) => Hashable1 ((,,) a1 a2) where @@ -555,8 +564,6 @@ instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4) => Hashable (a1, a2, a3, a4) where - hash (a1, a2, a3, a4) = hash a1 `hashWithSalt` a2 - `hashWithSalt` a3 `hashWithSalt` a4 hashWithSalt = hashWithSalt1 instance (Hashable a1, Hashable a2, Hashable a3) => Hashable1 ((,,,) a1 a2 a3) where @@ -568,9 +575,6 @@ instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5) => Hashable (a1, a2, a3, a4, a5) where - hash (a1, a2, a3, a4, a5) = - hash a1 `hashWithSalt` a2 `hashWithSalt` a3 - `hashWithSalt` a4 `hashWithSalt` a5 hashWithSalt s (a1, a2, a3, a4, a5) = s `hashWithSalt` a1 `hashWithSalt` a2 `hashWithSalt` a3 `hashWithSalt` a4 `hashWithSalt` a5 @@ -589,9 +593,6 @@ instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5, Hashable a6) => Hashable (a1, a2, a3, a4, a5, a6) where - hash (a1, a2, a3, a4, a5, a6) = - hash a1 `hashWithSalt` a2 `hashWithSalt` a3 - `hashWithSalt` a4 `hashWithSalt` a5 `hashWithSalt` a6 hashWithSalt s (a1, a2, a3, a4, a5, a6) = s `hashWithSalt` a1 `hashWithSalt` a2 `hashWithSalt` a3 `hashWithSalt` a4 `hashWithSalt` a5 `hashWithSalt` a6 @@ -611,9 +612,6 @@ instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5, Hashable a6, Hashable a7) => Hashable (a1, a2, a3, a4, a5, a6, a7) where - hash (a1, a2, a3, a4, a5, a6, a7) = - hash a1 `hashWithSalt` a2 `hashWithSalt` a3 - `hashWithSalt` a4 `hashWithSalt` a5 `hashWithSalt` a6 `hashWithSalt` a7 hashWithSalt s (a1, a2, a3, a4, a5, a6, a7) = s `hashWithSalt` a1 `hashWithSalt` a2 `hashWithSalt` a3 `hashWithSalt` a4 `hashWithSalt` a5 `hashWithSalt` a6 `hashWithSalt` a7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.4.2.0/src/Data/Hashable/Imports.hs new/hashable-1.4.3.0/src/Data/Hashable/Imports.hs --- old/hashable-1.4.2.0/src/Data/Hashable/Imports.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/hashable-1.4.3.0/src/Data/Hashable/Imports.hs 2001-09-09 03:46:40.000000000 +0200 @@ -5,9 +5,10 @@ Int64, Int32, Word64, Word32, xor, shiftR, shiftL, + (.&.), ) where import Prelude () import Data.Int (Int64, Int32) import Data.Word (Word64, Word32) -import Data.Bits (xor, shiftR, shiftL) +import Data.Bits (xor, shiftR, shiftL, (.&.)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.4.2.0/src/Data/Hashable/LowLevel.hs new/hashable-1.4.3.0/src/Data/Hashable/LowLevel.hs --- old/hashable-1.4.2.0/src/Data/Hashable/LowLevel.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/hashable-1.4.3.0/src/Data/Hashable/LowLevel.hs 2001-09-09 03:46:40.000000000 +0200 @@ -61,11 +61,31 @@ -- | Hash 'Int'. First argument is a salt, second argument is an 'Int'. -- The result is new salt / hash value. hashInt :: Salt -> Int -> Salt +hashInt s x = s `rnd` x1 `rnd` x2 `rnd` x3 `rnd` x4 + where + {-# INLINE rnd #-} + {-# INLINE x1 #-} + {-# INLINE x2 #-} + {-# INLINE x3 #-} + {-# INLINE x4 #-} #if WORD_SIZE_IN_BITS == 64 -hashInt s x = (s * 1099511628211) `xor` x + -- See https://github.com/haskell-unordered-containers/hashable/issues/270 + -- FNV-1 is defined to hash byte at the time. + -- We used to hash whole Int at once, which provided very bad mixing. + -- Current is a performance-quality compromise, we do four rounds per Int (instead of 8 for FNV-1 or 1 for previous hashable). + rnd a b = (a * 1099511628211) `xor` b + x1 = shiftR x 48 .&. 0xffff + x2 = shiftR x 32 .&. 0xffff + x3 = shiftR x 16 .&. 0xffff + x4 = x .&. 0xffff #else -hashInt s x = (s * 16777619) `xor` x + rnd a b = (a * 16777619) `xor` b + x1 = shiftR x 24 .&. 0xff + x2 = shiftR x 16 .&. 0xff + x3 = shiftR x 8 .&. 0xff + x4 = x .&. 0xff #endif + -- Note: FNV-1 hash takes a byte of data at once, here we take an 'Int', -- which is 4 or 8 bytes. Whether that's bad or not, I don't know. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.4.2.0/src/Data/Hashable.hs new/hashable-1.4.3.0/src/Data/Hashable.hs --- old/hashable-1.4.2.0/src/Data/Hashable.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/hashable-1.4.3.0/src/Data/Hashable.hs 2001-09-09 03:46:40.000000000 +0200 @@ -60,6 +60,9 @@ , hashByteArray , hashByteArrayWithSalt + , defaultHashWithSalt + , defaultHash + -- * Caching hashes , Hashed , hashed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.4.2.0/tests/Regress.hs new/hashable-1.4.3.0/tests/Regress.hs --- old/hashable-1.4.2.0/tests/Regress.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/hashable-1.4.3.0/tests/Regress.hs 2001-09-09 03:46:40.000000000 +0200 @@ -7,7 +7,8 @@ import qualified Test.Framework as F import Control.Monad (when) import Test.Framework.Providers.HUnit (testCase) -import Test.HUnit (assertFailure, (@=?)) +import Test.HUnit (Assertion, assertFailure, (@?=)) +import Test.Framework.Providers.QuickCheck2 (testProperty) import GHC.Generics (Generic) import Data.List (nub) import Data.Fixed (Pico) @@ -27,12 +28,17 @@ #include "MachDeps.h" +assertInequal :: Eq a => String -> a -> a -> Assertion +assertInequal msg x y + | x == y = assertFailure msg + | otherwise = return () + regressions :: [F.Test] regressions = [] ++ #ifdef HAVE_MMAP Mmap.regressions ++ [ testCase "Fixed" $ do - (hash (1 :: Pico) == hash (2 :: Pico)) @=? False + (hash (1 :: Pico) == hash (2 :: Pico)) @?= False ] ++ #endif [ F.testGroup "Generic: sum of nullary constructors" @@ -42,17 +48,27 @@ , testCase "3" $ nullaryCase 3 S3 , testCase "4" $ nullaryCase 4 S4 ] + + , testCase "Zero tuples: issue 271" $ do + assertInequal "Hash of (0,0) != 0" (hash (0 :: Int, 0 :: Int)) 0 + assertInequal "Hash of (0,0,0) != 0" (hash (0 :: Int, 0 :: Int, 0 :: Int)) 0 + + , testProperty "odd, odd: issue 271" $ \x' y' -> + let x = if odd x' then x' else x' + 1 :: Int + y = if odd y' then y' else y' + 1 :: Int + in hash (x, y) /= hash (negate x, negate y) + , testCase "Generic: Peano https://github.com/tibbe/hashable/issues/135" $ do let ns = take 20 $ iterate S Z let hs = map hash ns - hs @=? nub hs + hs @?= nub hs #if WORD_SIZE_IN_BITS == 64 , testCase "64 bit Text" $ do - hash ("hello world" :: Text) @=? + hash ("hello world" :: Text) @?= #if MIN_VERSION_text(2,0,0) - 4078614214911247440 + 2589482369471999198 #else - -3875242662334356092 + -1955893671357159554 #endif #endif , F.testGroup "concatenation" @@ -103,7 +119,7 @@ let salt = 42 let expected = salt `hashWithSalt` n `hashWithSalt` () let actual = hashWithSalt salt s - expected @=? actual + actual @?= expected data SumOfNullary = S0 | S1 | S2 | S3 | S4 deriving (Eq, Generic) instance Hashable SumOfNullary