exprIsDeadEnd is broken
exprIsDeadEnd :: CoreExpr -> Bool
-- See Note [Bottoming expressions]
exprIsDeadEnd e
| isEmptyTy (exprType e)
= True
| otherwise
= go 0 e
where
go n (Var v) = isDeadEndId v && n >= idArity v
go n (App e a) | isTypeArg a = go n e
| otherwise = go (n+1) e
We have
failIO :: forall a. String -> IO a
[Arity = 0 -- unknown arity
, ...]
failIO = failIO1
We call
exprIsDead (App failIO msg)
=> AppCase
go 1 failIO
=> Var case
isDeadEndId failIO && 1 >= idArity failIO
=>
True && n >= 1 >= 0
=>
True
The problem is that we trust idArity
to return a known arity. But it can also return zero if the arity is unknown.
That means for a potentially bottoming function we always get True for exprIsDeadEnd
if it has unknown Arity.