
#13611: Segfault due to levity polymorphism of mkWeak# -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by nomeata):
This is tantamount to unsafePerformIO, is it not?
Not quite, I am not producing a `RealWorld#` token out of thin air. Normal user code calls `mkWeak#` via `mkWeak` in `GHC.Weak`, which is not levity polymorphic. But there is one use of `mkWeak#` in the libraries that seems to use a different `TypeRep`: {{{ addForeignPtrConcFinalizer_ :: ForeignPtrContents -> IO () -> IO () addForeignPtrConcFinalizer_ (PlainForeignPtr r) finalizer = do noFinalizers <- insertHaskellFinalizer r finalizer if noFinalizers then IO $ \s -> case r of { IORef (STRef r#) -> case mkWeak# r# () (unIO $ foreignPtrFinalizer r) s of { (# s1, _ #) -> (# s1, () #) }} else return () }}} The `r#` here is of type `MutVar# s a`, which is `UnliftedRep`; there are similar calls in the modules for for `MVar` and `IORef`. So this is a use case where we want levity polymorphism that allows any *boxed* type, whether lifted or not. Or, the easy way out, is to have two copies of the `mkWeak#` primop, one for `LiftedRep` and one for `UnliftedRep`. They could use the same code and info-pointer. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13611#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler