Skip to content

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.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information