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.