LitRubbish representation confusion
Currently we have
data Literal = ... | LitRubbish [PrimRep]
literalType (LitRubbish preps) = mkForAllTy a Inferred (mkTyVarTy a)
where
a = mkTemplateTyVar (tYPE (primRepsToRuntimeRep preps))
When we want to make a rubbish literal of type ty
we do roughly
LitRubbish (typeMonoPrimRep ty) `App` Type ty
which should be a well-kinded application. But alas the round-trip
through [PrimRep]
loses information. consider make a rubbish literal of
type (# State# RealWorld, Int #)
.
- Its
typeMonoPrimRep
is[LiftedRep]
. That is, it is represented by a single pointer. - But
primRepsToRuntimeRep
applied to a singleton returns just that singleton, so we getLiftedRep
back. - So the rubblish literal has type
forall (a :: LiftedRep). a
- That is applied to
(# State# RealWorld, Int #)
, which an ill-kinded application.
Here's a reproducer:
f1 :: (# State# RealWorld, Int, Int #) -> Bool -> Int
f1 x True = 1
f` x False = f1 x True
Another bad consequence of using [PrimRep]
in LitRubbish
is that for this function
f2 :: (# State# RealWorld, Int #) -> Bool -> Int
f2 x True = 1
f2 x False = f x True
we have an absent x
whose [PrimRep]
is [LiftedRep]
. (Because that argument will ultimately
be represented by a singlt pointer.) But that currently triggers this code in GHC.Core.Opt.WorkWrap.Utils.mk_absent_let
:
mk_absent_let opts arg
-- The lifted case: Bind 'absentError' for a nice panic message if we are
-- wrong (like we were in #11126). See (1) in Note [Absent fillers]
| Just [LiftedRep] <- mb_mono_prim_reps
, not (isStrictDmd (idDemandInfo arg)) -- See (2) in Note [Absent fillers]
= Just (Let (NonRec arg panic_rhs))
Yikes! We generate
ww :: (# State# RealWorld, Int #) = absentError "blah"
But that type is unlifted.
This is all wrong.