Assertion failure with TypeData + dataToTag#
(Originally spun off from !9960 (comment 481426))
If you compile the following program with GHC 9.6 when built with assertions enabled + -O
:
{-# LANGUAGE TypeData, MagicHash #-}
module B where
import GHC.Exts
type data T a b where
MkT :: T a a
f :: T Int Bool -> Char
f x = case dataToTag# x of
0# -> 'a'
_ -> 'b'
Then it will trigger an assertion failure:
$ ~/Software/ghc3/_build/stage1/bin/ghc -O Bug.hs
[1 of 1] Compiling B ( Bug.hs, Bug.o )
<no location info>: error:
ASSERT failed!
CallStack (from HasCallStack):
assert, called at compiler/GHC/Core/DataCon.hs:1677:23 in ghc:GHC.Core.DataCon
The problem is the transformation:
Note [caseRules for dataToTag]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See also Note [dataToTag# magic].
We want to transform
case dataToTag x of
DEFAULT -> e1
1# -> e2
into
case x of
DEFAULT -> e1
(:) _ _ -> e2
which can be disabled with:
diff --git a/compiler/GHC/Core/Opt/ConstantFold.hs b/compiler/GHC/Core/Opt/ConstantFold.hs
index 7ace3124e9..ebf038c05c 100644
--- a/compiler/GHC/Core/Opt/ConstantFold.hs
+++ b/compiler/GHC/Core/Opt/ConstantFold.hs
@@ -55,7 +55,7 @@ import GHC.Core.TyCo.Compare( eqType )
import GHC.Core.TyCon
( tyConDataCons_maybe, isAlgTyCon, isEnumerationTyCon
, isNewTyCon, tyConDataCons
- , tyConFamilySize )
+ , tyConFamilySize, isTypeDataTyCon )
import GHC.Core.Map.Expr ( eqCoreExpr )
import GHC.Builtin.PrimOps ( PrimOp(..), tagToEnumKey )
@@ -3188,6 +3188,7 @@ caseRules _ (App (App (Var f) (Type ty)) v) -- dataToTag x
| Just DataToTagOp <- isPrimOpId_maybe f
, Just (tc, _) <- tcSplitTyConApp_maybe ty
, isAlgTyCon tc
+ , not (isTypeDataTyCon tc)
= Just (v, tx_con_dtt ty
, \v -> App (App (Var f) (Type ty)) (Var v))