Skip to content

Core Lint error with unsafeCoerce and phantom parameter

The following program fails -dcore-lint -O in master, as of 994bda56:

module M where

import Unsafe.Coerce
import Data.Kind

type Phantom :: Type -> Type
data Phantom a = MkPhantom

newtype Id a = MkId a
newtype First a = MkFirst (Id a)
data Second a = MkSecond (First a)
data Third a = MkThird !(Second a)

a :: Second (Phantom Int)
a = MkSecond (MkFirst (MkId MkPhantom))

uc :: Second (Phantom Int) -> Second (Phantom Bool)
uc = unsafeCoerce

b :: Third (Phantom Bool)
b = MkThird (uc a)
$ ./stage1/bin/ghc -dlint -O -dno-typeable-binds M
[1 of 1] Compiling M                ( M.hs, M.o ) [Source file changed]
*** Core Lint errors : in result of Simplifier ***
M.hs:21:1: warning:
    Role incompatibility: expected nominal, got representational
    in SelCo:Tc(0) (Sym co_azY)
    In the RHS of b :: Third (Phantom Bool)
    In a case alternative: (UnsafeRefl co_azY :: Second (Phantom Bool)
                                                 ~# Second (Phantom Int))
    Substitution: <InScope = {co_azY}
                   IdSubst   = []
                   TvSubst   = []
                   CvSubst   = [azY :-> co_azY]>

If Lint is not enabled, GHC shows an assertion failure

<no location info>: error:
    panic! (the 'impossible' happened)
  GHC version 9.7.20230506:
	ASSERT failed!
  Coercion = Sym Univ(nominal CorePrep
                      :: Second (Phantom Bool), Second (Phantom Int))
  LHS ty = Second (Phantom Int)
  RHS ty = Second (Phantom Bool)
  cs = Tc(0)
  coercion role = nominal
  Call stack:
      CallStack (from HasCallStack):
        assertPpr, called at compiler/GHC/Core/Coercion.hs:1152:5 in ghc-9.7-inplace:GHC.Core.Coercion
        mkSelCo_maybe, called at compiler/GHC/Core/Coercion.hs:1144:16 in ghc-9.7-inplace:GHC.Core.Coercion
        mkSelCo, called at compiler/GHC/Core/Type.hs:975:44 in ghc-9.7-inplace:GHC.Core.Type
  CallStack (from HasCallStack):
    panic, called at compiler/GHC/Utils/Error.hs:479:29 in ghc-9.7-inplace:GHC.Utils.Error

GHC 9.4 is fine, I haven't checked 9.6.

The use of unsafeCoerce should be fine: the program compiles correctly if it is replaced by coerce. The bug was originally found in the context of linear-base https://github.com/tweag/linear-base/issues/452, which is more complex and cannot use the coerce workaround.

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