ghc-heap's closure_size test is fragile, and runs on invalid ways
The closure_size
test checks sizes of some closures. The problem is type of
the closure passed to the primop (closureSize#
) depends on optimisations and
other compile parameters. For example:
pap :: Int -> Char -> Int
pap x _ = x
{-# NOINLINE pap #-}
main :: IO ()
main = assertSize (pap 1) 2
Here the assumption is that pap 1
will be represented as a PAP
with one pointer in the payload, but that's
not necessarily the case. If I compile this program with -O
I get this STG:
Main.main3 :: GHC.Types.Int
[GblId] =
\u []
case Main.$wpap 1# of v_s5gb [Occ=Once] {
__DEFAULT -> GHC.Types.I# [v_s5gb];
};
Main.main2 :: GHC.Types.Char -> GHC.Types.Int
[GblId, Arity=1, Str=<L,A>, Unf=OtherCon []] =
\r [w_s5gc] Main.main3;
Main.main1
:: GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
[GblId, Arity=1, Str=<L,U>, Unf=OtherCon []] =
\r [void_0E]
Main.$wassertSize
Main.main5 Main.main4 Main.main2 2# GHC.Prim.void#;
We check size of main2
, which is assumed to be a PAP
with one pointer in the
payload (hence size 2), but with this optimisation settings it's actually
compiled to a FUN
with no pointers or non-pointers (hence size 1), which
causes the test to fail.
Another failure happens when we run this in profiling mode, which adds one word to every closure, causes basically all of the tests to fail.