diff options
| author | Simon Peyton Jones <simonpj@microsoft.com> | 2013-01-25 13:30:39 +0000 |
|---|---|---|
| committer | Simon Peyton Jones <simonpj@microsoft.com> | 2013-01-25 13:30:39 +0000 |
| commit | 71221e242ab476501a631d3261d76e86bd4ebf6e (patch) | |
| tree | a8b0fe2e24a5f244fcee5f1e37c890c6c021407f | |
| parent | 8564b7f308104d88bc4da9b742772519c570394b (diff) | |
| download | haskell-71221e242ab476501a631d3261d76e86bd4ebf6e.tar.gz | |
Grotesque hack on Unsafe.Coerce
The hack is described in detail in Note [Meta-hack for coerce].
It's a consequence of this, perfectly legitimate, commit:
commit 7a1480c7c590d4d2fa7a105a4eebf299e921e056
Author: Simon Peyton Jones <simonpj@microsoft.com>
Date: Tue Jan 22 22:43:22 2013 +0000
Allow eta-reduction of eval'd functions if of arity 1
See Note [Eta reduction of an eval'd function] in CoreUtils.
This doesn't fix Trac #7542, but that was the ticket that
pointed out this infelicity.
compiler/coreSyn/CoreUtils.lhs | 24 ++++++++++++++++++++++--
| -rw-r--r-- | libraries/base/Unsafe/Coerce.hs | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/libraries/base/Unsafe/Coerce.hs b/libraries/base/Unsafe/Coerce.hs index 50f52edc4e..a802ba319b 100644 --- a/libraries/base/Unsafe/Coerce.hs +++ b/libraries/base/Unsafe/Coerce.hs @@ -31,10 +31,33 @@ module Unsafe.Coerce (unsafeCoerce) where + #if defined(__GLASGOW_HASKELL__) import GHC.Prim (unsafeCoerce#) + +local_id :: a -> a +local_id x = x -- See Note [Mega-hack for coerce] + +{- Note [Meta-hack for coerce] + +If we just say + unsafeCoerce x = unsafeCoercs# x +then the simple-optimiser that the desugarer runs will eta-reduce to + unsafeCoerce :: forall (a:*) (b:*). a -> b + unsafeCoercs = unsafeCoerce# +And that, sadly, is ill-typed because unsafeCoercs# has OpenKind type variables +And rightly so, becuase we shouldn't be calling unsafeCoerce# in a higher +order way; it has a compulsory unfolding + unsafeCoerce# a b x = x |> UnsafeCo a b +and we really rely on it being inlined pronto. But the simple-optimiser doesn't. +The identity function local_id delays the eta reduction just long enough +for unsafeCoerce# to get inlined. + +Sigh. This is horrible, but then so is unsafeCoerce. +-} + unsafeCoerce :: a -> b -unsafeCoerce x = unsafeCoerce# x +unsafeCoerce x = local_id (unsafeCoerce# x) -- See Note [Unsafe coerce magic] in basicTypes/MkId -- NB: Do not eta-reduce this definition, else the type checker -- give usafeCoerce the same (dangerous) type as unsafeCoerce# |
