Skip to content

Miscompilation when pattern match on unsafe coerced GADT

Summary

Function of form

m = case 5 of
  J{} -> Just 3

where J{} is

data D a where
    J :: Integer -> D Int

Returns Nothing.

I suppose that this is because of unsafeCoerce from the Num (D a) instance:

instance Num a => Num (D a) where
    fromInteger = unsafeCoerce . J . fromInteger

Steps to reproduce

Playground with whole example: https://play.haskell.org/saved/Va3pKOVb

Core code for complete issue:

data D a where
    J :: Integer -> D Int

instance Eq (D a) where
    J i == J j = i == j

instance Num a => Num (D a) where
    fromInteger = unsafeCoerce . J . fromInteger

-- >>> m
-- Just 5
m :: Maybe Integer
m = case (5 :: D Int) of
    J j -> Just j

-- >>> n
-- Nothing
n :: Maybe Integer
n = case 5 of
    5 -> Just 42
    J{} -> Just 3 -- hint to GHC that this is a `D something`

Notice that Nothing is returned by n only with -O0. On the other optimization levels print n will print empty string.

Expected behavior

Just 42 or at least error about non-exhaustive pattern match

Environment

  • GHC version used: [8.4 .. 9.8]
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information