[commit: ghc] master: Prevent solveFlatWanteds from losing insolubles when using typechecker plugins (d6f9276)
git at git.haskell.org
git at git.haskell.org
Thu Dec 4 13:41:35 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/d6f92769a89c29a05127cdf5f19dee56fc65dc40/ghc
>---------------------------------------------------------------
commit d6f92769a89c29a05127cdf5f19dee56fc65dc40
Author: Adam Gundry <adam at well-typed.com>
Date: Thu Dec 4 13:31:08 2014 +0000
Prevent solveFlatWanteds from losing insolubles when using typechecker plugins
Summary: I've added a Note explaining the problem.
Test Plan:
validate; we don't have a very good story for testing plugins yet,
but I've verified that this does at least fix the bug in my plugin.
Reviewers: simonpj, austin
Reviewed By: austin
Subscribers: carter, thomie, gridaphobe, yav
Differential Revision: https://phabricator.haskell.org/D552
>---------------------------------------------------------------
d6f92769a89c29a05127cdf5f19dee56fc65dc40
compiler/typecheck/TcInteract.hs | 47 +++++++++++++++++++++++++++-------------
1 file changed, 32 insertions(+), 15 deletions(-)
diff --git a/compiler/typecheck/TcInteract.hs b/compiler/typecheck/TcInteract.hs
index ed686da..a9ed64a 100644
--- a/compiler/typecheck/TcInteract.hs
+++ b/compiler/typecheck/TcInteract.hs
@@ -110,6 +110,19 @@ to float. This means that
[w] xxx[1] ~ s
[W] forall[2] . (xxx[1] ~ Empty)
=> Intersect (BuriedUnder sub k Empty) inv ~ Empty
+
+Note [Running plugins on unflattened wanteds]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There is an annoying mismatch between solveFlatGivens and
+solveFlatWanteds, because the latter needs to fiddle with the inert
+set, unflatten and and zonk the wanteds. It passes the zonked wanteds
+to runTcPluginsWanteds, which produces a replacement set of wanteds,
+some additional insolubles and a flag indicating whether to go round
+the loop again. If so, prepareInertsForImplications is used to remove
+the previous wanteds (which will still be in the inert set). Note
+that prepareInertsForImplications will discard the insolubles, so we
+must keep track of them separately.
-}
solveFlatGivens :: CtLoc -> [EvVar] -> TcS ()
@@ -128,21 +141,25 @@ solveFlatGivens loc givens
}
solveFlatWanteds :: Cts -> TcS WantedConstraints
-solveFlatWanteds wanteds
- = do { solveFlats wanteds
- ; (implics, tv_eqs, fun_eqs, insols, others) <- getUnsolvedInerts
- ; unflattened_eqs <- unflatten tv_eqs fun_eqs
- -- See Note [Unflatten after solving the flat wanteds]
-
- ; zonked <- zonkFlats (others `andCts` unflattened_eqs)
- -- Postcondition is that the wl_flats are zonked
-
- ; (wanteds', insols', rerun) <- runTcPluginsWanted zonked
- ; if rerun then do { updInertTcS prepareInertsForImplications
- ; solveFlatWanteds wanteds' }
- else return (WC { wc_flat = wanteds'
- , wc_insol = insols' `unionBags` insols
- , wc_impl = implics }) }
+solveFlatWanteds = go emptyBag
+ where
+ go insols0 wanteds
+ = do { solveFlats wanteds
+ ; (implics, tv_eqs, fun_eqs, insols, others) <- getUnsolvedInerts
+ ; unflattened_eqs <- unflatten tv_eqs fun_eqs
+ -- See Note [Unflatten after solving the flat wanteds]
+
+ ; zonked <- zonkFlats (others `andCts` unflattened_eqs)
+ -- Postcondition is that the wl_flats are zonked
+
+ ; (wanteds', insols', rerun) <- runTcPluginsWanted zonked
+ -- See Note [Running plugins on unflattened wanteds]
+ ; let all_insols = insols0 `unionBags` insols `unionBags` insols'
+ ; if rerun then do { updInertTcS prepareInertsForImplications
+ ; go all_insols wanteds' }
+ else return (WC { wc_flat = wanteds'
+ , wc_insol = all_insols
+ , wc_impl = implics }) }
-- The main solver loop implements Note [Basic Simplifier Plan]
More information about the ghc-commits
mailing list