Derived Enum instances should perform tagToEnum# eagerly
Currently, the code for enumFrom
in a derived Enum
instance looks like this:
enumFrom a_aF3
= case (GHC.Prim.dataToTag# a_aF3) of
a#_aF4
-> GHC.Base.map
$tag2con_W_aEV
(GHC.Enum.enumFromTo (GHC.Types.I# a#_aF4) $maxtag_W_aEW)
Here, $tag2con_W_aEV
is a trivial wrapper around the tagToEnum#
primop, which can segfault if called with a bad argument. In this case, every element of GHC.Enum.enumFromTo (GHC.Types.I# a#_aF4) $maxtag_W_aEW
is a valid argument, so we would really like to eagerly evaluate this $tag2con_W_aEV
call when building each cons cell in the result list rather than producing a thunk. This means using a stricter version of map
.
Today, the desired eager evaluation actually does happen, but for completely the wrong reason: tagToEnum#
is (incorrectly) not marked as can_fail
, so the compiler sees no danger in speculatively evaluating it in CorePrep. But this omission will be fixed in !10097 (closed), causing a performance regression until the derived code is fixed.
(All of the above applies to enumFromThen
as well as to enumFrom
.)