[commit: ghc] wip/new-flatten-skolems-Aug14: More flatten-skolem progress (0d2ce1d)

git at git.haskell.org git at git.haskell.org
Wed Oct 1 11:57:15 UTC 2014


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

On branch  : wip/new-flatten-skolems-Aug14
Link       : http://ghc.haskell.org/trac/ghc/changeset/0d2ce1ddae9cb8400b3d228a73023019cbe4f789/ghc

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

commit 0d2ce1ddae9cb8400b3d228a73023019cbe4f789
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Wed Oct 1 12:54:27 2014 +0100

    More flatten-skolem progress


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

0d2ce1ddae9cb8400b3d228a73023019cbe4f789
 compiler/typecheck/Flattening-notes |  2 ++
 compiler/typecheck/TcEvidence.lhs   | 23 +++++++++++++++++++++++
 compiler/typecheck/TcRnTypes.lhs    |  2 ++
 compiler/typecheck/TcSMonad.lhs     | 19 ++++++++++++-------
 4 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/compiler/typecheck/Flattening-notes b/compiler/typecheck/Flattening-notes
index a945d03..da8441a 100644
--- a/compiler/typecheck/Flattening-notes
+++ b/compiler/typecheck/Flattening-notes
@@ -1,5 +1,7 @@
 ToDo:
 
+* ctev_loc should have a decent name ctEvLoc
+
 * Float only CTyEqCans.   kind-incompatible things should be CNonCanonical,
   so they won't float and generate a duplicate kind-unify message
 
diff --git a/compiler/typecheck/TcEvidence.lhs b/compiler/typecheck/TcEvidence.lhs
index 3b2a3d6..d0481c8 100644
--- a/compiler/typecheck/TcEvidence.lhs
+++ b/compiler/typecheck/TcEvidence.lhs
@@ -28,6 +28,7 @@ module TcEvidence (
   mkTcAxiomRuleCo,
   tcCoercionKind, coVarsOfTcCo, isEqVar, mkTcCoVarCo,
   isTcReflCo, getTcCoVar_maybe,
+  tcLiftCoSubst, 
   tcCoercionRole, eqVarRole
   ) where
 #include "HsVersions.h"
@@ -339,6 +340,28 @@ coVarsOfTcCo tc_co
 
     get_bndrs :: Bag EvBind -> VarSet
     get_bndrs = foldrBag (\ (EvBind b _) bs -> extendVarSet bs b) emptyVarSet
+
+tcLiftCoSubst :: TcTyVar -> TcCoercion -> TcType -> TcCoercion
+-- Substitute the_tv -> the_co in the given type, at Nominal role
+-- Like Coercion.liftCoSubst, but for TcCoercion, and 
+-- specialised for Nominal role
+tcLiftCoSubst the_tv the_co ty
+ = ASSERT( tcCoercionRole the_co == Nominal )
+   go ty
+ where
+   go ty@(TyVarTy tv)
+     | tv == the_tv = the_co
+     | otherwise    = TcRefl Nominal ty
+   go ty@(LitTy {}) = TcRefl Nominal ty
+
+   go (AppTy ty1 ty2)   = mkTcAppCo         (go ty1) (go ty2)
+   go (FunTy ty1 ty2)   = mkTcFunCo Nominal (go ty1) (go ty2)
+   go (TyConApp tc tys) = mkTcTyConAppCo Nominal tc (map go tys)
+                          -- We are building a Nominal coercion, so the TyCon's
+                          -- args must all be Nominal coercions too, regardless
+                          -- of the TyCon's arg rules (c.f. Coercion.tyConRolesX)
+   go ty@(ForAllTy _ _) = pprPanic "tcLiftCoSubst" (ppr ty)
+     -- Substituting under a for-all is awkward
 \end{code}
 
 Pretty printing
diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs
index d5315d2..584115f 100644
--- a/compiler/typecheck/TcRnTypes.lhs
+++ b/compiler/typecheck/TcRnTypes.lhs
@@ -960,6 +960,8 @@ data Ct
   | CFunEqCan {  -- F xis ~ fsk
        -- Invariant: * isSynFamilyTyCon cc_fun
        --            * typeKind (F xis) `subKind` typeKind xi
+       --            * always Nominal role
+       --            * always Given or Watned, never Derived
        --       See Note [Kind orientation for CFunEqCan]
       cc_ev     :: CtEvidence,  -- See Note [Ct/evidence invariant]
       cc_fun    :: TyCon,       -- A type function
diff --git a/compiler/typecheck/TcSMonad.lhs b/compiler/typecheck/TcSMonad.lhs
index 25b22e9..b05368f 100644
--- a/compiler/typecheck/TcSMonad.lhs
+++ b/compiler/typecheck/TcSMonad.lhs
@@ -687,21 +687,22 @@ getInertUnsolved
     unflatten_funeq :: DynFlags
                     -> Ct -> TcS Cts -> TcS Cts
     unflatten_funeq dflags (CFunEqCan { cc_fun = tc, cc_tyargs = xis
-                                      , cc_fsk = tv, cc_ev = ev }) rest
+                                      , cc_fsk = fsk, cc_ev = ev }) rest
       | isGiven ev -- tv should be a FlatSkol; zonking will eliminate it
       = rest
 
       | otherwise  -- A flatten meta-tv; we now fix its final
                    -- value, and then zonking will eliminate it
-      = do { unsolved <- rest
+      = ASSERT( isWanted ev )  -- CFunEqCans are never Derived
+        do { unsolved <- rest
            ; fn_app <- wrapTcS (TcM.zonkTcType (mkTyConApp tc xis))
-           ; case occurCheckExpand dflags tv fn_app of
+           ; case occurCheckExpand dflags fsk fn_app of
                OC_OK fn_app' 
                  ->    -- Normal case: unflatten
                     do { let evterm = EvCoercion (mkTcNomReflCo fn_app')
                              evvar  = ctev_evar ev
                        ; setEvBind evvar evterm
-                       ; wrapTcS (TcM.writeMetaTyVar tv fn_app')
+                       ; wrapTcS (TcM.writeMetaTyVar fsk fn_app')
                              -- Write directly into the mutable tyvar
                              -- Flatten meta-vars are born locally and 
                              -- die locally
@@ -709,9 +710,13 @@ getInertUnsolved
 
                _ ->    -- Occurs check; don't unflatten, instead turn it into a NonCanonical
                        -- Don't forget to get rid ofthe 
-                    do { tv_ty <- newFlexiTcSTy (tyVarKind tv)
-                       ; wrapTcS (TcM.writeMetaTyVar tv tv_ty)
-                       ; return (unsolved `extendCts` mkNonCanonical ev) } }
+                    do { tv_ty <- newFlexiTcSTy (tyVarKind fsk)
+                       ; let fn_app' = substTyWith [fsk] [tv_ty] fn_app
+                       ; wrapTcS (TcM.writeMetaTyVar fsk fn_app')
+                       ; new_ev <- newWantedEvVarNC (ctev_loc ev) (mkEqPred fn_app' tv_ty)
+                                   -- w' :: F tau[alpha] ~ alpha
+                       ; setEvBind (ctEvId ev) (EvCoercion (tcLiftCoSubst fsk (ctEvCoercion new_ev) fn_app))
+                       ; return (unsolved `extendCts` mkNonCanonical new_ev) } }
 
     unflatten_funeq _ other_ct _ 
       = pprPanic "unflatten_funeq" (ppr other_ct)



More information about the ghc-commits mailing list