summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/Plugin.hs
diff options
context:
space:
mode:
authorsheaf <sam.derbyshire@gmail.com>2021-08-13 14:40:16 +0200
committersheaf <sam.derbyshire@gmail.com>2021-08-13 14:40:16 +0200
commit9d4ba36f1de7ced62e2c0c6a911411144e9a3b27 (patch)
treec04b9b349cc34ae9f1f194f56519c679a0bd9fc7 /compiler/GHC/Tc/Plugin.hs
parentc367b39e5236b86b4923d826ab0395b33211d30a (diff)
downloadhaskell-9d4ba36f1de7ced62e2c0c6a911411144e9a3b27.tar.gz
Add rewriting to typechecking plugins
Type-checking plugins can now directly rewrite type-families. The TcPlugin record is given a new field, tcPluginRewrite. The plugin specifies how to rewrite certain type-families with a value of type `UniqFM TyCon TcPluginRewriter`, where: type TcPluginRewriter = RewriteEnv -- Rewriter environment -> [Ct] -- Givens -> [TcType] -- type family arguments -> TcPluginM TcPluginRewriteResult data TcPluginRewriteResult = TcPluginNoRewrite | TcPluginRewriteTo { tcPluginRewriteTo :: Reduction , tcRewriterNewWanteds :: [Ct] } When rewriting an exactly-saturated type-family application, GHC will first query type-checking plugins for possible rewritings before proceeding. Includes some changes to the TcPlugin API, e.g. removal of the EvBindsVar parameter to the TcPluginM monad.
Diffstat (limited to 'compiler/GHC/Tc/Plugin.hs')
-rw-r--r--compiler/GHC/Tc/Plugin.hs61
1 files changed, 31 insertions, 30 deletions
diff --git a/compiler/GHC/Tc/Plugin.hs b/compiler/GHC/Tc/Plugin.hs
index 78a0ebd16a..a62ac86734 100644
--- a/compiler/GHC/Tc/Plugin.hs
+++ b/compiler/GHC/Tc/Plugin.hs
@@ -47,7 +47,6 @@ module GHC.Tc.Plugin (
-- * Manipulating evidence bindings
newEvVar,
setEvBind,
- getEvBindsTcPluginM
) where
import GHC.Prelude
@@ -62,30 +61,30 @@ import qualified GHC.Unit.Finder as Finder
import GHC.Core.FamInstEnv ( FamInstEnv )
import GHC.Tc.Utils.Monad ( TcGblEnv, TcLclEnv, TcPluginM
- , unsafeTcPluginTcM, getEvBindsTcPluginM
+ , unsafeTcPluginTcM
, liftIO, traceTc )
import GHC.Tc.Types.Constraint ( Ct, CtLoc, CtEvidence(..), ctLocOrigin )
import GHC.Tc.Utils.TcMType ( TcTyVar, TcType )
import GHC.Tc.Utils.Env ( TcTyThing )
import GHC.Tc.Types.Evidence ( CoercionHole, EvTerm(..)
- , EvExpr, EvBind, mkGivenEvBind )
+ , EvExpr, EvBindsVar, EvBind, mkGivenEvBind )
import GHC.Types.Var ( EvVar )
-import GHC.Unit.Module
-import GHC.Types.Name
-import GHC.Types.TyThing
+import GHC.Unit.Module ( ModuleName, Module )
+import GHC.Types.Name ( OccName, Name )
+import GHC.Types.TyThing ( TyThing )
import GHC.Core.Reduction ( Reduction )
-import GHC.Core.TyCon
-import GHC.Core.DataCon
-import GHC.Core.Class
-import GHC.Driver.Config.Finder
-import GHC.Driver.Env
-import GHC.Utils.Outputable
-import GHC.Core.Type
-import GHC.Types.Id
-import GHC.Core.InstEnv
-import GHC.Data.FastString
-import GHC.Types.Unique
+import GHC.Core.TyCon ( TyCon )
+import GHC.Core.DataCon ( DataCon )
+import GHC.Core.Class ( Class )
+import GHC.Driver.Config.Finder ( initFinderOpts )
+import GHC.Driver.Env ( HscEnv(..), hsc_home_unit, hsc_units )
+import GHC.Utils.Outputable ( SDoc )
+import GHC.Core.Type ( Kind, Type, PredType )
+import GHC.Types.Id ( Id )
+import GHC.Core.InstEnv ( InstEnvs )
+import GHC.Data.FastString ( FastString )
+import GHC.Types.Unique ( Unique )
-- | Perform some IO, typically to interact with an external tool.
@@ -162,9 +161,8 @@ zonkTcType = unsafeTcPluginTcM . TcM.zonkTcType
zonkCt :: Ct -> TcPluginM Ct
zonkCt = unsafeTcPluginTcM . TcM.zonkCt
-
-- | Create a new wanted constraint.
-newWanted :: CtLoc -> PredType -> TcPluginM CtEvidence
+newWanted :: CtLoc -> PredType -> TcPluginM CtEvidence
newWanted loc pty
= unsafeTcPluginTcM (TcM.newWanted (ctLocOrigin loc) Nothing pty)
@@ -172,26 +170,29 @@ newWanted loc pty
newDerived :: CtLoc -> PredType -> TcPluginM CtEvidence
newDerived loc pty = return CtDerived { ctev_pred = pty, ctev_loc = loc }
--- | Create a new given constraint, with the supplied evidence. This
--- must not be invoked from 'tcPluginInit' or 'tcPluginStop', or it
--- will panic.
-newGiven :: CtLoc -> PredType -> EvExpr -> TcPluginM CtEvidence
-newGiven loc pty evtm = do
+-- | Create a new given constraint, with the supplied evidence.
+--
+-- This should only be invoked within 'tcPluginSolve'.
+newGiven :: EvBindsVar -> CtLoc -> PredType -> EvExpr -> TcPluginM CtEvidence
+newGiven tc_evbinds loc pty evtm = do
new_ev <- newEvVar pty
- setEvBind $ mkGivenEvBind new_ev (EvExpr evtm)
+ setEvBind tc_evbinds $ mkGivenEvBind new_ev (EvExpr evtm)
return CtGiven { ctev_pred = pty, ctev_evar = new_ev, ctev_loc = loc }
-- | Create a fresh evidence variable.
+--
+-- This should only be invoked within 'tcPluginSolve'.
newEvVar :: PredType -> TcPluginM EvVar
newEvVar = unsafeTcPluginTcM . TcM.newEvVar
-- | Create a fresh coercion hole.
+-- This should only be invoked within 'tcPluginSolve'.
newCoercionHole :: PredType -> TcPluginM CoercionHole
newCoercionHole = unsafeTcPluginTcM . TcM.newCoercionHole
--- | Bind an evidence variable. This must not be invoked from
--- 'tcPluginInit' or 'tcPluginStop', or it will panic.
-setEvBind :: EvBind -> TcPluginM ()
-setEvBind ev_bind = do
- tc_evbinds <- getEvBindsTcPluginM
+-- | Bind an evidence variable.
+--
+-- This should only be invoked within 'tcPluginSolve'.
+setEvBind :: EvBindsVar -> EvBind -> TcPluginM ()
+setEvBind tc_evbinds ev_bind = do
unsafeTcPluginTcM $ TcM.addTcEvBind tc_evbinds ev_bind