summaryrefslogtreecommitdiff
path: root/libraries/ghc-prim
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2021-04-13 18:17:19 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-04-29 17:27:54 -0400
commit5981ac7d83810d26d74a07bbc452a0be278de66c (patch)
tree6681ca9ff678352669f763666e7734ed22143fc6 /libraries/ghc-prim
parent7d18e1bace3f3a85eae177654690d91b688c0e8f (diff)
downloadhaskell-5981ac7d83810d26d74a07bbc452a0be278de66c.tar.gz
Redesign withDict (formerly magicDict)
This gives a more precise type signature to `magicDict` as proposed in #16646. In addition, this replaces the constant-folding rule for `magicDict` in `GHC.Core.Opt.ConstantFold` with a special case in the desugarer in `GHC.HsToCore.Expr.dsHsWrapped`. I have also renamed `magicDict` to `withDict` in light of the discussion in https://mail.haskell.org/pipermail/ghc-devs/2021-April/019833.html. All of this has the following benefits: * `withDict` is now more type safe than before. Moreover, if a user applies `withDict` at an incorrect type, the special-casing in `dsHsWrapped` will now throw an error message indicating what the user did incorrectly. * `withDict` can now work with classes that have multiple type arguments, such as `Typeable @k a`. This means that `Data.Typeable.Internal.withTypeable` can now be implemented in terms of `withDict`. * Since the special-casing for `withDict` no longer needs to match on the structure of the expression passed as an argument to `withDict`, it no longer cares about the presence or absence of `Tick`s. In effect, this obsoletes the fix for #19667. The new `T16646` test case demonstrates the new version of `withDict` in action, both in terms of `base` functions defined in terms of `withDict` as well as in terms of functions from the `reflection` and `singletons` libraries. The `T16646Fail` test case demonstrates the error message that GHC throws when `withDict` is applied incorrectly. This fixes #16646. By adding more tests for `withDict`, this also fixes #19673 as a side effect.
Diffstat (limited to 'libraries/ghc-prim')
-rw-r--r--libraries/ghc-prim/GHC/Magic/Dict.hs44
-rw-r--r--libraries/ghc-prim/changelog.md26
-rw-r--r--libraries/ghc-prim/ghc-prim.cabal1
3 files changed, 69 insertions, 2 deletions
diff --git a/libraries/ghc-prim/GHC/Magic/Dict.hs b/libraries/ghc-prim/GHC/Magic/Dict.hs
new file mode 100644
index 0000000000..12861db568
--- /dev/null
+++ b/libraries/ghc-prim/GHC/Magic/Dict.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE ImpredicativeTypes #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE Unsafe #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module : GHC.Magic.Dict
+-- Copyright : (c) The University of Glasgow 2009
+-- License : see libraries/ghc-prim/LICENSE
+--
+-- Maintainer : cvs-ghc@haskell.org
+-- Stability : internal
+-- Portability : non-portable (GHC Extensions)
+--
+-- Defines the 'withDict' function. For more information, see
+-- @Note [withDict]@ in "GHC.HsToCore.Expr" in GHC.
+-- The definition of 'withDict' is located in a separate module from
+-- "GHC.Magic" because 'withDict' is @Unsafe@ (it threatens type class
+-- coherence) while "GHC.Magic" is @Trustworthy@.
+--
+-- Use "GHC.Exts" from the @base@ package instead of importing this
+-- module directly.
+--
+-----------------------------------------------------------------------------
+
+module GHC.Magic.Dict (withDict) where
+
+import GHC.Prim.Panic (panicError)
+import GHC.Types (RuntimeRep, TYPE)
+
+-- | @'withDict' d f@ provides a way to call a type-class–overloaded function
+-- @f@ by applying it to the supplied dictionary @d@.
+--
+-- 'withDict' can only be used if the type class has a single method with no
+-- superclasses. For more (important) details on how this works, see
+-- @Note [withDict]@ in "GHC.HsToCore.Expr" in GHC.
+withDict :: forall {rr :: RuntimeRep} st dt (r :: TYPE rr). st -> (dt => r) -> r
+{-# NOINLINE withDict #-}
+withDict = panicError "Non-rewritten withDict"#
diff --git a/libraries/ghc-prim/changelog.md b/libraries/ghc-prim/changelog.md
index 6c7723068f..1ce61e2e61 100644
--- a/libraries/ghc-prim/changelog.md
+++ b/libraries/ghc-prim/changelog.md
@@ -1,3 +1,25 @@
+## next (edit as necessary)
+
+- `magicDict` has been renamed to `withDict` and is now defined in
+ `GHC.Magic.Dict` instead of `GHC.Prim`. `withDict` now has the type:
+
+ ```
+ withDict :: forall {rr :: RuntimeRep} st dt (r :: TYPE rr). st -> (dt => r) -> r
+ ```
+
+ Unlike `magicDict`, `withDict` can be used without defining an
+ intermediate data type. For example, the `withTypeable` function from the
+ `Data.Typeable` module can now be defined as:
+
+ ```
+ withTypeable :: forall k (a :: k) rep (r :: TYPE rep). ()
+ => TypeRep a -> (Typeable a => r) -> r
+ withTypeable rep k = withDict @(TypeRep a) @(Typeable a) rep k
+ ```
+
+ Note that the explicit type applications are required, as the call to
+ `withDict` would be ambiguous otherwise.
+
## 0.8.0 (edit as necessary)
- Change array access primops to use type with size maxing the element size:
@@ -23,7 +45,7 @@
- Add known-key `cstringLength#` to `GHC.CString`. This is just the
C function `strlen`, but a built-in rewrite rule allows GHC to
compute the result at compile time when the argument is known.
-
+
- In order to support unicode better the following functions in `GHC.CString`
gained UTF8 counterparts:
@@ -47,7 +69,7 @@
atomicCasAddrAddr# :: Addr# -> Addr# -> Addr# -> State# s -> (# State# s, Addr# #)
atomicCasWordAddr# :: Addr# -> Word# -> Word# -> State# s -> (# State# s, Word# #)
-- Add an explicit fixity for `(~)` and `(~~)`:
+- Add an explicit fixity for `(~)` and `(~~)`:
infix 4 ~, ~~
diff --git a/libraries/ghc-prim/ghc-prim.cabal b/libraries/ghc-prim/ghc-prim.cabal
index 05fd60f09a..61840021c1 100644
--- a/libraries/ghc-prim/ghc-prim.cabal
+++ b/libraries/ghc-prim/ghc-prim.cabal
@@ -45,6 +45,7 @@ Library
GHC.Debug
GHC.IntWord64
GHC.Magic
+ GHC.Magic.Dict
GHC.Prim.Ext
GHC.Prim.Panic
GHC.Prim.Exception