Skip to content

Be more up-front about fragility of `StableName` and `WeakPtr` in the presence of worker-wrapper

The worker-wrapper transform can introduce reboxing of constructor closures. For instance, we might in principle transform:

f :: Maybe Int -> Maybe Int
f x = x

into the following STG:

f :: Maybe Int -> Maybe Int
f = \x -> case x of
            Just y -> let result = Just y
                      in result
            Nothing -> Nothing

See #2289 #4874 (closed), #8032, #10649 (closed) for cases where this happens in practice

This reboxing is usually okay (and sometimes even desirable) since Haskell programs generally don't rely on object identity.

However, there are two mechanisms which allow the user to observe object identity and therefore may break in due to this transform:

  • in the case of a WeakPtr to a standard constructor closure reboxing may result in a finalizer being run while the resource is still reachable.
  • in the case of StableName, we may return two different names for the "same" object.

Really, both of these mechanisms are only truly safe when used with "primitive" objects which cannot be reboxed (e.g. MutVars). However, many users seem to be unaware of this issue. At very least we should state this caveat loudly in the documentation for these two mechanisms. There is currently a small note in System.Mem.Weak but it isn't nearly loud enough, in my opinion. StableName seems pretty up-front about its approximate nature, but I've nevertheless seen more than one user suggest that it be used as a precise object identifier.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information