Note [Boxity for bottoming functions]

GHC/Core/Opt/DmdAnal.hs:1565 compiler

Consider (A)
    indexError :: Show a => (a, a) -> a -> String -> b
    Str=<..><1!P(S,S)><1S><S>b
    indexError rng i s = error (show rng ++ show i ++ show s)

    get :: (Int, Int) -> Int -> [a] -> a
    get p@(l,u) i xs
      | l <= i, i < u = xs !! (i-u)
      | otherwise     = indexError p i "get"

The hot path of `get` certainly wants to unbox `p` as well as `l` and
`u`, but the unimportant, diverging error path needs `l::a` and `u::a`
boxed, since `indexError` can't unbox them because they are polymorphic.
This pattern often occurs in performance sensitive code that does
bounds-checking.

So we want to give `indexError` a signature like `<1!P(!S,!S)><1!S><S!S>b`
where the !S (meaning Poly Unboxed C1N) says that the polymorphic arguments
are unboxed (recursively).  The wrapper for `indexError` won't /actually/
unbox them (because their polymorphic type doesn't allow that) but when
demand-analysing /callers/, we'll behave as if that call needs the args
unboxed.

Then at call sites of `indexError`, we will end up doing some
reboxing, because `$windexError` still takes boxed arguments. This
reboxing should usually float into the slow, diverging code path; but
sometimes (sadly) it doesn't: see Note [Reboxed crud for bottoming calls].

Here is another important case (B):
    f x = Just x  -- Suppose f is not inlined for some reason
                  Main point: f takes its argument boxed

    wombat x = error (show (f x))

    g :: Bool -> Int -> a
    g True  x = x+1
    g False x = wombat x

Again we want `wombat` to pretend to take its Int-typed argument unboxed,
even though it has to pass it boxed to `f`, so that `g` can take its
argument unboxed (and rebox it before calling `wombat`).

So here's what we do: while summarising `indexError`'s boxity signature in
`finaliseArgBoxities`:

* To address (B), for bottoming functions, we start by using `unboxDeeplyDmd`
  to make all its argument demands unboxed, right to the leaves; regardless
  of what the analysis said.

* To address (A), for bottoming functions, in the DontUnbox case when the
  argument is a type variable, we /refrain/ from using trimBoxity.
  (Remember the previous bullet: we have already doen `unboxDeeplyDmd`.)

Wrinkle:

* Remember Note [No lazy, Unboxed demands in demand signature]. So
  unboxDeeplyDmd doesn't recurse into lazy demands.  It's extremely unusual
  to have lazy demands in the arguments of a bottoming function anyway.
  But it can happen, when the demand analyser gives up because it
  encounters a recursive data type; see Note [Demand analysis for recursive
  data constructors].

References 2

Referenced by 8