Worker/wrapper should replace absent unlifted args by rubbish literals
#9254 (closed) gave us the following example where demand analysis supposedly messed up:
f :: (() -> (# Int#, () #)) -> ()
-- Strictness signature is
-- <1C1(P(A,1L))>
-- I.e. calls k, but discards first component of result
f k = case k () of (# _, r #) -> r
g :: Int -> ()
g y = f (\n -> (# case y of I# y2 -> y2, n #))
Here, f's strictness signature says (correctly) that it calls its argument
function and ignores the first component of its result.
But in function g, we will evaluate the case y of ...
, because it has type
Int#
. So in the program as written, y
will be evaluated. Hence we must
record this usage of y
, else g
will say y
is absent, and will w/w so
that y
is bound to an absent filler (see Note [Absent fillers]), leading
to a crash when y
is evaluated.
But actually, it would be OK to propagate absence to y
if worker/wrapper
was smart enough to replace the absent argument case y of I# y2 -> y2
with a
suitable absent filler such as RUBBISH[IntRep] @Int#
that doesn't force y
when case-bound.
It would also mean less explaining in DmdAnal, which is always a good thing.