[commit: ghc] wip/impredicativity: Instantiation in approximation is now deep (3d5a3f2)
git at git.haskell.org
git at git.haskell.org
Wed Jul 29 09:37:56 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/impredicativity
Link : http://ghc.haskell.org/trac/ghc/changeset/3d5a3f20e1c849992783c794e30cfc2e2fd57ae2/ghc
>---------------------------------------------------------------
commit 3d5a3f20e1c849992783c794e30cfc2e2fd57ae2
Author: Alejandro Serrano <trupill at gmail.com>
Date: Wed Jul 29 08:00:39 2015 +0200
Instantiation in approximation is now deep
If we have a left-over constraint
`forall a. Q => (forall b. Q' => t) <~ v`
previously it would be approximated to
`v ~ [a -> alpha](forall b. Q' => t) /\ [a -> alpha]Q`
whereas now it is approximated to
`v ~ [a -> alpha, b -> beta]t /\ [a -> alpha]Q
/\ [a -> alpha, b -> beta]Q'`
This fixes several problems compiling the base Data.Category module.
>---------------------------------------------------------------
3d5a3f20e1c849992783c794e30cfc2e2fd57ae2
compiler/typecheck/TcRules.hs | 26 ++++++++++++++++++++------
compiler/typecheck/TcSMonad.hs | 23 +++++++++++++++++------
compiler/typecheck/TcSimplify.hs | 2 +-
3 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/compiler/typecheck/TcRules.hs b/compiler/typecheck/TcRules.hs
index 7a12cfa..4803aa7 100644
--- a/compiler/typecheck/TcRules.hs
+++ b/compiler/typecheck/TcRules.hs
@@ -317,10 +317,10 @@ simplifyRule name lhs_wanted rhs_wanted
; let lhs_wanted_simple = wc_simple lhs_wanted
; (lhs_wanted_inst, _) <- runTcS $
fmap andManyCts $ mapM instantiateWC (bagToList lhs_wanted_simple)
- ; let same_type x y = ctPred x == ctPred y
- none_with_same_type x = not (anyBag (same_type x) lhs_wanted_simple)
- lhs_wanted_inst' = filterBag none_with_same_type lhs_wanted_inst
-
+ ; let lhs_wanted_inst' = remove_duplicates lhs_wanted_simple lhs_wanted_inst
+ -- Build new WantedConstraints by adding the new instantiated
+ -- We need to be careful not to duplicate constraints,
+ -- because it would lead to too many forall's
; let new_lhs_wanted_simple = wc_simple lhs_wanted `unionBags` lhs_wanted_inst'
new_lhs_wanted = lhs_wanted { wc_simple = new_lhs_wanted_simple }
@@ -331,8 +331,15 @@ simplifyRule name lhs_wanted rhs_wanted
; rhs_resid <- solveWanteds rhs_wanted
; return (insolubleWC tc_lvl lhs_resid || insolubleWC tc_lvl rhs_resid) }
- ; zonked_lhs_simples <- zonkSimples new_lhs_wanted_simple
- ; let (q_cts, non_q_cts) = partitionBag quantify_me zonked_lhs_simples
+ ; zonked_lhs_simples <- zonkSimples (wc_simple lhs_wanted)
+ ; zonked_lhs_inst <- zonkSimples lhs_wanted_inst'
+ -- We need to remove duplicates once again,
+ -- because we might get new duplicated constraints
+ -- from unification of variables
+ ; let zonked_lhs = zonked_lhs_simples `unionBags`
+ remove_duplicates zonked_lhs_simples zonked_lhs_inst
+
+ ; let (q_cts, non_q_cts) = partitionBag quantify_me zonked_lhs
quantify_me -- Note [RULE quantification over equalities]
| insoluble = quantify_insol
| otherwise = quantify_normal
@@ -358,3 +365,10 @@ simplifyRule name lhs_wanted rhs_wanted
; return ( map (ctEvId . ctEvidence) (bagToList q_cts)
, lhs_wanted { wc_simple = non_q_cts }) }
+
+remove_duplicates :: Cts -> Cts -> Cts
+remove_duplicates main new
+ = filterBag none_with_same_type new
+ where
+ same_type x y = ctPred x == ctPred y
+ none_with_same_type x = not (anyBag (same_type x) main)
diff --git a/compiler/typecheck/TcSMonad.hs b/compiler/typecheck/TcSMonad.hs
index cf391ce..a0c36d4 100644
--- a/compiler/typecheck/TcSMonad.hs
+++ b/compiler/typecheck/TcSMonad.hs
@@ -15,8 +15,8 @@ module TcSMonad (
TcS, runTcS, runTcSWithEvBinds,
failTcS, tryTcS, nestTcS, nestImplicTcS, recoverTcS,
- runTcPluginTcS, addUsedRdrNamesTcS, deferTcSForAllEq, splitInst,
- deferTcSForAllInstanceOf,
+ runTcPluginTcS, addUsedRdrNamesTcS, deferTcSForAllEq,
+ splitInst, deeplySplitInst, deferTcSForAllInstanceOf,
-- Tracing etc
panicTcS, traceTcS,
@@ -2930,7 +2930,18 @@ splitInst :: Type -> TcS ([TyVar], ThetaType, Type)
splitInst sigma
= do { let (qvars, q, ty) = tcSplitSigmaTy sigma
-- instantiate variables for q and ty
- ; (subst, inst_vars) <- wrapTcS $ TcM.tcInstTyVars qvars
- ; let q_subst = map (Type.substTy subst) q
- ty_subst = Type.substTy subst ty
- ; return (inst_vars, q_subst, ty_subst) }
+ ; (subst, inst_vars) <- wrapTcS $ TcM.tcInstTyVars qvars
+ ; let q_subst = map (Type.substTy subst) q
+ ty_subst = Type.substTy subst ty
+ ; return (inst_vars, q_subst, ty_subst) }
+
+-- Split a sigma type and instantiate its variables, deeply
+deeplySplitInst :: Type -> TcS ([TyVar], ThetaType, Type)
+deeplySplitInst sigma
+ = do { (qvars, q, ty) <- splitInst sigma
+ ; case (qvars, q) of
+ ([], [])
+ -> return (qvars, q, ty)
+ (_, _)
+ -> do { (qvars', q', ty') <- deeplySplitInst ty
+ ; return ( qvars ++ qvars', q ++ q', ty') } }
diff --git a/compiler/typecheck/TcSimplify.hs b/compiler/typecheck/TcSimplify.hs
index e37df77..f080c09 100644
--- a/compiler/typecheck/TcSimplify.hs
+++ b/compiler/typecheck/TcSimplify.hs
@@ -1366,7 +1366,7 @@ instantiateWC :: Ct -> TcS Cts
instantiateWC ct
| isWantedCt ct, InstanceOfPred lhs rhs <- classifyPredType (ctPred ct)
= do { let loc = ctLoc ct
- ; (_qvars, q, ty) <- splitInst lhs
+ ; (_qvars, q, ty) <- deeplySplitInst lhs
; new_ev_qs <- mapM (newWantedEvVarNC loc) q
; let eq = mkTcEqPred ty rhs
; new_ev_ty <- newWantedEvVarNC loc eq
More information about the ghc-commits
mailing list