Note [Refine DEFAULT case alternatives]

GHC/Core/Utils.hs:995 compiler

refineDefaultAlt replaces the DEFAULT alt with a constructor if there
is one possible value it could be.

The simplest example being
    foo :: () -> ()
    foo x = case x of !_ -> ()
which rewrites to
    foo :: () -> ()
    foo x = case x of () -> ()

There are two reasons in general why replacing a DEFAULT alternative
with a specific constructor is desirable.

1. We can simplify inner expressions.  For example

       data Foo = Foo1 ()

       test :: Foo -> ()
       test x = case x of
                  DEFAULT -> mid (case x of
                                    Foo1 x1 -> x1)

   refineDefaultAlt fills in the DEFAULT here with `Foo ip1` and then
   x becomes bound to `Foo ip1` so is inlined into the other case
   which causes the KnownBranch optimisation to kick in. If we don't
   refine DEFAULT to `Foo ip1`, we are left with both case expressions.

2. combineIdenticalAlts does a better job. For example (Simon Jacobi)
       data D = C0 | C1 | C2

       case e of
         DEFAULT -> e0
         C0      -> e1
         C1      -> e1

   When we apply combineIdenticalAlts to this expression, it can't
   combine the alts for C0 and C1, as we already have a default case.
   But if we apply refineDefaultAlt first, we get
       case e of
         C0 -> e1
         C1 -> e1
         C2 -> e0
   and combineIdenticalAlts can turn that into
       case e of
         DEFAULT -> e1
         C2 -> e0

   It isn't obvious that refineDefaultAlt does this but if you look
   at its one call site in GHC.Core.Opt.Simplify.Utils then the
   `imposs_deflt_cons` argument is populated with constructors which
   are matched elsewhere.

There are two exceptions where we avoid refining a DEFAULT case:

* Exception 1: Newtypes

  We can have a newtype, if we are just doing an eval:

    case x of { DEFAULT -> e }

  And we don't want to fill in a default for them!

* Exception 2: `type data` declarations

  The data constructors for a `type data` declaration (see
  Note [Type data declarations] in GHC.Rename.Module) do not exist at the
  value level. Nevertheless, it is possible to strictly evaluate a value
  whose type is a `type data` declaration. Test case
  type-data/should_compile/T2294b.hs contains an example:

    type data T a where
      A :: T Int

    f :: T a -> ()
    f !x = ()

  We want to generate the following Core for f:

    f = \(@a) (x :: T a) ->
         case x of
           __DEFAULT -> ()

  Namely, we do _not_ want to match on `A`, as it doesn't exist at the value
  level! See wrinkle (W2b) in Note [Type data declarations] in GHC.Rename.Module

References 1

Referenced by 5