Skip to content

Enabling -XUnliftedNewtypes permits panicking code (getRuntimeRep)

One interesting piece of UnliftedNewtypes trivia is that it permits the use of type families in newtype return kinds. It seems that this can have unfortunate consequences, however. Consider this example:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
-- {-# LANGUAGE UnliftedNewtypes #-}
module Bug where

import Data.Kind

type family Id (x :: Type) :: Type where
  Id x = x

newtype T :: Id Type where
  MkT :: Int -> T

f :: T -> T
f (MkT x) = MkT (x + 1)

If you compile this, you'll simply get an error:

$ ~/Software/ghc5/inplace/bin/ghc-stage2 Bug.hs
[1 of 1] Compiling Bug              ( Bug.hs, Bug.o )

Bug.hs:12:1: error:
    • Kind signature on data type declaration has non-* return kind
        Id *
    • In the newtype declaration for ‘T’
   |
12 | newtype T :: Id Type where
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^...

However, if you uncomment the {-# LANGUAGE UnliftedNewtypes #-} line, then GHC will panic:

$ ~/Software/ghc5/inplace/bin/ghc-stage2 Bug.hs
[1 of 1] Compiling Bug              ( Bug.hs, Bug.o )
ghc-stage2: panic! (the 'impossible' happened)
  (GHC version 8.9.0.20190614:
        getRuntimeRep
  T :: Id *
  Call stack:
      CallStack (from HasCallStack):
        callStackDoc, called at compiler/utils/Outputable.hs:1179:37 in ghc:Outputable
        pprPanic, called at compiler/types/Type.hs:2366:18 in ghc:Type

It's unclear to me whether this program should work or not, but either way, something is afoot.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information