[commit: ghc] origin/wip/new-flatten-skolems-Aug14: More wip on flatten-skolems (84b3463)

git at git.haskell.org git at git.haskell.org
Tue Sep 9 16:30:12 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : origin/wip/new-flatten-skolems-Aug14
Link       : http://ghc.haskell.org/trac/ghc/changeset/84b34639ae19ce5c04f93dfead4d40f0349b8d09/ghc

>---------------------------------------------------------------

commit 84b34639ae19ce5c04f93dfead4d40f0349b8d09
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Tue Sep 9 17:29:50 2014 +0100

    More wip on flatten-skolems


>---------------------------------------------------------------

84b34639ae19ce5c04f93dfead4d40f0349b8d09
 compiler/typecheck/TcRnTypes.lhs  |  5 ++--
 compiler/typecheck/TcSMonad.lhs   |  2 +-
 compiler/typecheck/TcSimplify.lhs | 48 ++++++++++++++++++++++++++++++++-------
 3 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs
index b0d0c6c..1072d99 100644
--- a/compiler/typecheck/TcRnTypes.lhs
+++ b/compiler/typecheck/TcRnTypes.lhs
@@ -1285,8 +1285,9 @@ data Implication
                                  --   (order does not matter)
                                  -- See Invariant (GivenInv) in TcType
 
-      ic_fsks  :: [TcTyVar],     -- Extra flatten-skolems introduced by
-                                 -- by flattening the givens
+      ic_fsks  :: Cts            -- Extra Given constraints, all CFunEqCans,
+                                 -- arising from flattening the givens
+
       ic_no_eqs :: Bool,         -- True  <=> ic_givens have no equalities, for sure
                                  -- False <=> ic_givens might have equalities
 
diff --git a/compiler/typecheck/TcSMonad.lhs b/compiler/typecheck/TcSMonad.lhs
index f542c1e..a5275d1 100644
--- a/compiler/typecheck/TcSMonad.lhs
+++ b/compiler/typecheck/TcSMonad.lhs
@@ -1970,7 +1970,7 @@ deferTcSForAllEq role loc (tvs1,body1) (tvs2,body2)
                                                   , ic_skols  = skol_tvs
                                                   , ic_no_eqs = True
                                                   , ic_given  = []
-                                                  , ic_fsks   = []
+                                                  , ic_fsks   = emptyCts
                                                   , ic_wanted = wc
                                                   , ic_insol  = False
                                                   , ic_binds  = ev_binds_var
diff --git a/compiler/typecheck/TcSimplify.lhs b/compiler/typecheck/TcSimplify.lhs
index b14715f..4a1aff2 100644
--- a/compiler/typecheck/TcSimplify.lhs
+++ b/compiler/typecheck/TcSimplify.lhs
@@ -1122,7 +1122,10 @@ they carry evidence).
 
 
 \begin{code}
-floatEqualities :: [TcTyVar] -> Bool -> [TcTyVar]
+data SkolStatus = Pinned | CanFloat | Pending
+
+floatEqualities :: [TcTyVar] -> Bool
+                -> Cts          -- Given fsks
                 -> WantedConstraints -> TcS (Cts, WantedConstraints)
 -- Main idea: see Note [Float Equalities out of Implications]
 --
@@ -1140,14 +1143,43 @@ floatEqualities skols no_given_eqs fsks wanteds@(WC { wc_flat = flats })
   | otherwise
   = 
   where
-    (ufsk_funeqs, others) = partitionBag isCFunEqCan flats
+    skol_set = mkVarSet skols
+    (ufsks, others) = partitionBag isCFunEqCan flats
+    all_fsks = ufsks `andCts` fsks
+
+    fsk_tvs :: VarEnv [TcTyVar]
+    fsk_tvs = foldBag (\env (CFunEqCan { cc_fsk = tv, cc_tyargs = xis })
+                       -> extendVarEnv env tv (varSetElems (tyVarsOfTypes xis)))
+                      emptyVarEnv all_fsks
+
+    fsk_map :: VarEnv SkolStatus  -- True <=> pinned by skolem
+    fsk_map = foldrBag mk_fsk_map emptyVarEnv (ufsks `andCts` fsks)
+
+    mk_fsk_map :: Ct -> VarEnv SkolStatus -> VarEnv SkolStatus
+    mk_fsk_map (CFunEqCan { cc_fsk = tv }) map_so_far
+      = snd (mk_fsk_map_tv map_so_far tv)
+
+    mk_fsk_map_tv :: VarEnv SkolStatus -> TcTyVar -> (Bool, VarEnv SkolStatus)
+    mk_fsk_map_tv map_so_far tv
+      | Just status <- lookupVarEnv map_so_far tv
+      = (status, map_so_far)
+      | tv `elem skol_set
+      = (Pinned, extendVarEnv map_so_far tv Pinned)
+      | Just new_tvs <- lookupVarEnv fsk_tvs tv
+      , (status, map_so_far') <- mk_fsk_map_tvs (extendVarEnv map_so_far tv Pending) new_tvs
+      = (status, extendVarEnv map_so_far' tv status)
+      | otherwise
+      = (CanFloat, extendVarEnv map_so_far tv CanFloat)
+
+    mk_fsk_map_tvs :: VarEnv Bool -> [TcTyVar] -> (Bool, VarEnv Bool)
+    mk_fsk_map_tvs map_so_far []
+       = (CanFloat, map_so_far)
+    mk_fsk_map_tvs map_so_far (tv:tvs)
+       | (status, map_so_far') <- mk_fsk_map_tv map_so_far tv
+       = case status of
+           Pinned -> (Pinned, map_so_far')
+           _      -> mk_fsk_map_tvs map_so_far' tvs
 
-    pinned_tvs = fixVarSet mk_next (mkVarSet skols)
-    mk_next tvs = foldr grow_one tvs flat_eqs
-    grow_one (tvs1,tvs2) tvs
-      | intersectsVarSet tvs tvs1 = tvs `unionVarSet` tvs2
-      | intersectsVarSet tvs tvs2 = tvs `unionVarSet` tvs2
-      | otherwise                 = tvs
 
     (float_candidates, flats1) = partitionBag is_candidate flats
     is_candidate (CTyEqCan { cc_tyvar = tv, cc_rhs = xi })



More information about the ghc-commits mailing list