summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorOleg Grenrus <oleg.grenrus@iki.fi>2022-10-03 00:33:59 +0300
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-11-22 15:59:34 -0500
commit9d61c182739c415f4283cca3c692e25c82b274f1 (patch)
tree4debe3aefebe1dbe8bba15d2fa3c6a105af1e846 /compiler
parentde5fb3489f2a9bd6dc75d0cb8925a27fe9b9084b (diff)
downloadhaskell-9d61c182739c415f4283cca3c692e25c82b274f1.tar.gz
Add unsafePtrEquality# restricted to UnliftedTypes
Diffstat (limited to 'compiler')
-rw-r--r--compiler/GHC/Builtin/primops.txt.pp56
1 files changed, 37 insertions, 19 deletions
diff --git a/compiler/GHC/Builtin/primops.txt.pp b/compiler/GHC/Builtin/primops.txt.pp
index 1fc7bd5f23..617abe5f9e 100644
--- a/compiler/GHC/Builtin/primops.txt.pp
+++ b/compiler/GHC/Builtin/primops.txt.pp
@@ -3429,29 +3429,47 @@ primop ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp
-- The primop `reallyUnsafePtrEquality#` does a direct pointer
-- equality between two (boxed) values. Several things to note:
--
--- * It is levity-polymorphic. It works for TYPE (BoxedRep Lifted) and
--- TYPE (BoxedRep Unlifted). But not TYPE IntRep, for example.
--- This levity-polymorphism comes from the use of the type variables
--- "v" and "w". See Note [Levity and representation polymorphic primops]
+-- (PE1) It is levity-polymorphic. It works for TYPE (BoxedRep Lifted) and
+-- TYPE (BoxedRep Unlifted). But not TYPE IntRep, for example.
+-- This levity-polymorphism comes from the use of the type variables
+-- "v" and "w". See Note [Levity and representation polymorphic primops]
--
--- * It does not evaluate its arguments. The user of the primop is responsible
--- for doing so.
+-- (PE2) It is hetero-typed; you can compare pointers of different types.
+-- This is used in various packages such as containers & unordered-containers.
--
--- * It is hetero-typed; you can compare pointers of different types.
--- This is used in various packages such as containers & unordered-containers.
+-- (PE3) It does not evaluate its arguments. The user of the primop is responsible
+-- for doing so. Consider
+-- let { x = p+q; y = q+p } in reallyUnsafePtrEquality# x y
+-- Here `x` and `y` point to different closures, so the expression will
+-- probably return False; but if `x` and/or `y` were evaluated for some
+-- other reason, then it might return True.
--
--- * It is obviously very dangerous, because
--- let x = f y in reallyUnsafePtrEquality# x x
--- will probably return True, whereas
--- reallyUnsafePtrEquality# (f y) (f y)
--- will probably return False. ("probably", because it's affected
--- by CSE and inlining).
+-- (PE4) It is obviously very dangerous, because replacing equals with equals
+-- in the program can change the result. For example
+-- let x = f y in reallyUnsafePtrEquality# x x
+-- will probably return True, whereas
+-- reallyUnsafePtrEquality# (f y) (f y)
+-- will probably return False. ("probably", because it's affected
+-- by CSE and inlining).
--
--- * reallyUnsafePtrEquality# can't fail, but it is marked as such
--- to prevent it from floating out.
--- See Note [reallyUnsafePtrEquality# can_fail]
+-- (PE5) reallyUnsafePtrEquality# can't fail, but it is marked as such
+-- to prevent it from floating out.
+-- See Note [reallyUnsafePtrEquality# can_fail]
--
--- The library GHC.Exts provides several less Wild-West functions
+-- The library GHC.Prim.PtrEq (and GHC.Exts) provides
+--
+-- unsafePtrEquality# ::
+-- forall (a :: UnliftedType) (b :: UnliftedType). a -> b -> Int#
+--
+-- It is still heterotyped (like (PE2)), but it's restricted to unlifted types
+-- (unlike (PE1)). That means that (PE3) doesn't apply: unlifted types are
+-- always evaluated, which makes it a bit less unsafe.
+--
+-- However unsafePtrEquality# is /implemented/ by a call to
+-- reallyUnsafePtrEquality#, so using the former is really just a documentation
+-- hint to the reader of the code. GHC behaves no differently.
+--
+-- The same library provides less Wild-West functions
-- for use in specific cases, namely:
--
-- reallyUnsafePtrEquality :: a -> a -> Int# -- not levity-polymorphic, nor hetero-typed
@@ -3469,7 +3487,7 @@ primop ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp
-- sameIOPort# :: IOPort# s a -> IOPort# s a -> Int#
-- eqStableName# :: StableName# a -> StableName# b -> Int#
--
--- These operations are all specialisations of reallyUnsafePtrEquality#.
+-- These operations are all specialisations of unsafePtrEquality#.
-- Note [reallyUnsafePtrEquality# can_fail]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~