[commit: ghc] wip/ext-solver: Bugfix: avoid non-termination. (a1b3e4d)
git at git.haskell.org
git at git.haskell.org
Mon Jun 9 01:37:52 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/ext-solver
Link : http://ghc.haskell.org/trac/ghc/changeset/a1b3e4d0ded3f434dbfca9fe92ed7fbc42f2bf0c/ghc
>---------------------------------------------------------------
commit a1b3e4d0ded3f434dbfca9fe92ed7fbc42f2bf0c
Author: Iavor S. Diatchki <iavor.diatchki at gmail.com>
Date: Sun Jun 8 18:37:35 2014 -0700
Bugfix: avoid non-termination.
When we compute new derived work, we need to check that the result
is not already in the inert set. If we don't do this, we keep finding
the same constraints over and over again, if they don't do anything to the
inert set.
>---------------------------------------------------------------
a1b3e4d0ded3f434dbfca9fe92ed7fbc42f2bf0c
compiler/typecheck/TcInteract.lhs | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/compiler/typecheck/TcInteract.lhs b/compiler/typecheck/TcInteract.lhs
index babaeb6..3d057ae 100644
--- a/compiler/typecheck/TcInteract.lhs
+++ b/compiler/typecheck/TcInteract.lhs
@@ -156,6 +156,8 @@ interactExternSolver inGivenStage =
relList = bagToList relFeqs
othersList = funEqsToList otherFeqs
+ eqs = inert_eqs iCans
+
{- `survived` should be a sub-set of the inert funeqs.
This function rebuilds the inert set, after we've remove a constraint
(e.g., because they were solved, or caused a contradiciton. -}
@@ -189,8 +191,11 @@ interactExternSolver inGivenStage =
ExtSolOk newWork
-- We found some new work to do.
- | not (null newWork) ->
- do updWorkListTcS (extendWorkListEqs newWork)
+ | let reallyNew
+ | inGivenStage = newWork
+ | otherwise = filter (notKnownEq eqs) newWork
+ , not (null reallyNew) ->
+ do updWorkListTcS (extendWorkListEqs reallyNew)
return True
-- Nothing else to do.
@@ -208,7 +213,17 @@ interactExternSolver inGivenStage =
mapM_ setEv solved
return False
+
where
+ notKnownEq eqs ct =
+ case getEqPredTys_maybe (ctPred ct) of
+ Just (_,tvt,ty)
+ | Just tv <- getTyVar_maybe tvt ->
+ all (not . tcEqType ty)
+ [ t | CTyEqCan { cc_rhs = t } <- findTyEqs eqs tv ]
+ _ -> True
+
+
addCt ct mp =
case ct of
CFunEqCan { cc_fun = tc, cc_tyargs = tys } -> addFunEq mp tc tys ct
More information about the ghc-commits
mailing list