Skip to content

Unusable UNPACK regression

Summary

Making a recursive field of a sub-substructure strict triggers an "Unusable UNPACK" warning and blocks unpacking.

Steps to reproduce

module UnpackingWeirdness where

data List a = Nil | Cons a !(List a)
data Unconsed a = Unconsed a !(List a)
data MUnconsed a = No | Yes {-# UNPACK #-} !(Unconsed a)

Compiling with -O gives me

[1 of 1] Compiling UnpackingWeirdness ( UnpackingWeirdness.hs, UnpackingWeirdness.o )

UnpackingWeirdness.hs:7:25: warning:
    • Ignoring unusable UNPACK pragma on the first argument of ‘Yes’
    • In the definition of data constructor ‘Yes’
      In the data type declaration for ‘MUnconsed’
  |
7 | data MUnconsed a = No | Yes {-# UNPACK #-} !(Unconsed a)
  |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

-ddump-simpl indicates that unpacking really doesn't happen:

UnpackingWeirdness.$WYes [InlPrag=INLINE[final] CONLIKE]
  :: forall a. Unconsed a %1 -> MUnconsed a
[GblId[DataConWrapper],
 Arity=1,
 Str=<SL>,
 Unf=Unf{Src=StableSystem, TopLvl=True,
         Value=True, ConLike=True, WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
         Tmpl= \ (@a_ahA) (conrep_aiM [Occ=Once1] :: Unconsed a_ahA) ->
                 case conrep_aiM of conrep1_aiM [Occ=Once1] { __DEFAULT ->
                 UnpackingWeirdness.Yes @a_ahA conrep1_aiM
                 }}]
UnpackingWeirdness.$WYes
  = \ (@a_ahA) (conrep_aiM [Occ=Once1] :: Unconsed a_ahA) ->
      case conrep_aiM of conrep1_aiM [Occ=Once1] { __DEFAULT ->
      UnpackingWeirdness.Yes @a_ahA conrep1_aiM
      }

Expected behavior

If the List a field of the Cons constructor above is made lazy, then the field of Yes is unpacked, and no warning is issued. I expect the same thing to happen with the field strict.

GHC 9.4 behaved as expected in this regard.

Environment

  • GHC version used: 9.6.1

Optional:

  • Operating System:
  • System Architecture:
Edited by David Feuer
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information