[Git][ghc/ghc][wip/andreask/cast_any] Improve documentation of @Any@ type.
Andreas Klebinger (@AndreasK)
gitlab at gitlab.haskell.org
Wed May 22 13:29:00 UTC 2024
Andreas Klebinger pushed to branch wip/andreask/cast_any at Glasgow Haskell Compiler / GHC
Commits:
cb16f2bd by Andreas Klebinger at 2024-05-22T15:13:25+02:00
Improve documentation of @Any@ type.
In particular mention possible uses for non-lifted types.
Fixes #23100.
- - - - -
2 changed files:
- compiler/GHC/Builtin/Types.hs
- libraries/ghc-prim/GHC/Types.hs
Changes:
=====================================
compiler/GHC/Builtin/Types.hs
=====================================
@@ -445,7 +445,11 @@ It has these properties:
* When instantiated at a lifted type it is inhabited by at least one value,
namely bottom
- * You can safely coerce any /lifted/ type to Any, and back with unsafeCoerce.
+ * You can safely coerce any type to Any, and back with unsafeCoerce if the type
+ is lifted. By using unsafeCoerce# we can do the same for *all* types as long as
+ the kinds match up.
+ However for lifted types unsafeCoerce should be used over unsafeCoerce# if
+ possible.
* It does not claim to be a *data* type, and that's important for
the code generator, because the code gen may *enter* a data value
=====================================
libraries/ghc-prim/GHC/Types.hs
=====================================
@@ -283,11 +283,44 @@ data Symbol
* *
********************************************************************* -}
--- | The type constructor 'Any' is type to which you can unsafely coerce any
--- lifted type, and back. More concretely, for a lifted type @t@ and
--- value @x :: t@, @unsafeCoerce (unsafeCoerce x :: Any) :: t@ is equivalent
--- to @x at .
+-- | The type constructor @Any :: forall k. k@ is a type to which you can unsafely coerce any type, and back.
--
+-- For @unsafeCoerce@ this means for all lifted types @t@ that
+-- @unsafeCoerce (unsafeCoerce x :: Any) :: t@ is equivalent to @x@ and safe.
+--
+-- The same is true for *all* types when using unsafeCoerce# like this:
+-- @unsafeCoerce# (unsafeCoerce# x :: (Any :: TYPE r)) :: (t :: TYPE r)@.
+-- But users should always prefer unsafeCoerce over unsafeCoerce# when possible.
+--
+-- For example, if @x :: t@ and @t :: Type@, you can do this:
+--
+-- @
+-- a :: Any @Type
+-- a = unsafeCoerce x
+-- x2 :: t
+-- x2 = unsafeCoerce a
+-- @
+--
+-- But you must obey the following rule: do not change the *kind* of the type you are coercing. For example:
+-- @
+-- a1 :: Any @(TYPE 'IntRep)
+-- a1 = unsafeCoerce# True
+--
+-- a2 :: Any @(TYPE ('BoxedRep 'UnliftedRep))
+-- a2 = unsafeCoerce# True
+-- @
+-- Here @a1@ is bad because we started with @True :: (Bool :: Type)@, represented by a boxed heap pointer,
+-- and coerced it to @a1 :: Any @(TYPE 'IntRep)@, whose representation is a non-pointer integer.
+-- That's why we had to use `unsafeCoerce#`; it is really unsafe because it can change representations.
+-- Similarly @a2@ is bad because although both @True@ and @a2@ are represented by a heap pointer,
+-- @True@ is lifted but @a2@ is not; bugs here may be rather subtle.
+--
+-- To cast a boxed unlifted type to `Any`, type annotations are recommended
+-- to make sure that @Any@ has the correct kind. (Coercion between lifted and unlifted types is unsound.)
+-- For example, for some @b :: ByteArray#@:
+-- @
+-- unsafeCoerce# b :: (Any :: TYPE ('BoxedRep 'Unlifted))
+-- @
type family Any :: k where { }
-- See Note [Any types] in GHC.Builtin.Types. Also, for a bit of history on Any see
-- #10886. Note that this must be a *closed* type family: we need to ensure
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cb16f2bd0b463a97d626ed1d6b7f600f2db12b64
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cb16f2bd0b463a97d626ed1d6b7f600f2db12b64
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240522/c96f4c58/attachment-0001.html>
More information about the ghc-commits
mailing list