ghc-8.10 regression: function against record with many fields makes time to compile (noticed on protocol-buffers-descriptor-2.4.13)
Here is the self-contained example extracted from protocol-buffers-descriptor-2.4.13
:
{-# OPTIONS_GHC -O1 -Wall #-}
{-
$ time ghc-8.8 -c A.hs
0.2s
$ time ghc-8.10.2 -c A.hs
<too long to wait>
$ time ghc-8.10.3 -c A.hs
<too long to wait>
-}
module FileOptions (FileOptions(..)) where
import Prelude (Bool(..), Maybe(..))
class Mergeable a where
mergeAppend :: a -> a -> a
mergeAppend _a b = b
instance Mergeable a => Mergeable (Maybe a) where
mergeAppend = mayMerge
mayMerge :: (Mergeable b) => Maybe b -> Maybe b -> Maybe b
mayMerge Nothing y = y
mayMerge x Nothing = x
mayMerge (Just x) (Just y) = Just (mergeAppend x y)
instance Mergeable Bool
data FileOptions = FileOptions
{ f1 :: !(Maybe Bool)
, f2 :: !(Maybe Bool)
, f3 :: !(Maybe Bool)
, f4 :: !(Maybe Bool)
, f5 :: !(Maybe Bool)
, f6 :: !(Maybe Bool)
, f7 :: !(Maybe Bool)
, f8 :: !(Maybe Bool)
, f9 :: !(Maybe Bool)
-- adding more of these makes ghc slower and slower to compile example
, fA :: !(Maybe Bool)
}
instance Mergeable FileOptions where
mergeAppend (FileOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 xA)
(FileOptions y1 y2 y3 y4 y5 y6 y7 y8 y9 yA)
= FileOptions
(mergeAppend x1 y1)
(mergeAppend x2 y2)
(mergeAppend x3 y3)
(mergeAppend x4 y4)
(mergeAppend x5 y5)
(mergeAppend x6 y6)
(mergeAppend x7 y7)
(mergeAppend x8 y8)
(mergeAppend x9 y9)
(mergeAppend xA yA)
Running:
$ time ghc-8.8 -c A.hs
0.2s
$ time ghc-8.10.2 -c A.hs
<too long to wait>
Environment
- GHC version used: ghc-8.8.4
Optional:
- Operating System: Linux
- System Architecture: amd64