Skip to content

ghc panic on implicit recast of unboxed sum

Summary

As best I can tell, GHC is panicking when an unboxed sum type contains a variant that fits inside its other phantom variant type, and that same variant is returned in a different sum type whose phantom it does not fit.

I expect this is because in the examples below, ghc has decided to represent x as its wider type, and at some point simply reuses x in the return value without unpacking and repacking it('s metadata?) with the updated sum representation. But I have no idea where in the pipeline is causing it.

This is confusing but makes more sense with an example:

Steps to reproduce

The following panic with

   panic! (the 'impossible' happened)
  GHC version 9.4.2:
	findSlot
  Can't find slot
  [WordSlot, DoubleSlot]
  [Word64Slot]
  Call stack:
      CallStack (from HasCallStack):
        callStackDoc, called at compiler/GHC/Utils/Panic.hs:182:37 in ghc:GHC.Utils.Panic
        pprPanic, called at compiler/GHC/Types/RepType.hs:271:9 in ghc:GHC.Types.RepType
foo :: (# Float# | Double# #) -> (# Float# | Float #)
foo (# x | #) = (# x | #)
bar :: (# Word# | Int64# #) -> (# Double# | Word# #)
bar (# y | #) = let x = y in (# | x #)
baz :: (# Word# | Word64# #) -> (# Word# | (##) #)
baz (# x | #) = (# x | #)

while the following compile without issue:

bip :: (# Float# | Word64# #) -> (# Float# | Word# #)
bip (# x | #) = (# x | #)
bop :: (# Float# | Float# #) -> (# Float# | Double# #)
bop (# x | #) = (# x | #)
boop :: (# Word# | Word64# #) -> Word#
boop (# x | #) = x

Expected behavior

These should all compile.

Environment

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