Demand analyser triggers Lint error
@sgraf812 Consider this module:
module Foo where
{-# NOINLINE app #-}
app :: Int -> (Int -> Int) -> Int
app x f = if x>0 then f x else 0
foo :: String -> Bool -> Bool -> Int -> Int
foo s b b2 y = app y (let {-# NOINLINE j #-}
j :: Int -> Int
j = \z -> error s
in case b of
True -> j
False -> case b2 of
True -> \x -> x-1
False -> j)
Compile with -O, and we get
*** Core Lint errors : in result of Demand analysis (including Boxity) ***
Foo.hs:8:12: warning:
idArity 1 exceeds arity imposed by the strictness signature b{aJo->S
sQD->S}: j_sQs
In the RHS of foo :: String -> Bool -> Bool -> Int -> Int
In the body of lambda with binder s_aJo :: String
In the body of lambda with binder b_aJp :: Bool
In the body of lambda with binder b2_aJq :: Bool
In the body of lambda with binder y_aJr :: Int
Substitution: <InScope = {}
IdSubst = []
TvSubst = []
CvSubst = []>
Diagnosis
We get
foo
= \ (s_aJo [Dmd=LS] :: String)
(b_aJp [Dmd=ML] :: Bool)
(b2_aJq [Dmd=ML] :: Bool)
(y_aJr [Dmd=1L] :: Int) ->
app
y_aJr
(join {
j_sQs [InlPrag=NOINLINE, Dmd=MC(1,L)] :: Int -> Int
[LclId[JoinId(0)(Nothing)],
Arity=1,
Str=b{aJo->S sQD->S},
Cpr=b,
Unf=Unf{Src=<vanilla>, TopLvl=False,
Value=True, ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [0] 20 0}]
j_sQs = \ _ [Occ=Dead, Dmd=B] -> lvl_sQD s_aJo } in
case b_aJp of {
False ->
case b2_aJq of {
False -> jump j_sQs;
True -> lvl_sQE
};
True -> jump j_sQs
})
Note that j
's strictness signature is just b
, even though it manifestly has a value argument. That's what
the complaint is about.
Why? Because we analysed its RHS with a demand of C(1,L)
, beucase the app
context calls it.
I can't quite figure out if it's a legitimate signature for j
-- it looks wrong; but then we are analysing it with a stronger demand than strictness signatures are built for.
See Note [Demand analysis for join points]
in DmdAnal.