I've given this a yet some more thought. Given this simple core program:
f [InlPrag=NOINLINE] :: (#|#) Int Char -> Int
[GblId, Arity=1, Str=DmdType]
f =
\ (ds_dmE :: (#|#) Int Char) ->
case ds_dmE of _ [Occ=Dead] {
(#_|#) x_amy -> x_amy;
(#|_#) ipv_smK -> patError @ Int "UnboxedSum.hs:5:1-15|function f"#
}
We will get this stg pre-unarise:
unarise
[f [InlPrag=NOINLINE] :: (#|#) Int Char -> Int
[GblId, Arity=1, Str=DmdType, Unf=OtherCon []] =
\r srt:SRT:[0e :-> patError] [ds_svm]
case ds_svm of _ [Occ=Dead] {
(#_|#) x_svo [Occ=Once] -> x_svo;
(#|_#) _ [Occ=Dead] -> patError "UnboxedSum.hs:5:1-15|function f"#;
};]
What do we want it to look like afterwards? I currently, have this, modeled after unboxed tuples:
post-unarise:
[f [InlPrag=NOINLINE] :: (#|#) Int Char -> Int
[GblId, Arity=1, Str=DmdType, Unf=OtherCon []] =
\r srt:SRT:[0e :-> patError] [ds_gvu ds_gvv]
case (#_|#) [ds_gvu ds_gvv] of _ [Occ=Dead] { -- <-- WHAT SHOULD GO HERE?
(#_|#) x_svo [Occ=Once] -> x_svo;
(#|_#) _ [Occ=Dead] -> patError "UnboxedSum.hs:5:1-15|function f"#;
};]
Here I have performed the same rewriting of the scrutinee in the case statement as for unboxed tuples, but note that this doesn't quite work, as we don't know which data constructor to apply in "..." in case ... of. In the case of tuples it's easy; there is only one.
It seems to me that we just want to rewrite the case altogether into something that looks at the tag field of the data constructor. Also, in stg we use the same DataCon as in core, but after stg the unboxed sum case really only has one constructor (one with the union of all the fields), which makes it awkward to reuse the original DataCon.