Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic instance of Binary is broken for types with 256 constructors #175

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions binary.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ test-suite qc
other-modules:
Action
Arbitrary
Generic
build-depends:
base >= 4.5.0.0 && < 5,
base-orphans >=0.8.1 && <0.9,
Expand Down
2 changes: 1 addition & 1 deletion src/Data/Binary/Generic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ instance Binary a => GBinaryGet (K1 i a) where
-- encode the constructor. If it has 2^16 constructors or less it will
-- use two bytes, and so on till 2^64-1.

#define GUARD(WORD) (size - 1) <= fromIntegral (maxBound :: WORD)
#define GUARD(WORD) size <= fromIntegral (maxBound :: WORD)
#define PUTSUM(WORD) GUARD(WORD) = putSum (0 :: WORD) (fromIntegral size)
#define GETSUM(WORD) GUARD(WORD) = (get :: Get WORD) >>= checkGetSum (fromIntegral size)

Expand Down
28 changes: 28 additions & 0 deletions tests/Generic.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
module Generic where

import Data.Binary
import GHC.Generics
import Test.QuickCheck

data Generic256 =
C00 | C01 | C02 | C03 | C04 | C05 | C06 | C07 | C08 | C09 | C0a | C0b | C0c | C0d | C0e | C0f
| C10 | C11 | C12 | C13 | C14 | C15 | C16 | C17 | C18 | C19 | C1a | C1b | C1c | C1d | C1e | C1f
| C20 | C21 | C22 | C23 | C24 | C25 | C26 | C27 | C28 | C29 | C2a | C2b | C2c | C2d | C2e | C2f
| C30 | C31 | C32 | C33 | C34 | C35 | C36 | C37 | C38 | C39 | C3a | C3b | C3c | C3d | C3e | C3f
| C40 | C41 | C42 | C43 | C44 | C45 | C46 | C47 | C48 | C49 | C4a | C4b | C4c | C4d | C4e | C4f
| C50 | C51 | C52 | C53 | C54 | C55 | C56 | C57 | C58 | C59 | C5a | C5b | C5c | C5d | C5e | C5f
| C60 | C61 | C62 | C63 | C64 | C65 | C66 | C67 | C68 | C69 | C6a | C6b | C6c | C6d | C6e | C6f
| C70 | C71 | C72 | C73 | C74 | C75 | C76 | C77 | C78 | C79 | C7a | C7b | C7c | C7d | C7e | C7f
| C80 | C81 | C82 | C83 | C84 | C85 | C86 | C87 | C88 | C89 | C8a | C8b | C8c | C8d | C8e | C8f
| C90 | C91 | C92 | C93 | C94 | C95 | C96 | C97 | C98 | C99 | C9a | C9b | C9c | C9d | C9e | C9f
| Ca0 | Ca1 | Ca2 | Ca3 | Ca4 | Ca5 | Ca6 | Ca7 | Ca8 | Ca9 | Caa | Cab | Cac | Cad | Cae | Caf
| Cb0 | Cb1 | Cb2 | Cb3 | Cb4 | Cb5 | Cb6 | Cb7 | Cb8 | Cb9 | Cba | Cbb | Cbc | Cbd | Cbe | Cbf
| Cc0 | Cc1 | Cc2 | Cc3 | Cc4 | Cc5 | Cc6 | Cc7 | Cc8 | Cc9 | Cca | Ccb | Ccc | Ccd | Cce | Ccf
| Cd0 | Cd1 | Cd2 | Cd3 | Cd4 | Cd5 | Cd6 | Cd7 | Cd8 | Cd9 | Cda | Cdb | Cdc | Cdd | Cde | Cdf
| Ce0 | Ce1 | Ce2 | Ce3 | Ce4 | Ce5 | Ce6 | Ce7 | Ce8 | Ce9 | Cea | Ceb | Cec | Ced | Cee | Cef
| Cf0 | Cf1 | Cf2 | Cf3 | Cf4 | Cf5 | Cf6 | Cf7 | Cf8 | Cf9 | Cfa | Cfb | Cfc | Cfd | Cfe | Cff
deriving (Eq, Enum, Bounded, Show, Generic, Binary)

instance Arbitrary Generic256 where
arbitrary = oneof (map pure [minBound..maxBound])
8 changes: 8 additions & 0 deletions tests/QC.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import Test.QuickCheck hiding (total)

import qualified Action (tests)
import Arbitrary ()
import Generic (Generic256)
import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
Expand Down Expand Up @@ -528,6 +529,11 @@ prop_fixed_resolution_constr x = runGet get (runPut (fixedPut x)) == x

------------------------------------------------------------------------

prop_Generic256 :: Generic256 -> Property
prop_Generic256 = roundTripWith put get

------------------------------------------------------------------------

type T a = a -> Property
type B a = a -> Bool

Expand Down Expand Up @@ -708,4 +714,6 @@ tests =
]
#endif
, testTypeable
, testGroup "Generic"
[ testProperty "Generic256" $ p prop_Generic256 ]
]