Skip to content

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.)

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information