Note [Strict fields in Core]

GHC/Core.hs:1037 compiler 3 tickets

In Core, evaluating a data constructor worker evaluates its strict fields.

In other words, let's say we have the following data type

  data T a b = MkT !a b

Now if `xs` reduces to `error "boom"`, then `MkT xs b` will throw that error.
Consequently, it is sound to seq the field before the call to the constructor,
e.g., with `case xs of xs' { __DEFAULT -> MkT xs' b }`.
Let's call this transformation "field eval insertion".

Note in particular that the data constructor application `MkT xs b` above is
*not* a value, unless `xs` is!

This has pervasive effect on the Core pipeline:

(SFC1) `exprIsHNF`/`exprIsConLike`/`exprOkForSpeculation` need to assert that the
    strict arguments of a DataCon worker are values/ok-for-spec themselves.

(SFC2) `exprIsConApp_maybe` inserts field evals in the `FloatBind`s it returns, so
    that the Simplifier, Constant-folding, the pattern-match checker, etc. all
    see the inserted field evals when they match on strict workers.

    For example,
      exprIsConApp_maybe (MkT e1 e2)
        = Just ([FloatCase e1 x], MkT, [x,e2])
    Meaning that (MkT e1 e2) is indeed a data constructor application, but if
    you want to decompose it (which is the purpose of exprIsConApp_maybe) you
    must evaluate e1 first.
    In case of case-of-known constructor, we get the rewrite
      case MkT e1 e2 of MkT xs' b' -> b'
      ==>
      case e1 of xs' { __DEFAULT -> e2 }
    which crucially retains the eval on e1.

(SFC3) The demand signature of a data constructor is strict in strict field
    position and lazy in non-strict fields. Likewise the demand *transformer*
    of a DataCon worker can stricten up demands on strict field args.
    See Note [Demand transformer for data constructors].

(SFC4) In the absence of `-fpedantic-bottoms`, it is still possible that some seqs
    are ultimately dropped or delayed due to eta-expansion.
    See Note [Dealing with bottom].

Strict field semantics is exploited and lowered in STG during EPT enforcement;
see Note [EPT enforcement lowers strict constructor worker semantics] for the
connection.

It might be tempting to think that strict fields could be implemented in terms
of unlifted fields. However, unlifted fields behave differently when the data
constructor is partially applied; see Note [exprIsHNF for function applications]
for an example.

Historical Note:
The delightfully simple description of strict field semantics is the result of
a long saga (#20749, the bits about strict data constructors in #21497, #22475),
where we tried a more lenient (but actually not) semantics first that would
allow both strict and lazy implementations of DataCon workers. This was favoured
because the "pervasive effect" throughout the compiler was deemed too large
(when it really turned out to be quite modest).
Alas, this semantics would require us to implement `exprIsHNF` in *exactly* the
same way as above, otherwise the analysis would not be conservative wrt. the
lenient semantics (which includes the strict one). It is also much harder to
explain and maintain, as it turned out.

************************************************************************
*                                                                      *
            In/Out type synonyms
*                                                                      *
*********************************************************************