Skip to content

Make reallyUnsafePtrEquality# levity polymorphic, and use it to subsume pointer comparison primops

sheaf requested to merge sheaf/ghc:T17126 into master

A different approach than the previous MR !5932 (closed) for making reallyUnsafePtrEquality# levity-polymorphic, issue #17126 (closed), was agreed upon:

  1. Change the type of the primop reallyUnsafePtrEquality# to the most general version possible (meaning it should be heterogeneous as well as levity-polymorphic):
reallyUnsafePtrEquality#  :: forall {l1 :: Levity} {l2 :: Levity} 
                                    (a :: TYPE (BoxedRep l1)) (b :: TYPE (BoxedRep l2)).
                             a -> b -> Int#
  1. Add a new internal module, GHC.Ext.PtrEq, which defines pointer equality operations that are now subsumed by reallyUnsafePtrEquality#. These functions are then re-exported by GHC.Exts (so that no function goes missing from the export list of GHC.Exts, which is user-facing). [The functions can't be defined directly in GHC.Exts because other modules in the GHC namespace require access to them, and they can't import GHC.Exts.] More specifically, GHC.Ext.PtrEq defines:
  • A (new) function:
reallyUnsafePtrEquality :: forall (a :: TYPE (BoxedRep Lifted)). a -> a -> Int#
  • Library definitions of ex-primops:

    • sameMutableArray#
    • sameSmallMutableArray
    • sameMutableByteArray#
    • sameMutableArrayArray#
    • sameMutVar#
    • sameTVar#
    • sameMVar#
    • sameIOPort#
    • eqStableName#
  • New functions for comparing non-mutable arrays that were previously missing:

    • sameArray#
    • sameSmallArray#
    • sameByteArray#
    • sameArrayArray#

These were requested in #9192 (closed).

Generally speaking, existing libraries that use reallyUnsafePtrEquality# will continue to work with the new, levity-polymorphic version. But not all! Some (containers, unordered-containers, dependent-map) contain the following:

unsafeCoerce# reallyUnsafePtrEquality# a b

If we make reallyUnsafePtrEquality# levity-polymorphic, this code fails the current GHC representation polymorphism checks.
We agreed that the right solution here is to modify the library; in this case by deleting the call to unsafeCoerce#, since reallyUnsafePtrEquality# is now type-heterogeneous too.

Edited by sheaf

Merge request reports