Skip to content

Commit

Permalink
Remove a 'unsafeCoerce' from 'Unsafe.coerce' (#330)
Browse files Browse the repository at this point in the history
Previously, the linear `Unsafe.coerce` was implemented using two
`unsafeCoerce`'s, one to get a function `a -> b`, and another one to
cast that function to be a linear one.

After the unsafe equality proofs change[1], we have a
`unsafeEqualityProof` function to cast two types to be the same without
looking at the value, so we can linearly return it, removing the need
for the outer `unsafeCoerce`.

This removes one allocation from the generated STG code for
'Data.Array.Unlifted.get', improving the performance slightly.

[1]: https://gitlab.haskell.org/ghc/ghc/-/commit/74ad75e87317196c600dfabc61aee1b87d95c214
  • Loading branch information
utdemir authored Jun 11, 2021
1 parent 5317854 commit 566a804
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/Unsafe/Linear.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE LinearTypes #-}

Expand Down Expand Up @@ -29,8 +32,11 @@ import qualified Unsafe.Coerce as NonLinear
import GHC.Exts (TYPE, RuntimeRep)

-- | Linearly typed @unsafeCoerce@
coerce :: a %1-> b
coerce = NonLinear.unsafeCoerce NonLinear.unsafeCoerce
coerce :: forall a b. a %1-> b
coerce a =
case NonLinear.unsafeEqualityProof @a @b of
NonLinear.UnsafeRefl -> a
{-# INLINE coerce #-}

-- | Converts an unrestricted function into a linear function
toLinear
Expand Down

0 comments on commit 566a804

Please sign in to comment.