[commit: ghc] master: Allow the solved dictionaries to propagate from outside in (c945477)
git at git.haskell.org
git at git.haskell.org
Thu Nov 6 15:42:53 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/c945477fba81b541b5a9c59d982447b862f601f4/ghc
>---------------------------------------------------------------
commit c945477fba81b541b5a9c59d982447b862f601f4
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Thu Nov 6 13:54:20 2014 +0000
Allow the solved dictionaries to propagate from outside in
See Note [Propagate solved dictionaries] in TcSMonad. This
can signficantly reduce the number of solver steps.
>---------------------------------------------------------------
c945477fba81b541b5a9c59d982447b862f601f4
compiler/typecheck/TcSMonad.lhs | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/compiler/typecheck/TcSMonad.lhs b/compiler/typecheck/TcSMonad.lhs
index c539c1e..0b3b9d8 100644
--- a/compiler/typecheck/TcSMonad.lhs
+++ b/compiler/typecheck/TcSMonad.lhs
@@ -1165,8 +1165,9 @@ recoverTcS (TcS recovery_code) (TcS thing_inside)
nestTcS :: TcS a -> TcS a
-- Use the current untouchables, augmenting the current
--- evidence bindings, and solved caches
--- But have no effect on the InertCans or insolubles
+-- evidence bindings, and solved dictionaries
+-- But have no effect on the InertCans, or on the inert_flat_cache
+-- (the latter because the thing inside a nestTcS does unflattening)
nestTcS (TcS thing_inside)
= TcS $ \ env@(TcSEnv { tcs_inerts = inerts_var }) ->
do { inerts <- TcM.readTcRef inerts_var
@@ -1174,7 +1175,14 @@ nestTcS (TcS thing_inside)
; new_wl_var <- TcM.newTcRef emptyWorkList
; let nest_env = env { tcs_inerts = new_inert_var
, tcs_worklist = new_wl_var }
- ; thing_inside nest_env }
+
+ ; res <- thing_inside nest_env
+
+ ; new_inerts <- TcM.readTcRef new_inert_var
+ ; TcM.writeTcRef inerts_var -- See Note [Propagate the solved dictionaries]
+ (inerts { inert_solved_dicts = inert_solved_dicts new_inerts })
+
+ ; return res }
tryTcS :: TcS a -> TcS a
-- Like runTcS, but from within the TcS monad
@@ -1191,7 +1199,21 @@ tryTcS (TcS thing_inside)
, tcs_inerts = is_var
, tcs_worklist = wl_var }
; thing_inside nest_env }
+\end{code}
+
+Note [Propagate the solved dictionaries]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It's really quite important that nestTcS does not discard the solved
+dictionaries from the thing_inside.
+Consider
+ Eq [a]
+ forall b. empty => Eq [a]
+We solve the flat (Eq [a]), under nestTcS, and then turn our attention to
+the implications. It's definitely fine to use the solved dictionaries on
+the inner implications, and it can make a signficant performance difference
+if you do so.
+\begin{code}
-- Getters and setters of TcEnv fields
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1365,6 +1387,7 @@ zonkFlats :: Cts -> TcS Cts
zonkFlats cts = wrapTcS (TcM.zonkFlats cts)
\end{code}
+
Note [Do not add duplicate derived insolubles]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In general we *must* add an insoluble (Int ~ Bool) even if there is
More information about the ghc-commits
mailing list