[commit: ghc] wip/new-flatten-skolems-Aug14: Esablish the flattening invariant for CTyEqCan (e94d2ab)

git at git.haskell.org git at git.haskell.org
Thu Oct 2 16:51:11 UTC 2014


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

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

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

commit e94d2ab2b23a494bb47ac25b2a1fbeb46739f3c4
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Thu Oct 2 17:50:48 2014 +0100

    Esablish the flattening invariant for CTyEqCan


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

e94d2ab2b23a494bb47ac25b2a1fbeb46739f3c4
 compiler/typecheck/TcCanonical.lhs | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/compiler/typecheck/TcCanonical.lhs b/compiler/typecheck/TcCanonical.lhs
index fd07c5c..79f1eb1 100644
--- a/compiler/typecheck/TcCanonical.lhs
+++ b/compiler/typecheck/TcCanonical.lhs
@@ -458,10 +458,16 @@ data FlattenEnv
   = FE { fe_mode :: FlattenMode
        , fe_ev   :: CtEvidence }
 
-data FlattenMode
-  = FM_FlattenAll     -- Flatten all type functions
-  | FM_Avoid TcTyVar  -- Flatten type functions to avoid this type variable
-  | FM_SubstOnly      -- See Note [Flattening under a forall]
+data FlattenMode  -- Postcondition for all three: inert wrt the type substitution
+  = FM_FlattenAll          -- Postcondition: function-free
+
+  | FM_Avoid TcTyVar Bool  -- Postcondition:
+                           --  * tyvar is only mentioned in result under a rigid path
+                           --    e.g.   [a] is ok, but F a won't happen
+                           --  * If flat_top is True, top level is not a function application
+                           --   (but under type constructors is ok e.g. [F a])
+
+  | FM_SubstOnly           -- See Note [Flattening under a forall]
 
 -- Flatten a bunch of types all at once.
 flattenMany :: FlattenEnv -> [Type] -> TcS ([Xi], [TcCoercion])
@@ -522,11 +528,13 @@ flatten fmode (TyConApp tc tys)
 
   -- For * a normal data type application
   --     * data family application
-  --     * type synonym application whose RHS does not mention type families
-  --             See Note [Flattening synonyms]
   -- we just recursively flatten the arguments.
-  | otherwise
-  = flattenTyConApp fmode tc tys
+  | otherwise  -- Switch off the flat_top bit in FM_Avoid
+  , let fmode' = case fmode of
+                   FE { fe_mode = FM_Avoid tv _ }
+                     -> fmode { fe_mode = FM_Avoid tv False }
+                   _ -> fmode
+  = flattenTyConApp fmode' tc tys
 
 flatten fmode ty@(ForAllTy {})
 -- We allow for-alls when, but only when, no type function
@@ -605,11 +613,11 @@ flattenExactFamApp fmode tc tys
                           ; return ( mkTyConApp tc xis
                                    , mkTcTyConAppCo Nominal tc cos ) }
 
-       FM_Avoid tv -> do { (xis, cos) <- flattenMany fmode tys
-                         ; if tv `elemVarSet` tyVarsOfTypes xis
-                           then flattenExactFamApp_fully fmode tc tys
-                           else return ( mkTyConApp tc xis
-                                       , mkTcTyConAppCo Nominal tc cos ) }
+       FM_Avoid tv flat_top -> do { (xis, cos) <- flattenMany fmode tys
+                                  ; if flat_top || tv `elemVarSet` tyVarsOfTypes xis
+                                    then flattenExactFamApp_fully fmode tc tys
+                                    else return ( mkTyConApp tc xis
+                                                , mkTcTyConAppCo Nominal tc cos ) }
        FM_FlattenAll -> flattenExactFamApp_fully fmode tc tys
 
 flattenExactFamApp_fully fmode tc tys
@@ -1157,7 +1165,8 @@ canEqTyVar ev swapped tv1 ty2 ps_ty2              -- ev :: tv ~ s2
                                       Nothing     -> return Stop
                                       Just new_ev -> can_eq_nc new_ev ty1 ty1 ty2 ps_ty2 }
 
-           Left tv1' -> do { let fmode = FE { fe_ev = ev, fe_mode = FM_Avoid tv1' }
+           Left tv1' -> do { let fmode = FE { fe_ev = ev, fe_mode = FM_Avoid tv1' True }
+                                 -- Flatten the RHS less vigorously, to avoid gratuitous
                            ; (xi2, co2) <- flatten fmode ps_ty2 -- co2 :: xi2 ~ ps_ty2
                                            -- Use ps_ty2 to preserve type synonyms if poss
                            ; dflags <- getDynFlags



More information about the ghc-commits mailing list