Note [Dealing with bottom]
GHC does some transformations that are technically unsound wrt
bottom, because doing so improves arities... a lot! We describe
them in this Note.
The flag -fpedantic-bottoms (off by default) restore technically
correct behaviour at the cots of efficiency.
It's mostly to do with eta-expansion. Consider
f = \x -> case x of
True -> \s -> e1
False -> \s -> e2
This happens all the time when f :: Bool -> IO ()
In this case we do eta-expand, in order to get that \s to the
top, and give f arity 2.
This isn't really right in the presence of seq. Consider
(f bot) `seq` 1
This should diverge! But if we eta-expand, it won't. We ignore this
"problem" (unless -fpedantic-bottoms is on), because being scrupulous
would lose an important transformation for many programs. (See
#5587 for an example.)
Consider also
f = \x -> error "foo"
Here, arity 1 is fine. But if it looks like this (see #22068)
f = \x -> case x of
True -> error "foo"
False -> \y -> x+y
then we want to get arity 2. Technically, this isn't quite right, because
(f True) `seq` 1
should diverge, but it'll converge if we eta-expand f. Nevertheless, we
do so; it improves some programs significantly, and increasing convergence
isn't a bad thing. Hence the ABot/ATop in ArityType.
So these two transformations aren't always the Right Thing, and we
have several tickets reporting unexpected behaviour resulting from
this transformation. So we try to limit it as much as possible:
(1) Do NOT move a lambda outside a known-bottom case expression
case undefined of { (a,b) -> \y -> e }
This showed up in #5557
(2) Do NOT move a lambda outside a case unless
(a) The scrutinee is ok-for-speculation, or
(b) more liberally: the scrutinee is cheap (e.g. a variable), and
-fpedantic-bottoms is not enforced (see #2915 for an example)
Of course both (1) and (2) are readily defeated by disguising the bottoms.
There also is an interaction with Note [Combining arity type with demand info],
outlined in Wrinkle (CAD1). References 1
- Combining arity type with demand info GHC.Core.Opt.Arity
Referenced by 5
- GHC.Core.Opt.Arity call site ×3
- Strict fields in Core GHC.Core
- Combining arity type with demand info GHC.Core.Opt.Arity