[commit: ghc] wip/tc-plugins: Hook-in the plugins with the constraint solve in TcInteract (09e74f4)
git at git.haskell.org
git at git.haskell.org
Thu Oct 9 16:27:42 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/tc-plugins
Link : http://ghc.haskell.org/trac/ghc/changeset/09e74f4545cb37b1263217ac513191d20fc16939/ghc
>---------------------------------------------------------------
commit 09e74f4545cb37b1263217ac513191d20fc16939
Author: Iavor S. Diatchki <diatchki at galois.com>
Date: Wed Oct 8 16:10:51 2014 -0700
Hook-in the plugins with the constraint solve in TcInteract
>---------------------------------------------------------------
09e74f4545cb37b1263217ac513191d20fc16939
compiler/typecheck/TcInteract.lhs | 74 ++++++++++++++++++++++++++++++++++++++-
compiler/typecheck/TcSMonad.lhs | 15 ++++++++
2 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/compiler/typecheck/TcInteract.lhs b/compiler/typecheck/TcInteract.lhs
index 4948692..a881a40 100644
--- a/compiler/typecheck/TcInteract.lhs
+++ b/compiler/typecheck/TcInteract.lhs
@@ -118,12 +118,84 @@ solveInteract cts
do { sel <- selectNextWorkItem max_depth
; case sel of
NoWorkRemaining -- Done, successfuly (modulo frozen)
- -> return ()
+ -> do more_work <- runTcPlugins
+ when more_work (solve_loop max_depth)
+
MaxDepthExceeded cnt ct -- Failure, depth exceeded
-> wrapErrTcS $ solverDepthErrorTcS cnt (ctEvidence ct)
NextWorkItem ct -- More work, loop around!
-> do { runSolverPipeline thePipeline ct; solve_loop max_depth } }
+
+-- | Try to make progress using type-checker plugings.
+-- Returns 'True' if we added some extra work to the work queue.
+runTcPlugins :: TcS Bool
+runTcPlugins =
+ do gblEnv <- getGblEnv
+ case tcg_tc_plugins gblEnv of
+ [] -> return False
+ plugins ->
+ do has_new_works <- mapM runPlugin plugins
+ return (or has_new_works)
+ where
+ runPlugin p =
+ do iSet <- getTcSInerts
+ let iCans = inert_cans iSet
+ iEqs = concat (varEnvElts (inert_eqs iCans))
+ iFunEqs = funEqsToList (inert_funeqs iCans)
+ allCts = iEqs ++ iFunEqs
+ (derived,other) = partition isDerivedCt allCts
+ (wanted,given) = partition isWantedCt other
+
+ -- We use this to remove some constraints.
+ -- 'survived' should be the sub-set of constraints that
+ -- remains inert.
+ restoreICans survived =
+ do let iCans1 = iCans { inert_eqs = emptyVarEnv
+ , inert_funeqs = emptyFunEqs }
+ iCans2 = foldl addInertCan iCans1 derived
+ iCans3 = foldl addInertCan iCans2 survived
+ setInertCans iCans3
+
+ result <- tcPluginIO $ tcPluginSolve p given wanted
+ case result of
+
+ TcPluginContradiction bad_cts ok_cts ->
+ do restoreICans ok_cts
+ mapM_ emitInsoluble bad_cts
+ return False
+
+ TcPluginNewWork new_cts ->
+ case removeKnownCts iCans new_cts of
+ [] -> return False
+ new_work ->
+ do updWorkListTcS (extendWorkListCts new_work)
+ return True
+
+ TcPluginSolved solved_cts other_cts ->
+ case solved_cts of
+ [] -> return False -- Fast common case
+ _ -> do restoreICans other_cts
+ let setEv (ev,ct) = setEvBind (ctev_evar (cc_ev ct)) ev
+ mapM_ setEv solved_cts
+ return False
+
+ removeKnownCts origIcans = filter (not . isKnownCt origIcans)
+ isKnownCt origIcans ct =
+ case ct of
+
+ CFunEqCan { cc_fun = f, cc_tyargs = ts } ->
+ case findFunEq (inert_funeqs origIcans) f ts of
+ Just _ -> True
+ _ -> False
+
+ CTyEqCan { cc_tyvar = x, cc_rhs = t } ->
+ not $ any (eqType t . cc_rhs) $ findTyEqs (inert_eqs origIcans) x
+
+ _ -> panic "TcPlugin returned not a TyEq or FunEq constraint"
+
+
+
type WorkItem = Ct
type SimplifierStage = WorkItem -> TcS StopOrContinue
diff --git a/compiler/typecheck/TcSMonad.lhs b/compiler/typecheck/TcSMonad.lhs
index 0f7fff8..c5d1b59 100644
--- a/compiler/typecheck/TcSMonad.lhs
+++ b/compiler/typecheck/TcSMonad.lhs
@@ -77,6 +77,7 @@ module TcSMonad (
findDict, findDictsByClass, addDict, addDictsByClass, delDict, partitionDicts,
+ emptyFunEqs, funEqsToList,
findFunEq, findTyEqs,
findFunEqsByTyCon, findFunEqs, partitionFunEqs,
sizeFunEqMap,
@@ -90,6 +91,8 @@ module TcSMonad (
getDefaultInfo, getDynFlags, getGlobalRdrEnvTcS,
+ tcPluginIO,
+
matchFam,
checkWellStagedDFun,
pprEq -- Smaller utils, re-exported from TcM
@@ -2013,3 +2016,15 @@ deferTcSForAllEq role loc (tvs1,body1) (tvs2,body2)
}
\end{code}
+
+External Type-checker Plugins
+-----------------------------
+
+\begin{code}
+-- | Execute an IO action needed by an external plugin.
+tcPluginIO :: IO a -> TcS a
+tcPluginIO m = TcS (\_ -> liftIO m)
+\end{code}
+
+
+
More information about the ghc-commits
mailing list