Skip to content

Adding a type signature changes heap allocation into stack allocation without changing the actual type

According to Milan Straka, changing

insert :: Ord k => k -> a -> Map k a -> Map k a
insert = go
  where
    STRICT_1_OF_3(go)
    go kx x Tip = singleton kx x
    go kx x (Bin sz ky y l r) = ...

to

insert :: Ord k => k -> a -> Map k a -> Map k a
insert = go
  where
    go :: Ord k => k -> a -> Map k a -> Map k a
    STRICT_1_OF_3(go)
    go kx x Tip = singleton kx x
    go kx x (Bin sz ky y l r) = ...

changes how GHC allocates the argument, from heap to stack. Here's the relevant commit: https://github.com/haskell/containers/commit/32d84ba5eb82f34dbb8a8fabf07077d848cdb408

It includes this comment:

-- [Note: Type of local 'go' function]
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-- If the local 'go' function uses an Ord class, it must be given a type
-- which mentions this Ord class. Otherwise it is not passed as an argument and
-- it is instead heap-allocated at the entry of the outer method.

I find this quite alarming. The type of k above is already Ord k, so the extra type signature shouldn't make a difference in my opinion.

Trac metadata
Trac field Value
Version 7.4.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information