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. MutVar
s). 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.