Skip to content

Unevaluated values in strict fields.

Summary

For a constructor of the form MkT !a I would expect all fields to be evaluated, even if the actual pointer at runtime might reference a indirection to the evaluated object.

However in parts of cabal we get these definitions (core output)


-- RHS size: {terms: 17, types: 28, coercions: 0, joins: 0/0}
lvl113_rF5y :: Data.ByteString.Internal.ByteString
[GblId]
lvl113_rF5y
  = case ghc-prim-0.6.1:GHC.Prim.newMutVar#
           @ GHC.ForeignPtr.Finalizers
           @ ghc-prim-0.6.1:GHC.Prim.RealWorld
           GHC.ForeignPtr.NoFinalizers
           ghc-prim-0.6.1:GHC.Prim.realWorld#
    of
    { (# ipv_atj5, ipv1_atj6 #) ->
    case {__pkg_ccall bytestring-0.10.9.0 Addr#
                                 -> State# RealWorld -> (# State# RealWorld, Word# #)}_atj4
           addr#40_rF5x ipv_atj5
    of
    { (# ds_atja, ds2_atjb #) ->
    Data.ByteString.Internal.PS
      addr#40_rF5x
      (GHC.ForeignPtr.PlainForeignPtr ipv1_atj6)
      0#
      (ghc-prim-0.6.1:GHC.Prim.word2Int# ds2_atjb)
    }
    }

-- RHS size: {terms: 5, types: 3, coercions: 0, joins: 0/0}
lvl197_rFaq :: Data.Set.Internal.Set FieldName
[GblId, Str=m1, Unf=OtherCon []]
lvl197_rFaq
  = Data.Set.Internal.Bin
      @ FieldName
      1#
      lvl113_rF5y
      (Data.Set.Internal.Tip @ FieldName)
      (Data.Set.Internal.Tip @ FieldName)

In particular lvl197_rFaq is a Bin constructor with all strict fields Bin {-# UNPACK #-} !Size !a !(Set a) !(Set a)
lvl197_rFaq is also marked as being in WHNF (Unf=OtherCon []). However it clearly contains the binding lvl113_rF5y which is NOT in WHNF.

As far as I can tell this violates the semantics defined in the Haskell Report.

Steps to reproduce

This happens when compiling FieldGrammar.hs file bundled with the cabal submodule for GHC commit 2fd1ed54 using -O

Also reproduceable with:

git clone https://github.com/haskell/cabal
cd cabal
cabal new-build Cabal --ghc-options="-ddump-simpl -ddump-to-file"

locate the "FieldGrammar.dump-simpl" file look for top level Bin constructors with a lvl* argument. This pattern seems pretty common in this module.

Expected behavior

I would expect lvl197_rFaq to evaluate lvl113_rF5y before constructing the Bin.

Environment

  • GHC version used: Commit 2fd1ed54, reproduced with 8.6.5

Optional:

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