Skip to content

GHC 9.6 panics when encountering representation-polymorphic type hidden behind type family

Summary

GHC 9.6 panics when encountering an illegal representation-polymorphic type that is hidden behind a type family, instead of reporting the appropriate error (GHC-55287). The issue occurs with both GHC 9.6.2 and 9.6.1, but doesn't occur with GHC 9.4.7 and 9.2.8.

Steps to reproduce

Below is the offending code:

{-# LANGUAGE GHC2021, AllowAmbiguousTypes, DataKinds, MagicHash, TypeFamilies #-}
module Unboxed where

import Data.Kind(Type)
import GHC.Exts(Float#, Int#, RuntimeRep(FloatRep, IntRep), TYPE)

type Rep :: Type -> RuntimeRep
type family Rep t where
  Rep Int = IntRep
  Rep Float = FloatRep

type Unbox :: forall (t :: Type) -> TYPE (Rep t)
type family Unbox t where
  Unbox Int = Int#
  Unbox Float = Float#

type family a #-> b where
  a #-> b = Unbox a -> b

f :: a #-> ()
f _ = ()

Attempting to compile the above module results in a Core Lint error and a panic:

> ghc-9.6.2 -dcore-lint Unboxed.hs
[1 of 1] Compiling Unboxed          ( Unboxed.hs, Unboxed.o )
*** Core Lint errors : in result of Desugar (after optimization) ***
Unboxed.hs:20:1: warning:
    Binder does not have a fixed runtime representation: ds_dIa :: (Unbox
                                                                      a_aHC :: TYPE (Rep a_aHC))
    In the RHS of f :: forall a. a #-> ()
    In the body of lambda with binder a_aHC :: *
    In the body of lambda with binder ds_dIa :: Unbox a_aHC
    Substitution: <InScope = {a_aHC}
                   IdSubst   = []
                   TvSubst   = [aHC :-> a_aHC]
                   CvSubst   = []>
*** Offending Program ***
f :: forall a. a #-> ()
[LclIdX,
 Unf=Unf{Src=<vanilla>, TopLvl=True,
         Value=True,
<no location info>: error:
    panic! (the 'impossible' happened)
  GHC version 9.6.2:
        runtimeRepPrimRep
  typePrimRep (Unbox a_aHC :: TYPE (Rep a_aHC))
  Rep a_aHC
  Call stack:
      CallStack (from HasCallStack):
        callStackDoc, called at compiler/GHC/Utils/Panic.hs:189:37 in ghc:GHC.Utils.Panic
        pprPanic, called at compiler/GHC/Types/RepType.hs:615:5 in ghc:GHC.Types.RepType
  CallStack (from HasCallStack):
    panic, called at compiler/GHC/Utils/Error.hs:454:29 in ghc:GHC.Utils.Error


Please report this as a GHC bug:  https://www.haskell.org/ghc/reportabug

If f's type signature is changed to f :: Unbox a -> () (i.e. inlining the body of the type family), then GHC produces the expected error message:

> ghc-9.6.2 -dcore-lint Unboxed.hs
[1 of 1] Compiling Unboxed          ( Unboxed.hs, Unboxed.o )

Unboxed.hs:21:1: error: [GHC-55287]
    The first pattern in the equation for ‘f’
    does not have a fixed runtime representation.
    Its type is:
      Unbox a :: TYPE (Rep a)
   |
21 | f _ = ()
   | ^^^^^^^^

GHC 9.4.7 and 9.2.8 correctly report an error even with the type family in the signature:

> ghc-9.4.7 -dcore-lint Unboxed.hs
[1 of 1] Compiling Unboxed          ( Unboxed.hs, Unboxed.o )

Unboxed.hs:21:1: error:
    • The first pattern in the equation for ‘f’
      does not have a fixed runtime representation.
      Its type is:
        p0 :: TYPE c0
      Cannot unify ‘Rep a’ with the type variable ‘c0’
      because it is not a concrete ‘RuntimeRep’.
    • The equation for ‘f’ has one value argument,
        but its type ‘a #-> ()’ has none
    • Relevant bindings include
        f :: a #-> () (bound at Unboxed.hs:21:1)
   |
21 | f _ = ()
   | ^^^^^^^^
> ghc-9.2.8 -dcore-lint Unboxed.hs
[1 of 1] Compiling Unboxed          ( Unboxed.hs, Unboxed.o )

Unboxed.hs:21:3: error:
    A levity-polymorphic type is not allowed here:
      Type: Unbox a
      Kind: TYPE (Rep a)
    In a wildcard pattern
   |
21 | f _ = ()
   |   ^

Similar issues

While researching this, I've found 2 other similar issues involving panics and representation-polymorphic types:

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