Note [Return non-recursive bindings in dependency order]
For recursive bindings, the desugarer has no choice: it returns a single big
Rec{...} group.
But for /non-recursive/ bindings, the desugarer guarantees to desugar them to
a sequence of non-recurive Core bindings, in dependency order.
Why is this important? Partly it saves a bit of work in the first run of the
occurrence analyser. But more importantly, for linear types, non-recursive lets
can be linear whereas recursive-let can't. Since we check the output of the
desugarer for linearity (see also Note [Linting linearity]), desugaring
non-recursive lets to recursive lets would break linearity checks. An
alternative is to refine the typing rule for recursive lets so that we don't
have to care (see in particular #23218 and #18694), but the outcome of this line
of work is still unclear. In the meantime, being a little precise in the
desugarer is cheap. (paragraph written on 2023-06-09)
In dsLHSBinds (and dependencies), a single binding can be desugared to multiple
bindings. For instance because the source binding has the {-# SPECIALIZE # References 1
- Linting linearity GHC.Core.Lint
Referenced by 4
- GHC.HsToCore.Binds call site ×2
- The no-tyvar no-dict case GHC.HsToCore.Binds
- GHC.HsToCore.Expr call site