Bignum literals aren't always considered as constructor applications
Reproducer:
module Bug where
import GHC.Num.Integer
foo :: Int
foo = case 2 of
IS _ -> 9999
IP _ -> 0
IN _ -> 0
Even with -O2
with HEAD we get the following Core:
foo2 = I# 9999#
foo1 = I# 0#
foo3 = 2
foo
= case foo3 of {
IS ds_dxZ -> foo2;
IP ds_dy0 -> foo1;
IN ds_dy1 -> foo1
}
while we would expect:
foo = I# 9999#
It's because bignum literals are only desugared into IS/IN/IP constructor applications in Core prep; after Core optimisations. In some places (e.g. rules) we are careful to match on both bignum literal representations but usually to extract a Literal
from a ConApp
(e.g. IS 2# ==> 2
). We would have to do the same in the opposite direction but exprIsConApp_maybe
currently doesn't handle bignum literals.
I've found this while working on #15327 (closed). Luckily I already have a branch that fixes this because having two representations in Core for bignum literals already bothered me. Instead of adding another special case to exprIsConApp_maybe
, it removes Integer and Natural literals to only keep BigNat#
literals.