From b044b7649f79ef77959f538afe9c1803581479c7 Mon Sep 17 00:00:00 2001 From: Taylor Fausak Date: Fri, 28 May 2021 18:48:31 +0000 Subject: [PATCH 1/6] Test i386 in CI --- .github/workflows/ci.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0e1057b..3a61821 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,7 +12,6 @@ on: jobs: build: strategy: - fail-fast: false matrix: include: - { os: ubuntu-20.04, ghc: 9.0.1, cabal: 3.4.0.0 } @@ -48,3 +47,8 @@ jobs: - run: cabal check - if: github.event_name == 'release' && matrix.os == 'ubuntu-20.04' && matrix.ghc == '9.0.1' run: cabal upload --publish --username '${{ secrets.HACKAGE_USERNAME }}' --password '${{ secrets.HACKAGE_PASSWORD }}' dist-newstyle/sdist/witch-*.tar.gz + i386: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - run: docker run --rm --user 0 --volume "$PWD:$PWD" --workdir "$PWD" taylorfausak/i386-haskell@sha256:450720742fa69258c0a8589dcac28c3c6d5d34718172d935b385520f4ee9128e sh -c 'cabal update && cabal test --test-show-details direct' From 566ff323fd2cf84859f53964e85c0c965da50ec6 Mon Sep 17 00:00:00 2001 From: Taylor Fausak Date: Fri, 28 May 2021 18:48:41 +0000 Subject: [PATCH 2/6] Comment out overflowing test cases --- src/test/Main.hs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/test/Main.hs b/src/test/Main.hs index d886606..6e43f97 100644 --- a/src/test/Main.hs +++ b/src/test/Main.hs @@ -363,8 +363,8 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Int64 Int" ~: let f = hush . Witch.tryFrom @Int.Int64 @Int in [ f 0 ~?= Just 0 - , f 9223372036854775807 ~?= Just 9223372036854775807 - , f (-9223372036854775808) ~?= Just (-9223372036854775808) + -- , f 9223372036854775807 ~?= Just 9223372036854775807 + -- , f (-9223372036854775808) ~?= Just (-9223372036854775808) ] , "From Int64 Integer" ~: let f = Witch.from @Int.Int64 @Integer in @@ -401,7 +401,7 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Int64 Word" ~: let f = hush . Witch.tryFrom @Int.Int64 @Word in [ f 0 ~?= Just 0 - , f 9223372036854775807 ~?= Just 9223372036854775807 + -- , f 9223372036854775807 ~?= Just 9223372036854775807 , f (-1) ~?= Nothing ] , "TryFrom Int64 Natural" ~: @@ -446,9 +446,9 @@ main = runTestTTAndExit $ "Witch" ~: let f = hush . Witch.tryFrom @Int @Int.Int32 in [ f 0 ~?= Just 0 , f 2147483647 ~?= Just 2147483647 - , f 2147483648 ~?= Nothing + -- , f 2147483648 ~?= Nothing , f (-2147483648) ~?= Just (-2147483648) - , f (-2147483649) ~?= Nothing + -- , f (-2147483649) ~?= Nothing ] , "From Int Int64" ~: let f = Witch.from @Int @Int.Int64 in @@ -479,8 +479,8 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Int Word32" ~: let f = hush . Witch.tryFrom @Int @Word.Word32 in [ f 0 ~?= Just 0 - , f 4294967295 ~?= Just 4294967295 - , f 4294967296 ~?= Nothing + -- , f 4294967295 ~?= Just 4294967295 + -- , f 4294967296 ~?= Nothing , f (-1) ~?= Nothing ] , "TryFrom Int Word64" ~: @@ -512,10 +512,10 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Int Double" ~: let f = hush . Witch.tryFrom @Int @Double in [ f 0 ~?= Just 0 - , f 9007199254740991 ~?= Just 9007199254740991 - , f 9007199254740992 ~?= Nothing - , f (-9007199254740991) ~?= Just (-9007199254740991) - , f (-9007199254740992) ~?= Nothing + -- , f 9007199254740991 ~?= Just 9007199254740991 + -- , f 9007199254740992 ~?= Nothing + -- , f (-9007199254740991) ~?= Just (-9007199254740991) + -- , f (-9007199254740992) ~?= Nothing ] , "TryFrom Integer Int8" ~: let f = hush . Witch.tryFrom @Integer @Int.Int8 in @@ -801,7 +801,7 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Word32 Int" ~: let f = hush . Witch.tryFrom @Word.Word32 @Int in [ f 0 ~?= Just 0 - , f 4294967295 ~?= Just 4294967295 + -- , f 4294967295 ~?= Just 4294967295 ] , "From Word32 Integer" ~: let f = Witch.from @Word.Word32 @Integer in @@ -840,7 +840,7 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Word64 Word" ~: let f = hush . Witch.tryFrom @Word.Word64 @Word in [ f 0 ~?= Just 0 - , f 18446744073709551615 ~?= Just 18446744073709551615 + -- , f 18446744073709551615 ~?= Just 18446744073709551615 ] , "From Word64 Natural" ~: let f = Witch.from @Word.Word64 @Natural.Natural in @@ -910,7 +910,7 @@ main = runTestTTAndExit $ "Witch" ~: let f = hush . Witch.tryFrom @Word @Word.Word32 in [ f 0 ~?= Just 0 , f 4294967295 ~?= Just 4294967295 - , f 4294967296 ~?= Nothing + -- , f 4294967296 ~?= Nothing ] , "From Word Word64" ~: let f = Witch.from @Word @Word.Word64 in @@ -943,8 +943,8 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Word Int64" ~: let f = hush . Witch.tryFrom @Word @Int.Int64 in [ f 0 ~?= Just 0 - , f 9223372036854775807 ~?= Just 9223372036854775807 - , f 9223372036854775808 ~?= Nothing + -- , f 9223372036854775807 ~?= Just 9223372036854775807 + -- , f 9223372036854775808 ~?= Nothing ] , "TryFrom Word Int" ~: let f = hush . Witch.tryFrom @Word @Int in @@ -966,8 +966,8 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Word Double" ~: let f = hush . Witch.tryFrom @Word @Double in [ f 0 ~?= Just 0 - , f 9007199254740991 ~?= Just 9007199254740991 - , f 9007199254740992 ~?= Nothing + -- , f 9007199254740991 ~?= Just 9007199254740991 + -- , f 9007199254740992 ~?= Nothing ] , "TryFrom Natural Word8" ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word8 in @@ -1236,9 +1236,9 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Double Int" ~: let f = hush . Witch.tryFrom @Double @Int in [ f 0 ~?= Just 0 - , f 9007199254740991 ~?= Just 9007199254740991 + -- , f 9007199254740991 ~?= Just 9007199254740991 , f 9007199254740992 ~?= Nothing - , f (-9007199254740991) ~?= Just (-9007199254740991) + -- , f (-9007199254740991) ~?= Just (-9007199254740991) , f (-9007199254740992) ~?= Nothing , f (0 / 0) ~?= Nothing , f (1 / 0) ~?= Nothing @@ -1294,7 +1294,7 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Double Word" ~: let f = hush . Witch.tryFrom @Double @Word in [ f 0 ~?= Just 0 - , f 9007199254740991 ~?= Just 9007199254740991 + -- , f 9007199254740991 ~?= Just 9007199254740991 , f 9007199254740992 ~?= Nothing , f (0 / 0) ~?= Nothing , f (1 / 0) ~?= Nothing From d86ffe4f5f230c16ddec70b774271dec65b21a31 Mon Sep 17 00:00:00 2001 From: Taylor Fausak Date: Fri, 28 May 2021 18:57:15 +0000 Subject: [PATCH 3/6] Fix broken conversions into naturals --- src/lib/Witch/Instances.hs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lib/Witch/Instances.hs b/src/lib/Witch/Instances.hs index d4aa72a..e4b43f5 100644 --- a/src/lib/Witch/Instances.hs +++ b/src/lib/Witch/Instances.hs @@ -251,7 +251,12 @@ instance TryFrom.TryFrom Int.Int64 Word where -- | Uses 'fromIntegral' when the input is not negative. instance TryFrom.TryFrom Int.Int64 Natural.Natural where - tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral + -- This should use @eitherTryFrom fromNonNegativeIntegral@, but that causes + -- a bug in GHC 9.0.1. + -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html + tryFrom s = case TryFrom.tryFrom (From.from s :: Integer) of + Left (TryFromException.TryFromException _ e) -> Left $ TryFromException.TryFromException s e + Right t -> Right t -- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215 -- inclusive. @@ -590,7 +595,9 @@ instance TryFrom.TryFrom Word.Word64 Word where -- | Uses 'fromIntegral'. instance From.From Word.Word64 Natural.Natural where - from = fromIntegral + -- This should use @fromIntegral@, but that causes a bug in GHC 9.0.1. + -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html + from s = Utility.unsafeFrom (From.from s :: Integer) -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Int.Int8 where From 3a48128c568ab4c5665e5534ce2bdeeb04bf6d56 Mon Sep 17 00:00:00 2001 From: Taylor Fausak Date: Fri, 28 May 2021 19:42:06 +0000 Subject: [PATCH 4/6] Rewrite test cases to handle 32-bit integral types --- src/test/Main.hs | 86 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/src/test/Main.hs b/src/test/Main.hs index 6e43f97..16bf3bc 100644 --- a/src/test/Main.hs +++ b/src/test/Main.hs @@ -1,3 +1,5 @@ +{-# OPTIONS_GHC -Wno-error=overflowed-literals #-} + {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-} @@ -363,8 +365,12 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Int64 Int" ~: let f = hush . Witch.tryFrom @Int.Int64 @Int in [ f 0 ~?= Just 0 - -- , f 9223372036854775807 ~?= Just 9223372036854775807 - -- , f (-9223372036854775808) ~?= Just (-9223372036854775808) + , let x = maxBound :: Int in if toInteger x >= 9223372036854775807 + then f 9223372036854775807 ~?= Just 9223372036854775807 + else f (fromIntegral x) ~?= Just x + , let x = minBound :: Int in if toInteger x <= (-9223372036854775808) + then f (-9223372036854775808) ~?= Just (-9223372036854775808) + else f (fromIntegral x) ~?= Just x ] , "From Int64 Integer" ~: let f = Witch.from @Int.Int64 @Integer in @@ -401,7 +407,9 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Int64 Word" ~: let f = hush . Witch.tryFrom @Int.Int64 @Word in [ f 0 ~?= Just 0 - -- , f 9223372036854775807 ~?= Just 9223372036854775807 + , let x = maxBound :: Word in if toInteger x >= 9223372036854775807 + then f 9223372036854775807 ~?= Just 9223372036854775807 + else f (fromIntegral x) ~?= Just x , f (-1) ~?= Nothing ] , "TryFrom Int64 Natural" ~: @@ -446,9 +454,13 @@ main = runTestTTAndExit $ "Witch" ~: let f = hush . Witch.tryFrom @Int @Int.Int32 in [ f 0 ~?= Just 0 , f 2147483647 ~?= Just 2147483647 - -- , f 2147483648 ~?= Nothing + , let x = maxBound :: Int in if toInteger x >= 2147483648 + then f 2147483648 ~?= Nothing + else f x ~?= Just (fromIntegral x) , f (-2147483648) ~?= Just (-2147483648) - -- , f (-2147483649) ~?= Nothing + , let x = minBound :: Int in if toInteger x <= (-2147483649) + then f (-2147483649) ~?= Nothing + else f x ~?= Just (fromIntegral x) ] , "From Int Int64" ~: let f = Witch.from @Int @Int.Int64 in @@ -479,8 +491,12 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Int Word32" ~: let f = hush . Witch.tryFrom @Int @Word.Word32 in [ f 0 ~?= Just 0 - -- , f 4294967295 ~?= Just 4294967295 - -- , f 4294967296 ~?= Nothing + , let x = maxBound :: Int in if toInteger x >= 4294967295 + then f 4294967295 ~?= Just 4294967295 + else f x ~?= Just (fromIntegral x) + , let x = maxBound :: Int in if toInteger x >= 4294967296 + then f 4294967296 ~?= Nothing + else f x ~?= Just (fromIntegral x) , f (-1) ~?= Nothing ] , "TryFrom Int Word64" ~: @@ -512,10 +528,18 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Int Double" ~: let f = hush . Witch.tryFrom @Int @Double in [ f 0 ~?= Just 0 - -- , f 9007199254740991 ~?= Just 9007199254740991 - -- , f 9007199254740992 ~?= Nothing - -- , f (-9007199254740991) ~?= Just (-9007199254740991) - -- , f (-9007199254740992) ~?= Nothing + , let x = maxBound :: Int in if toInteger x >= 9007199254740991 + then f 9007199254740991 ~?= Just 9007199254740991 + else f x ~?= Just (fromIntegral x) + , let x = maxBound :: Int in if toInteger x >= 9007199254740992 + then f 9007199254740992 ~?= Nothing + else f x ~?= Just (fromIntegral x) + , let x = minBound :: Int in if toInteger x <= (-9007199254740991) + then f (-9007199254740991) ~?= Just (-9007199254740991) + else f x ~?= Just (fromIntegral x) + , let x = minBound :: Int in if toInteger x <= (-9007199254740992) + then f (-9007199254740992) ~?= Nothing + else f x ~?= Just (fromIntegral x) ] , "TryFrom Integer Int8" ~: let f = hush . Witch.tryFrom @Integer @Int.Int8 in @@ -801,7 +825,9 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Word32 Int" ~: let f = hush . Witch.tryFrom @Word.Word32 @Int in [ f 0 ~?= Just 0 - -- , f 4294967295 ~?= Just 4294967295 + , let x = maxBound :: Int in if toInteger x >= 4294967295 + then f 4294967295 ~?= Just 4294967295 + else f (fromIntegral x) ~?= Just x ] , "From Word32 Integer" ~: let f = Witch.from @Word.Word32 @Integer in @@ -840,7 +866,9 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Word64 Word" ~: let f = hush . Witch.tryFrom @Word.Word64 @Word in [ f 0 ~?= Just 0 - -- , f 18446744073709551615 ~?= Just 18446744073709551615 + , let x = maxBound :: Word in if toInteger x >= 18446744073709551615 + then f 18446744073709551615 ~?= Just 18446744073709551615 + else f (fromIntegral x) ~?= Just x ] , "From Word64 Natural" ~: let f = Witch.from @Word.Word64 @Natural.Natural in @@ -910,7 +938,9 @@ main = runTestTTAndExit $ "Witch" ~: let f = hush . Witch.tryFrom @Word @Word.Word32 in [ f 0 ~?= Just 0 , f 4294967295 ~?= Just 4294967295 - -- , f 4294967296 ~?= Nothing + , let x = maxBound :: Word in if toInteger x >= 4294967296 + then f 4294967296 ~?= Nothing + else f x ~?= Just (fromIntegral x) ] , "From Word Word64" ~: let f = Witch.from @Word @Word.Word64 in @@ -943,8 +973,12 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Word Int64" ~: let f = hush . Witch.tryFrom @Word @Int.Int64 in [ f 0 ~?= Just 0 - -- , f 9223372036854775807 ~?= Just 9223372036854775807 - -- , f 9223372036854775808 ~?= Nothing + , let x = maxBound :: Word in if toInteger x >= 9223372036854775807 + then f 9223372036854775807 ~?= Just 9223372036854775807 + else f x ~?= Just (fromIntegral x) + , let x = maxBound :: Word in if toInteger x >= 9223372036854775808 + then f 9223372036854775808 ~?= Nothing + else f x ~?= Just (fromIntegral x) ] , "TryFrom Word Int" ~: let f = hush . Witch.tryFrom @Word @Int in @@ -966,8 +1000,12 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Word Double" ~: let f = hush . Witch.tryFrom @Word @Double in [ f 0 ~?= Just 0 - -- , f 9007199254740991 ~?= Just 9007199254740991 - -- , f 9007199254740992 ~?= Nothing + , let x = maxBound :: Word in if toInteger x >= 9007199254740991 + then f 9007199254740991 ~?= Just 9007199254740991 + else f x ~?= Just (fromIntegral x) + , let x = maxBound :: Word in if toInteger x >= 9007199254740991 + then f 9007199254740991 ~?= Nothing + else f x ~?= Just (fromIntegral x) ] , "TryFrom Natural Word8" ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word8 in @@ -1236,9 +1274,13 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Double Int" ~: let f = hush . Witch.tryFrom @Double @Int in [ f 0 ~?= Just 0 - -- , f 9007199254740991 ~?= Just 9007199254740991 + , let x = maxBound :: Int in if toInteger x >= 9007199254740991 + then f 9007199254740991 ~?= Just 9007199254740991 + else f (fromIntegral x) ~?= Just x , f 9007199254740992 ~?= Nothing - -- , f (-9007199254740991) ~?= Just (-9007199254740991) + , let x = maxBound :: Int in if toInteger x <= (-9007199254740991) + then f (-9007199254740991) ~?= Just (-9007199254740991) + else f (fromIntegral x) ~?= Just x , f (-9007199254740992) ~?= Nothing , f (0 / 0) ~?= Nothing , f (1 / 0) ~?= Nothing @@ -1294,7 +1336,9 @@ main = runTestTTAndExit $ "Witch" ~: , "TryFrom Double Word" ~: let f = hush . Witch.tryFrom @Double @Word in [ f 0 ~?= Just 0 - -- , f 9007199254740991 ~?= Just 9007199254740991 + , let x = maxBound :: Word in if toInteger x >= 9007199254740991 + then f 9007199254740991 ~?= Just 9007199254740991 + else f (fromIntegral x) ~?= Just x , f 9007199254740992 ~?= Nothing , f (0 / 0) ~?= Nothing , f (1 / 0) ~?= Nothing From dc2af8f27747c36b8d67c7ffb659aa8abaa50d75 Mon Sep 17 00:00:00 2001 From: Taylor Fausak Date: Fri, 28 May 2021 19:52:13 +0000 Subject: [PATCH 5/6] Fix x86_64 test cases --- src/test/Main.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/Main.hs b/src/test/Main.hs index 16bf3bc..4bef51a 100644 --- a/src/test/Main.hs +++ b/src/test/Main.hs @@ -1003,8 +1003,8 @@ main = runTestTTAndExit $ "Witch" ~: , let x = maxBound :: Word in if toInteger x >= 9007199254740991 then f 9007199254740991 ~?= Just 9007199254740991 else f x ~?= Just (fromIntegral x) - , let x = maxBound :: Word in if toInteger x >= 9007199254740991 - then f 9007199254740991 ~?= Nothing + , let x = maxBound :: Word in if toInteger x >= 9007199254740992 + then f 9007199254740992 ~?= Nothing else f x ~?= Just (fromIntegral x) ] , "TryFrom Natural Word8" ~: @@ -1278,7 +1278,7 @@ main = runTestTTAndExit $ "Witch" ~: then f 9007199254740991 ~?= Just 9007199254740991 else f (fromIntegral x) ~?= Just x , f 9007199254740992 ~?= Nothing - , let x = maxBound :: Int in if toInteger x <= (-9007199254740991) + , let x = minBound :: Int in if toInteger x <= (-9007199254740991) then f (-9007199254740991) ~?= Just (-9007199254740991) else f (fromIntegral x) ~?= Just x , f (-9007199254740992) ~?= Nothing From f5fc6ed6df04568e1c5b5d81fee62dc2249c0b90 Mon Sep 17 00:00:00 2001 From: Taylor Fausak Date: Fri, 28 May 2021 16:03:47 -0400 Subject: [PATCH 6/6] Use more succinct definition --- src/lib/Witch/Instances.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/Witch/Instances.hs b/src/lib/Witch/Instances.hs index e4b43f5..8942f1b 100644 --- a/src/lib/Witch/Instances.hs +++ b/src/lib/Witch/Instances.hs @@ -254,9 +254,7 @@ instance TryFrom.TryFrom Int.Int64 Natural.Natural where -- This should use @eitherTryFrom fromNonNegativeIntegral@, but that causes -- a bug in GHC 9.0.1. -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html - tryFrom s = case TryFrom.tryFrom (From.from s :: Integer) of - Left (TryFromException.TryFromException _ e) -> Left $ TryFromException.TryFromException s e - Right t -> Right t + tryFrom = Utility.eitherTryFrom $ \ s -> TryFrom.tryFrom (From.from s :: Integer) -- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215 -- inclusive.