template-haskell: reifyConStrictness classifies unlifted typed field as DecidedLazy
Summary
reifyConStrictness
is a function that takes the name of a constructor and gives us the strictness information of the fields from the point of view of the compiler (as opposed to telling us what source annotations the fields were given).
I was surprised to find that for I#
, we get [DecidedLazy]
. I would have expected to be told that this field is DecidedStrict
as an Int#
value cannot be bottom. Admittedly terms like strict and lazy don't make much sense in the presence of unlifted types.
Even if you add explicit bang patterns, you still get told unlifted fields are DecidedLazy
, which makes sense as bang patterns would do nothing for an unlifted field.
This can be worked around by checking if the type of a field is unlifted, but this is an unnecessarily confusing edge case.
Steps to reproduce
run the following ghci script
:set -XTemplateHaskell -XMagicHash
import Language.Haskell.TH.Syntax
import GHC.Exts
$(lift . show =<< reifyConStrictness 'I#)
The output is "[DecidedLazy]"
Expected behavior
I would expect the output to be "[DecidedStrict]"
or maybe we could introduce a new constructor called something like DecidedUnlifted
for this case.
Environment
- GHC version used: 9.2.1