Hello community,

here is the log from the commit of package ghc-hashable for openSUSE:Factory 
checked in at 2017-04-14 13:37:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-hashable (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-hashable.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-hashable"

Fri Apr 14 13:37:56 2017 rev:11 rq:485129 version:1.2.6.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-hashable/ghc-hashable.changes        
2017-03-14 10:04:49.079067071 +0100
+++ /work/SRC/openSUSE:Factory/.ghc-hashable.new/ghc-hashable.changes   
2017-04-14 13:37:58.029304571 +0200
@@ -1,0 +2,5 @@
+Mon Mar 27 12:41:05 UTC 2017 - [email protected]
+
+- Update to version 1.2.6.0 revision 1 with cabal2obs.
+
+-------------------------------------------------------------------

Old:
----
  hashable-1.2.5.0.tar.gz

New:
----
  hashable-1.2.6.0.tar.gz
  hashable.cabal

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-hashable.spec ++++++
--- /var/tmp/diff_new_pack.yu9mof/_old  2017-04-14 13:38:00.592942254 +0200
+++ /var/tmp/diff_new_pack.yu9mof/_new  2017-04-14 13:38:00.596941688 +0200
@@ -19,15 +19,17 @@
 %global pkg_name hashable
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        1.2.5.0
+Version:        1.2.6.0
 Release:        0
 Summary:        A class for types that can be converted to a hash value
 License:        BSD-3-Clause
 Group:          Development/Languages/Other
 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-bytestring-devel
+BuildRequires:  ghc-deepseq-devel
 BuildRequires:  ghc-rpm-macros
 BuildRequires:  ghc-text-devel
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -60,6 +62,7 @@
 
 %prep
 %setup -q -n %{pkg_name}-%{version}
+cp -p %{SOURCE1} %{pkg_name}.cabal
 
 %build
 %ifarch i586

++++++ hashable-1.2.5.0.tar.gz -> hashable-1.2.6.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.2.5.0/CHANGES.md 
new/hashable-1.2.6.0/CHANGES.md
--- old/hashable-1.2.5.0/CHANGES.md     2017-01-02 09:44:38.000000000 +0100
+++ new/hashable-1.2.6.0/CHANGES.md     2017-03-18 00:26:23.000000000 +0100
@@ -1,3 +1,9 @@
+## Version 1.2.6.0
+
+ * Add support for type-indexed `Typeable`.
+
+ * Rework the `Generic` hashable for sums.
+
 ## Version 1.2.5.0
 
   * Add `Hashable1` and `Hashable2`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.2.5.0/Data/Hashable/Class.hs 
new/hashable-1.2.6.0/Data/Hashable/Class.hs
--- old/hashable-1.2.5.0/Data/Hashable/Class.hs 2017-01-02 09:44:38.000000000 
+0100
+++ new/hashable-1.2.6.0/Data/Hashable/Class.hs 2017-03-18 00:26:23.000000000 
+0100
@@ -1,5 +1,14 @@
 {-# LANGUAGE BangPatterns, CPP, ForeignFunctionInterface, MagicHash,
-             ScopedTypeVariables, UnliftedFFITypes, DeriveDataTypeable #-}
+             ScopedTypeVariables, UnliftedFFITypes #-}
+
+#if __GLASGOW_HASKELL__ < 710
+{-# LANGUAGE DeriveDataTypeable #-}
+#endif
+
+#if __GLASGOW_HASKELL__ >= 801
+{-# LANGUAGE PolyKinds #-} -- For TypeRep instances
+#endif
+
 #ifdef GENERICS
 {-# LANGUAGE DefaultSignatures, FlexibleContexts, GADTs,
     MultiParamTypeClasses, EmptyDataDecls #-}
@@ -56,9 +65,9 @@
 
 import Control.Applicative (Const(..))
 import Control.Exception (assert)
+import Control.DeepSeq (NFData(rnf))
 import Data.Bits (shiftL, shiftR, xor)
 import qualified Data.ByteString as B
-import qualified Data.ByteString.Internal as B
 import qualified Data.ByteString.Lazy as BL
 import qualified Data.ByteString.Unsafe as B
 import Data.Int (Int8, Int16, Int32, Int64)
@@ -68,7 +77,6 @@
 import qualified Data.Text.Array as TA
 import qualified Data.Text.Internal as T
 import qualified Data.Text.Lazy as TL
-import Data.Typeable (Typeable, TypeRep)
 import Data.Version (Version(..))
 import Data.Word (Word8, Word16, Word32, Word64)
 import Foreign.C (CString)
@@ -78,7 +86,7 @@
 import GHC.Base (ByteArray#)
 import GHC.Conc (ThreadId(..))
 import GHC.Prim (ThreadId#)
-import System.IO.Unsafe (unsafePerformIO)
+import System.IO.Unsafe (unsafeDupablePerformIO)
 import System.Mem.StableName
 import Data.Unique (Unique, hashUnique)
 
@@ -101,14 +109,17 @@
 import GHC.Generics
 #endif
 
-#if __GLASGOW_HASKELL__ >= 710
-import Data.Typeable (typeRepFingerprint)
+#if   __GLASGOW_HASKELL__ >= 801
+import Type.Reflection (typeRepFingerprint, Typeable, TypeRep, SomeTypeRep(..))
+import GHC.Fingerprint.Type(Fingerprint(..))
+#elif __GLASGOW_HASKELL__ >= 710
+import Data.Typeable (typeRepFingerprint, Typeable, TypeRep)
 import GHC.Fingerprint.Type(Fingerprint(..))
 #elif __GLASGOW_HASKELL__ >= 702
-import Data.Typeable.Internal (TypeRep (..))
+import Data.Typeable.Internal (Typeable, TypeRep (..))
 import GHC.Fingerprint.Type(Fingerprint(..))
 #elif __GLASGOW_HASKELL__ >= 606
-import Data.Typeable (typeRepKey)
+import Data.Typeable (typeRepKey, Typeable, TypeRep)
 #endif
 
 #if __GLASGOW_HASKELL__ >= 703
@@ -267,11 +278,10 @@
 defaultLiftHashWithSalt :: (Hashable2 f, Hashable a) => (Int -> b -> Int) -> 
Int -> f a b -> Int
 defaultLiftHashWithSalt h = liftHashWithSalt2 hashWithSalt h
 
--- Since we support a generic implementation of 'hashWithSalt' we
+-- | Since we support a generic implementation of 'hashWithSalt' we
 -- cannot also provide a default implementation for that method for
 -- the non-generic instance use case. Instead we provide
 -- 'defaultHashWith'.
-
 defaultHashWithSalt :: Hashable a => Int -> a -> Int
 defaultHashWithSalt salt x = salt `combine` hash x
 
@@ -443,7 +453,7 @@
         | isIEEE x =
             assert (sizeOf x >= sizeOf (0::Word32) &&
                     alignment x >= alignment (0::Word32)) $
-            hash ((unsafePerformIO $ with x $ peek . castPtr) :: Word32)
+            hash ((unsafeDupablePerformIO $ with x $ peek . castPtr) :: Word32)
         | otherwise = hash (show x)
     hashWithSalt = defaultHashWithSalt
 
@@ -452,7 +462,7 @@
         | isIEEE x =
             assert (sizeOf x >= sizeOf (0::Word64) &&
                     alignment x >= alignment (0::Word64)) $
-            hash ((unsafePerformIO $ with x $ peek . castPtr) :: Word64)
+            hash ((unsafeDupablePerformIO $ with x $ peek . castPtr) :: Word64)
         | otherwise = hash (show x)
     hashWithSalt = defaultHashWithSalt
 
@@ -591,7 +601,7 @@
         step (SP s l) x   = SP (h s x) (l + 1)
 
 instance Hashable B.ByteString where
-    hashWithSalt salt bs = B.inlinePerformIO $
+    hashWithSalt salt bs = unsafeDupablePerformIO $
                            B.unsafeUseAsCStringLen bs $ \(p, len) ->
                            hashPtrWithSalt p (fromIntegral len) salt
 
@@ -641,6 +651,7 @@
     hash n = fromIntegral n
     hashWithSalt = defaultHashWithSalt
 
+#if __GLASGOW_HASKELL__ < 801
 -- | Compute the hash of a TypeRep, in various GHC versions we can do this 
quickly.
 hashTypeRep :: TypeRep -> Int
 {-# INLINE hashTypeRep #-}
@@ -651,7 +662,7 @@
 -- Fingerprint is just the MD5, so taking any Int from it is fine
 hashTypeRep (TypeRep (Fingerprint x _) _ _) = fromIntegral x
 #elif __GLASGOW_HASKELL__ >= 606
-hashTypeRep = B.inlinePerformIO . typeRepKey
+hashTypeRep = unsafeDupablePerformIO . typeRepKey
 #else
 hashTypeRep = hash . show
 #endif
@@ -661,6 +672,23 @@
     hashWithSalt = defaultHashWithSalt
     {-# INLINE hash #-}
 
+#else
+
+hashTypeRep :: Type.Reflection.TypeRep a -> Int
+hashTypeRep tr =
+    let Fingerprint x _ = typeRepFingerprint tr in fromIntegral x
+
+instance Hashable Type.Reflection.SomeTypeRep where
+    hash (Type.Reflection.SomeTypeRep r) = hashTypeRep r
+    hashWithSalt = defaultHashWithSalt
+    {-# INLINE hash #-}
+
+instance Hashable (Type.Reflection.TypeRep a) where
+    hash = hashTypeRep
+    hashWithSalt = defaultHashWithSalt
+    {-# INLINE hash #-}
+#endif
+
 #if MIN_VERSION_base(4,8,0)
 instance Hashable Void where
     hashWithSalt _ = absurd
@@ -855,6 +883,9 @@
 instance F.Foldable Hashed where
   foldr f acc (Hashed a _) = f a acc
 
+instance NFData a => NFData (Hashed a) where
+  rnf = rnf . unhashed
+
 -- | 'Hashed' cannot be 'Functor'
 mapHashed :: Hashable b => (a -> b) -> Hashed a -> Hashed b
 mapHashed f (Hashed a _) = hashed (f a)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.2.5.0/Data/Hashable/Generic.hs 
new/hashable-1.2.6.0/Data/Hashable/Generic.hs
--- old/hashable-1.2.5.0/Data/Hashable/Generic.hs       2017-01-02 
09:44:38.000000000 +0100
+++ new/hashable-1.2.6.0/Data/Hashable/Generic.hs       2017-03-18 
00:26:23.000000000 +0100
@@ -22,7 +22,6 @@
 import Data.Hashable.Class
 import GHC.Generics
 
-
 -- Type without constructors
 instance GHashable arity V1 where
     ghashWithSalt _ salt _ = hashWithSalt salt ()
@@ -52,25 +51,64 @@
 instance (Hashable1 f, GHashable One g) => GHashable One (f :.: g) where
     ghashWithSalt targs salt = liftHashWithSalt (ghashWithSalt targs) salt . 
unComp1
 
-class GSum arity f where
-    hashSum :: HashArgs arity a -> Int -> Int -> Int -> f a -> Int
-
-instance (GSum arity a, GSum arity b, SumSize a, SumSize b) => GHashable arity 
(a :+: b) where
-    ghashWithSalt toHash salt = hashSum toHash salt 0 size
-        where size = unTagged (sumSize :: Tagged (a :+: b))
+class SumSize f => GSum arity f where
+    hashSum :: HashArgs arity a -> Int -> Int -> f a -> Int
+    -- hashSum args salt index value = ...
+
+-- [Note: Hashing a sum type]
+--
+-- The tree structure is used in GHC.Generics to represent the sum (and
+-- product) part of the generic represention of the type, e.g.:
+--
+--   (C0 ... :+: C1 ...) :+: (C2 ... :+: (C3 ... :+: C4 ...))
+--
+-- The value constructed with C2 constructor is represented as (R1 (L1 ...)).
+-- Yet, if we think that this tree is a flat (heterogenous) list:
+--
+--   [C0 ..., C1 ..., C2 ..., C3 ..., C4... ]
+--
+-- then the value constructed with C2 is a (dependent) pair (2, ...), and
+-- hashing it is simple:
+--
+--   salt `hashWithSalt` (2 :: Int) `hashWithSalt` ...
+--
+-- This is what we do below. When drilling down the tree, we count how many
+-- leafs are to the left (`index` variable). At the leaf case C1, we'll have an
+-- actual index into the sum.
+--
+-- This works well for balanced data. However for recursive types like:
+--
+--   data Nat = Z | S Nat
+--
+-- the `hashWithSalt salt (S (S (S Z)))` is
+--
+--   salt `hashWithSalt` (1 :: Int) -- first S
+--        `hashWithSalt` (1 :: Int) -- second S
+--        `hashWithSalt` (1 :: Int) -- third S
+--        `hashWithSalt` (0 :: Int) -- Z
+--        `hashWithSalt` ()         -- U1
+--
+-- For that type the manual implementation:
+--
+--    instance Hashable Nat where
+--        hashWithSalt salt n = hashWithSalt salt (natToInteger n)
+--
+-- would be better performing CPU and hash-quality wise (assuming that
+-- Integer's Hashable is of high quality).
+--
+instance (GSum arity a, GSum arity b) => GHashable arity (a :+: b) where
+    ghashWithSalt toHash salt = hashSum toHash salt 0
 
 instance (GSum arity a, GSum arity b) => GSum arity (a :+: b) where
-    hashSum toHash !salt !code !size s = case s of
-        L1 x -> hashSum toHash salt code           sizeL x
-        R1 x -> hashSum toHash salt (code + sizeL) sizeR x
+    hashSum toHash !salt !index s = case s of
+        L1 x -> hashSum toHash salt index x
+        R1 x -> hashSum toHash salt (index + sizeL) x
       where
-        sizeL = size `shiftR` 1
-        sizeR = size - sizeL
+        sizeL = unTagged (sumSize :: Tagged a)
     {-# INLINE hashSum #-}
 
 instance GHashable arity a => GSum arity (C1 c a) where
-    -- hashSum toHash !salt !code _ (M1 x) = ghashWithSalt toHash 
(hashWithSalt salt code) x
-    hashSum toHash !salt !code _ (M1 x) = hashWithSalt salt (ghashWithSalt 
toHash code x)
+    hashSum toHash !salt !index (M1 x) = ghashWithSalt toHash (hashWithSalt 
salt index) x
     {-# INLINE hashSum #-}
 
 class SumSize f where
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.2.5.0/hashable.cabal 
new/hashable-1.2.6.0/hashable.cabal
--- old/hashable-1.2.5.0/hashable.cabal 2017-01-02 09:44:38.000000000 +0100
+++ new/hashable-1.2.6.0/hashable.cabal 2017-03-18 00:26:23.000000000 +0100
@@ -1,5 +1,5 @@
 Name:                hashable
-Version:             1.2.5.0
+Version:             1.2.6.0
 Synopsis:            A class for types that can be converted to a hash value
 Description:         This package defines a class, 'Hashable', for types that
                      can be converted to a hash value.  This class
@@ -46,8 +46,9 @@
   Exposed-modules:   Data.Hashable
                      Data.Hashable.Lifted
   Other-modules:     Data.Hashable.Class
-  Build-depends:     base >= 4.0 && < 4.10,
-                     bytestring >= 0.9 && < 0.11
+  Build-depends:     base >= 4.0 && < 4.11,
+                     bytestring >= 0.9 && < 0.11,
+                     deepseq >= 1.3
   if impl(ghc)
     Build-depends:   ghc-prim,
                      text >= 0.11.0.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.2.5.0/tests/Regress.hs 
new/hashable-1.2.6.0/tests/Regress.hs
--- old/hashable-1.2.5.0/tests/Regress.hs       2017-01-02 09:44:38.000000000 
+0100
+++ new/hashable-1.2.6.0/tests/Regress.hs       2017-03-18 00:26:23.000000000 
+0100
@@ -1,15 +1,47 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveGeneric #-}
 
 module Regress (regressions) where
 
 import qualified Test.Framework as F
+import Test.Framework.Providers.HUnit (testCase)
+import Test.HUnit ((@=?))
+import GHC.Generics (Generic)
+import Data.List (nub)
 
 #ifdef HAVE_MMAP
 import qualified Regress.Mmap as Mmap
 #endif
 
+import Data.Hashable
+
 regressions :: [F.Test]
-regressions = []
+regressions = [] ++
 #ifdef HAVE_MMAP
-              ++ Mmap.regressions
+    Mmap.regressions ++
 #endif
+    [ F.testGroup "Generic: sum of nullary constructors"
+        [ testCase "0" $ nullaryCase 0 S0
+        , testCase "1" $ nullaryCase 1 S1
+        , testCase "2" $ nullaryCase 2 S2
+        , testCase "3" $ nullaryCase 3 S3
+        , testCase "4" $ nullaryCase 4 S4
+        ]
+    , 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
+    ]
+  where
+    nullaryCase :: Int -> SumOfNullary -> IO ()
+    nullaryCase n s = do
+        let salt = 42
+        let expected = salt `hashWithSalt` n `hashWithSalt` ()
+        let actual = hashWithSalt salt s
+        expected @=? actual
+
+data SumOfNullary = S0 | S1 | S2 | S3 | S4 deriving (Generic)
+instance Hashable SumOfNullary
+
+data Nat = Z | S Nat deriving (Generic)
+instance Hashable Nat

++++++ hashable.cabal ++++++
Name:                hashable
Version:             1.2.6.0
x-revision: 1
Synopsis:            A class for types that can be converted to a hash value
Description:         This package defines a class, 'Hashable', for types that
                     can be converted to a hash value.  This class
                     exists for the benefit of hashing-based data
                     structures.  The package provides instances for
                     basic types and a way to combine hash values.
Homepage:            http://github.com/tibbe/hashable
License:             BSD3
License-file:        LICENSE
Author:              Milan Straka <[email protected]>
                     Johan Tibell <[email protected]>
Maintainer:          [email protected]
bug-reports:         https://github.com/tibbe/hashable/issues
Stability:           Provisional
Category:            Data
Build-type:          Simple
Cabal-version:       >=1.8
-- tests/Properties.hs shouldn't have to go here, but the source files
-- for the test-suite stanzas don't get picked up by `cabal sdist`.
Extra-source-files:
  CHANGES.md, README.md, tests/Properties.hs,
  benchmarks/Benchmarks.hs, benchmarks/cbits/*.c, benchmarks/cbits/*.h

Flag integer-gmp
  Description: Are we using integer-gmp to provide fast Integer instances?
  Default: True

Flag sse2
  Description: Do we want to assume that a target supports SSE 2?
  Default: True
  Manual: True

Flag sse41
  Description: Do we want to assume that a target supports SSE 4.1?
  Default: False
  Manual: True

Flag examples
  Description: Build example modules
  Default: False
  Manual: True

Library
  Exposed-modules:   Data.Hashable
                     Data.Hashable.Lifted
  Other-modules:     Data.Hashable.Class
  Build-depends:     base >= 4.4 && < 4.11,
                     bytestring >= 0.9 && < 0.11,
                     deepseq >= 1.3
  if impl(ghc)
    Build-depends:   ghc-prim,
                     text >= 0.11.0.5
  if impl(ghc) && flag(integer-gmp)
    Build-depends:   integer-gmp >= 0.2

  if impl(ghc >= 7.2.1)
    CPP-Options:     -DGENERICS
    Other-modules:   Data.Hashable.Generic

  C-sources:
                     cbits/fnv.c

  Ghc-options:       -Wall
  if impl(ghc >= 6.8)
    Ghc-options: -fwarn-tabs
  else
    c-sources:         cbits/getRandomBytes.c
    other-modules:     Data.Hashable.RandomSource
    if os(windows)
      extra-libraries: advapi32

Test-suite tests
  Type:              exitcode-stdio-1.0
  Hs-source-dirs:    tests
  Main-is:           Main.hs
  Other-modules:     Properties Regress
  Build-depends:     base >= 4.0 && < 5.0,
                     bytestring,
                     ghc-prim,
                     hashable,
                     test-framework >= 0.3.3,
                     test-framework-hunit,
                     test-framework-quickcheck2 >= 0.2.9,
                     HUnit,
                     QuickCheck >= 2.4.0.1,
                     random >= 1.0 && < 1.2,
                     text >= 0.11.0.5
  if !os(windows)
    Build-depends:   unix
    CPP-options:     -DHAVE_MMAP
    Other-modules:   Regress.Mmap

  Ghc-options:       -Wall -fno-warn-orphans
  if impl(ghc >= 7.2.1)
    CPP-Options:     -DGENERICS

benchmark benchmarks
  -- We cannot depend on the hashable library directly as that creates
  -- a dependency cycle.
  hs-source-dirs: . benchmarks

  main-is: Benchmarks.hs
  other-modules:
    Data.Hashable
    Data.Hashable.Class
    Data.Hashable.RandomSource
    Data.Hashable.SipHash
  type: exitcode-stdio-1.0

  build-depends:
    base,
    bytestring,
    criterion >= 1.0,
    ghc-prim,
    siphash,
    text

  if impl(ghc)
    Build-depends:   ghc-prim,
                     text >= 0.11.0.5
  if impl(ghc) && flag(integer-gmp)
    Build-depends:   integer-gmp >= 0.2

  if impl(ghc >= 7.2.1)
    CPP-Options:     -DGENERICS

  include-dirs:
    benchmarks/cbits

  includes:
    siphash.h

  c-sources:
    benchmarks/cbits/inthash.c
    benchmarks/cbits/siphash.c
    benchmarks/cbits/wang.c
    cbits/fnv.c

  if (arch(i386) || arch(x86_64)) && flag(sse2)
    cpp-options: -DHAVE_SSE2
    c-sources:
      benchmarks/cbits/siphash-sse2.c

    if flag(sse41)
      cpp-options: -DHAVE_SSE41
      c-sources:
        benchmarks/cbits/siphash-sse41.c

  Ghc-options:       -Wall -O2
  if impl(ghc >= 6.8)
    Ghc-options: -fwarn-tabs
  else
    c-sources:         cbits/getRandomBytes.c
    other-modules:     Data.Hashable.RandomSource
    if os(windows)
      extra-libraries: advapi32


Executable hashable-examples
  if flag(examples)
    build-depends: base, hashable
  else
    buildable: False
  hs-source-dirs: examples
  main-is: Main.hs

source-repository head
  type:     git
  location: https://github.com/tibbe/hashable.git

Reply via email to