GHC HEAD-only panic (emitPrimOp: handled above in cgOpApp)
I noticed this issue originally as deriving-compat-0.5.7
's test suite fails to compile on HEAD. Here is a minimized version of the test suite that compiles successfully with optimizations on GHC 8.8.1 and earlier:
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeFamilies #-}
module Bug where
import Control.Monad
import GHC.Arr (Ix(..))
import GHC.Base (getTag)
import GHC.Exts
data family D
data instance D = MkD
deriving (Eq, Ord, Show)
instance Ix D where
range (a, b) =
let a# = getTag a
b# = getTag b
in map (\(I# i#) -> tagToEnum# i# :: D)
(enumFromTo (I# a#) (I# b#))
unsafeIndex (a, _) c =
let a# = getTag a
c# = getTag c
d# = c# -# a#
in I# d#
inRange (a, b) c =
let a# = getTag a
b# = getTag b
c# = getTag c
in tagToEnum# (c# >=# a#) && tagToEnum# (c# <=# b#)
shouldBe :: (Eq a, Show a) => a -> a -> IO ()
shouldBe x y =
unless (x == y) $ fail $ show x ++ " is not equal to " ++ show y
ixLaws :: (Ix a, Show a) => a -> a -> a -> IO ()
ixLaws l u i = do
inRange (l,u) i `shouldBe` elem i (range (l,u))
range (l,u) !! index (l,u) i `shouldBe` i
map (index (l,u)) (range (l,u)) `shouldBe` [0..rangeSize (l,u)-1]
rangeSize (l,u) `shouldBe` length (range (l,u))
dIsLawfulIx :: IO ()
dIsLawfulIx = ixLaws MkD MkD MkD
However, it panics on GHC HEAD:
$ ~/Software/ghc5/inplace/bin/ghc-stage2 Bug.hs -O -fforce-recomp
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
ghc-stage2: panic! (the 'impossible' happened)
(GHC version 8.9.0.20191023:
emitPrimOp: handled above in cgOpApp
Some notes:
-
The use of optimization
-O
is critical to triggering the bug. -
The panic goes away if
D
is an ordinary data type instead of a data family. -
The code in the hand-written
Ix
instance is very similar to the code you would get for a derivedIx
instance, but with one key difference: the hand-written code usesgetTag
instead of a function that does something like this:dTag :: D -> Int# dTag MkD = 0#
If you replace all uses of
getTag
withdTag
, then the panic goes away. As a consequence, you won't trigger the panic if you derive theIx
instance.